कुबेरनेट्स एपीआई के खिलाफ `कुबेटेल अप्लाय` के लिए क्लाइंट का उपयोग करके सीधे एक एकल फ़ाइल फ़ाइल में कई प्रकारों के साथ


10

मैं https://github.com/kubernetes/client-go का उपयोग कर रहा हूं और सभी अच्छे से काम कर रहे हैं।

मेरे पास आधिकारिक कुबर्नेटेस डैशबोर्ड के लिए एक मैनिफ़ेस्ट (YAML) है: https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta4/aio/deploy/ycommended.yaml

मैं kubectl applyक्लाइंट-गो का उपयोग करके गो कोड में इस प्रकटीकरण की नकल करना चाहता हूं ।

मैं समझता हूं कि मुझे पैकेज में परिभाषित सही एपीआई प्रकारों में YAML बाइट्स के कुछ (संयुक्त राष्ट्र) मार्शलिंग करने की आवश्यकता है: https://github.com/kubernetes/api

मैंने Createअपने क्लस्टर में एकल एपीआई प्रकारों को सफलतापूर्वक संपादित किया है, लेकिन मैं इसे कैसे प्रकट करता हूं जिसमें ऐसे प्रकारों की सूची है जो समान नहीं हैं ? क्या कोई संसाधन है kind: List*जो इन विभिन्न प्रकारों का समर्थन करता है?

मेरे वर्तमान समाधान csplit--- के साथ उपयोग कर YAML फ़ाइल को विभाजित करना है - सीमांकक के रूप में

csplit /path/to/recommended.yaml /---/ '{*}' --prefix='dashboard.' --suffix-format='%03d.yaml'

इसके बाद, मैं नए (14) भागों पर लूप करता हूं, जो उनके बाइट्स को पढ़ते हैं, यूनिवर्सलडेसरीलाइज़र के डिकोडर द्वारा लौटाए गए ऑब्जेक्ट के प्रकार पर स्विच करते हैं और मेरे k8s क्लाइंटसेट का उपयोग करके सही एपीआई तरीकों को कॉल करते हैं।

मैं इसे अपने क्लस्टर में डैशबोर्ड के किसी भी नए संस्करण में अपडेट करने के लिए प्रोग्रामेटिक रूप से करना चाहूंगा। मुझे मेट्रिक्स सर्वर और कई अन्य संसाधनों के लिए भी ऐसा करने की आवश्यकता होगी। वैकल्पिक (शायद सरल) विधि मेरे कोड को कंटेनर छवि और सीधे कॉल पर स्थापित कुबेकेल के साथ जहाज करना हैkubectl apply -f - ; लेकिन इसका मतलब है कि मुझे डिस्क के लिए क्यूब कॉन्फिग्रेशन लिखना होगा या हो सकता है कि इसे इनलाइन पास कर दें ताकि कुबेकटेल इसका इस्तेमाल कर सके।

मुझे यह मुद्दा मददगार लगा: https://github.com/kubernetes/client-go/issues/193 डिकोडर यहाँ रहता है: https://github.com/kubernetes/apimachinery/tree/master/bkg/runtime/ serializer

यह क्लाइंट-गो में यहाँ उजागर किया गया है: https://github.com/kubernetes/client-go/blob/master/kubernetes/scheme/register.go#L69

मैंने RunConvert विधि पर भी एक नज़र डाली है जो kubectl द्वारा उपयोग की जाती है: https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/convert.convert.go#L139 और मान लें कि मैं अपने स्वयं के सामान्य प्रदान कर सकते हैं उत्पादन प्राप्त करने के लिए ।

ऐसा लगता है कि RunConvert एक पदावनत पथ पर है

मैंने [क्लाइंट-गो] टैग किए गए अन्य प्रश्नों को भी देखा है, लेकिन ज्यादातर पुराने उदाहरणों का उपयोग करते हैं या एकल के साथ एक YAML फ़ाइल का उपयोग करते हैं kind परिभाषित के , और एपीआई तब से बदल गया है।

संपादित करें: क्योंकि मुझे एक से अधिक क्लस्टर के लिए ऐसा करने की आवश्यकता है और क्रमिक रूप से क्लस्टर बनाए जा रहे हैं (AWS EKS API + CloudFormation / eksctl ), मैं ServiceAccountकई AWS खातों में कई क्लस्टर संदर्भों के निर्माण के ओवरहेड को कम करना चाहूंगा । आदर्श रूप से, मेरे क्लाइंटसेट बनाने में शामिल एकमात्र प्रमाणीकरण चरण aws-iam- Authator का उपयोग करके क्लस्टर डेटा (नाम, क्षेत्र, CA प्रमाणपत्र, आदि) का उपयोग करके टोकन प्राप्त करने के लिए किया जाता है। वहाँ थोड़ी देर के लिए aws-iam-Authator की रिलीज़ नहीं हुई है, लेकिन masterएक तृतीय-पक्ष भूमिका क्रॉस-अकाउंट भूमिका और बाहरी आईडी को पारित करने के लिए अनुमति की सामग्री पारित की जाती है। IMO, यह एक का उपयोग करने से क्लीनर हैServiceAccount (और IRSA)) क्योंकि अन्य एडब्ल्यूएस सेवाएं हैं (इन समूहों के लिए ऐड-ऑन बनाने और लागू करने वाले बैकएंड एपीआई) के साथ बातचीत करने की आवश्यकता है।

