Tek bir YAML dosyasında birden çok türde doğrudan Kubernetes API'sine karşı `` kubectl uygula '' istemcisi-go kullanma


10

Https://github.com/kubernetes/client-go kullanıyorum ve hepsi iyi çalışıyor.

Resmi Kubernetes Kontrol Paneli için bir manifesto (YAML) var: https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta4/aio/deploy/recommended.yaml

kubectl applyİstemci-go'yu kullanarak Go kodundaki bu manifestoyu taklit etmek istiyorum.

YAML baytlarının pakette tanımlanan doğru API türlerine bazı (un) marşlarını yapmam gerektiğini anlıyorum: https://github.com/kubernetes/api

CreateTek bir API türlerini kümem için başarıyla düzenledim, ancak bunu aynı olmayan türlerin listesini içeren bir bildirim için nasıl yapabilirim ? kind: List*Bu farklı türleri destekleyen bir kaynak var mı ?

Geçerli geçici çözümüm, YAML dosyasını csplitayırıcı olarak --- ile kullanarak bölmektir

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

Daha sonra, oluşturulan yeni (14) parçaların üzerine döngü yapıyorum, baytlarını okudum, UniversalDeserializer'ın kod çözücüsü tarafından döndürülen nesnenin türünü açtım ve k8s istemcimi kullanarak doğru API yöntemlerini çağırıyorum.

Bunu, gösterge tablosunun yeni sürümlerinde kümemde güncellemeler yapmak için programlı olarak yapmak istiyorum. Bunu Metrics Server ve diğer birçok kaynak için de yapmam gerekecek. Alternatif (belki daha basit) yöntem, kodumu kap görüntüsüne kurulu kubectl ile göndermek ve doğrudan çağırmaktır kubectl apply -f -; ama bu da kube yapılandırmasını diske yazmam veya kubectl'in kullanabilmesi için satır içi geçirmem gerektiği anlamına geliyor.

Bu sorunu yardımcı buldum: https://github.com/kubernetes/client-go/issues/193 Dekoder burada yaşıyor: https://github.com/kubernetes/apimachinery/tree/master/pkg/runtime/ sıralandırıcı

İstemciye gidin: https://github.com/kubernetes/client-go/blob/master/kubernetes/scheme/register.go#L69

Ayrıca kubectl tarafından kullanılan RunConvert yöntemine de baktım: https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/convert/convert.go#L139 ve varsayalım kendi genericclioptions.IOStreams çıktı almak için sağlayabilir ?

RunConvert kullanımdan kaldırılıyor gibi görünüyor

Ayrıca [client-go] etiketli diğer sorulara da baktım, ancak çoğu eski örnekleri kullanıyor veya kindtanımlanmış tek bir YAML dosyası kullanıyor ve API o zamandan beri değişti.

Düzenleme: Birden fazla küme için bunu yapmak ve programlı kümeler oluşturuyorum çünkü (AWS EKS API + CloudFormation / eksctl ), ServiceAccountbirçok AWS hesaplarında, birçok küme bağlamında oluşturma yükünü en aza indirmek istiyorum . İdeal olarak, müşteri setimi oluşturmayla ilgili tek kimlik doğrulama adımı, küme verilerini (ad, bölge, CA sertifikası vb.) Kullanarak bir simge almak için aws-iam-authenticator kullanmaktır. Bir süredir aws-iam-authenticator sürümü yayınlanmadı, ancak masterüçüncü taraf rol hesaplar arası rol ve harici kimlik kullanılmasına izin verme içeriği . IMO, bu bir ServiceAccount(ve IRSA kullanmaktan daha temiz), uygulamanın (bu kümelere eklentiler oluşturan ve uygulayan arka uç API'sı) etkileşim kurması gereken başka AWS hizmetleri olduğundan.

Edit: Son zamanlarda https://github.com/ericchiang/k8s buldum . Yüksek seviyede kullanmak kesinlikle istemciden daha kolaydır, ancak bu davranışı desteklemez.


1
Konteyner yapılandırmasını kabın diskine yazmak yerine kubernetes.io/docs/tasks/configure-pod-container/…
KFC_

1
Neden YAML dosyasının içeriğini okumuyorsunuz ve ^---$kodunuzda bölüyorsunuz ?
Shawyeok

@Shawyeok Çünkü bu hala dosyada hangi türlerin olduğunu bilmemi gerektiriyor. Beklenen türlere (Kubernetes nesneleri) karşı test yapmadan türü dinamik olarak almanın bir yolu yoktur ve beklenen tür yoksa, nesne kümeye uygulanmaz (bu da daha fazla soruna yol açar). Bu aynı zamanda, tek bir bileşen için birçok bileşen için ölçeklenmeyen çok fazla kod yazmak zorunda kalmanıza neden olur. Kod çözmenin ötesinde, nesneyi bir kümeye uygulamak için doğru API yöntemini çağırır.
Simon

Yanıtlar:


3

Görünüşe göre YAML dosyalarını Kubernetes runtime.Objects içine serileştirmeyi anladınız , ancak sorun runtime.Objecther Tür için özel bir kod yazmadan dinamik olarak dağıtmaktır .

kubectlbunu doğrudan REST API ile etkileşime girerek başarır . Özellikle, kaynak yoluyla .

Kodumda, ben gibi bir şey var:

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)
}

Merhaba Kevin, cevabın için teşekkürler! Bunu denemek için bir şansım olmadı, ama farkında değildim package restmapperve bu çok umut verici görünüyor. Şimdilik cevabı kabul etmek, ancak yakında tekrar ziyaret edecektir.
Simon

1
Umarım sizin için çalışır!
Kevin Lin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.