संपादित करें: मैंने हाल ही में https://github.com/ericchiang/k8s पाया है । यह उच्च स्तर पर क्लाइंट-गो की तुलना में निश्चित रूप से सरल है, लेकिन इस व्यवहार का समर्थन नहीं करता है।


1
कंटेनर की डिस्क पर क्यूब कॉन्फिग लिखने के बजाय सर्विस अकाउंट kubernetes.io/docs/tasks/configure-pod-container/…
KFC_

1
आप ^---$अपने कोड में सिर्फ YAML फ़ाइल और विभाजन की सामग्री क्यों नहीं पढ़ते हैं ?
शाओयोक

@ श्वाययोक क्योंकि अभी भी मुझे यह जानने की आवश्यकता है कि फ़ाइल में क्या प्रकार हैं। कई अपेक्षित प्रकारों (कुबेरनेट्स ऑब्जेक्ट्स) के खिलाफ परीक्षण के बिना प्रकार को गतिशील रूप से प्राप्त करने का कोई तरीका नहीं है, और यदि अपेक्षित प्रकार मौजूद नहीं है, तो ऑब्जेक्ट क्लस्टर पर लागू नहीं होगा (जो और भी अधिक समस्याओं की ओर जाता है)। यह एक एकल घटक के लिए बहुत सारे कोड लिखने में भी परिणाम होगा जो कई घटकों के लिए पैमाने पर नहीं होता है। ऑब्जेक्ट को क्लस्टर करने के लिए सही डिकोडिंग विधि से परे डिकोडिंग कॉल कर रहा है।
साइमन

जवाबों:


3

ऐसा लगता है कि आपने पता लगा लिया है कि कुबेरनेट्स में YAML फ़ाइलों को कैसे डिसेरलाइज़ करना है runtime.Object, लेकिन समस्या गतिशील रूप से runtime.Objectप्रत्येक प्रकार के लिए विशेष कोड लिखे बिना तैनात है ।

kubectlइसे सीधे REST API के साथ इंटरैक्ट करके प्राप्त करता है। विशेष रूप से, resource.Helper के माध्यम से ।

मेरे कोड में, मेरे पास कुछ इस तरह है:

import (
    meta "k8s.io/apimachinery/pkg/api/meta"
    "k8s.io/cli-runtime/pkg/resource"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/restmapper"
    "k8s.io/apimachinery/pkg/runtime"
)

func createObject(kubeClientset kubernetes.Interface, restConfig rest.Config, obj runtime.Object) error {
    // Create a REST mapper that tracks information about the available resources in the cluster.
    groupResources, err := restmapper.GetAPIGroupResources(kubeClientset.Discovery())
    if err != nil {
        return err
    }
    rm := restmapper.NewDiscoveryRESTMapper(groupResources)

    // Get some metadata needed to make the REST request.
    gvk := obj.GetObjectKind().GroupVersionKind()
    gk := schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}
    mapping, err := rm.RESTMapping(gk, gvk.Version)
    if err != nil {
        return err
    }

    name, err := meta.NewAccessor().Name(obj)
    if err != nil {
        return err
    }

    // Create a client specifically for creating the object.
    restClient, err := newRestClient(restConfig, mapping.GroupVersionKind.GroupVersion())
    if err != nil {
        return err
    }

    // Use the REST helper to create the object in the "default" namespace.
    restHelper := resource.NewHelper(restClient, mapping)
    return restHelper.Create("default", false, obj, &metav1.CreateOptions{})
}

func newRestClient(restConfig rest.Config, gv schema.GroupVersion) (rest.Interface, error) {
    restConfig.ContentConfig = resource.UnstructuredPlusDefaultContentConfig()
    restConfig.GroupVersion = &gv
    if len(gv.Group) == 0 {
        restConfig.APIPath = "/api"
    } else {
        restConfig.APIPath = "/apis"
    }

    return rest.RESTClientFor(&restConfig)
}

हैलो केविन, आपके उत्तर के लिए धन्यवाद! मुझे यह कोशिश करने का मौका नहीं मिला, लेकिन मुझे इसकी जानकारी नहीं थी package restmapperऔर यह बहुत ही आशाजनक लगता है। अब के लिए जवाब स्वीकार है, लेकिन जल्द ही यह फिर से आना होगा।
साइमन

1
आशा है कि यह आप के लिए काम करता है!
केविन लिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.