Ampliación de kubernetes cliente-go
Estoy escribiendo un controlador que mira kubernetes servicio objetos, y crea tráficos si contienen cierta etiqueta.
Ya que los kubernetes nativos van cliente no apoya el objeto trafficsplit, tuve que encontrar una manera y extender el cliente para que reconocer el recurso personalizado. Encontré esto. guía que fue útil y me permitió abordar el tema así -
import (
"splitClientV1alpha1 "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/split/clientset/versioned/typed/split/v1alpha1"
"k8s.io/client-go/kubernetes"
...
)
// getting ./kube/config from file
kubehome := filepath.Join(homedir.HomeDir(), ".kube", "config")
// Building the config from file
kubeConfig, err = clientcmd.BuildConfigFromFlags("", kubehome)
if err != nil {
return fmt.Errorf("error loading kubernetes configuration: %w", err)
}
// Creating the native client object
kubeClient, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
return fmt.Errorf("error creating kubernetes client: %w", err)
}
// Creating another clientset exclusively for the custom resource
splitClient, err := splitClientV1alpha1.NewForConfig(kubeConfig)
if err != nil {
return fmt.Errorf("error creating split client: %s", err)
}
Siento que debe haber una manera de extender el objeto kubeClient con el esquema de tráficosplit, en lugar de crear un cliente separado como lo hice. ¿Hay alguna manera de lograr esto?
Pregunta hecha hace 3 años, 5 meses, 0 días - Por javajedi
3 Respuestas:
-
¡Esto es definitivamente posible! Usted quiere utilizar las características de extensión de struct de go :)
Básicamente, creamos una estructura que extiende ambas
kubernetes.Clientset
ysplitClientV1alpha1.SplitV1alpha1Client
e inicializarlo usando código muy similar al suyo arriba. Entonces podemos utilizar métodos de cualquier cliente en esa estructura.import ( "fmt" splitClientV1alpha1 "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/split/clientset/versioned/typed/split/v1alpha1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir" "path/filepath" ) type MyKubeClient struct { kubernetes.Clientset splitClientV1alpha1.SplitV1alpha1Client } func getClient() (*MyKubeClient, error) { // getting ./kube/config from file kubehome := filepath.Join(homedir.HomeDir(), ".kube", "config") // Building the config from file kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubehome) if err != nil { return nil, fmt.Errorf("error loading kubernetes configuration: %w", err) } // Creating the native client object kubeClient, err := kubernetes.NewForConfig(kubeConfig) if err != nil { return nil, fmt.Errorf("error creating kubernetes client: %w", err) } // Creating another clientset exclusively for the custom resource splitClient, err := splitClientV1alpha1.NewForConfig(kubeConfig) if err != nil { return nil, fmt.Errorf("error creating split client: %s", err) } return &MyKubeClient{ Clientset: *kubeClient, SplitV1alpha1Client: *splitClient, }, nil } func doSomething() error { client, err := getClient() if err != nil { return err } client.CoreV1().Pods("").Create(...) client.TrafficSplits(...) }
Si necesita pasar a su cliente personalizado a una función que sólo espera el original
kubernetes.ClientSet
, puedes hacerlo con:func doSomething() error { client, err := getClient() if err != nil { return err } useClientSet(&client.Clientset) } func useOriginalKubeClientSet(clientSet *kubernetes.Clientset) { # ... do things }
Respondida el Dec 19, 2020 a las 07:45 - por compilercaptain
Votos positivos: 0 | Votos negativos: 0 -
Sí, puedes extender el cliente de Kubernetes para que pueda manejar recursos personalizados como TrafficSplit utilizando CRD (Custom Resource Definitions). Para lograr esto, necesitas registrar el esquema del recurso personalizado en el cliente de Kubernetes.
Aquí te dejo un ejemplo de cómo podrías hacerlo:
go import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/util/retry" myv1alpha1 "github.com/example.com/api/v1alpha1" myclientset "github.com/example.com/clientset/versioned" myinformers "github.com/example.com/informers/externalversions" mylisters "github.com/example.com/listers" ) func extendClientWithCustomResource(kubeClient kubernetes.Clientset, kubeConfig rest.Config) (*kubernetes.Clientset, error) { customClient, err := myclientset.NewForConfig(kubeConfig) if err != nil { return nil, err } // Create informers for custom resource myInformersFactory := myinformers.NewSharedInformerFactory(customClient, 0) customInformer := myInformersFactory.Example().V1alpha1().MyResources().Informer() // Create lister for custom resource customLister := mylisters.NewMyResourceLister(customInformer.GetIndexer()) // You can now use customClient to interact with your custom resource // Example operations retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { customResource, err := customClient.ExampleV1alpha1().MyResources(namespace).Get(name, metav1.GetOptions{}) if err != nil { return err } // Perform operations on customResource _, updateErr := customClient.ExampleV1alpha1().MyResources(namespace).Update(customResource) return updateErr }) if retryErr != nil { return nil, retryErr } return kubeClient, nil } // Usage in your code kubeClient, err := kubernetes.NewForConfig(kubeConfig) if err != nil { return nil, fmt.Errorf("error creating kubernetes client: %w", err) } kubeClient, err = extendClientWithCustomResource(kubeClient, kubeConfig) if err != nil { return nil, fmt.Errorf("error extending client with custom resource: %w", err) }
En este ejemplo,
extendClientWithCustomResource
registra el esquema del recurso personalizadoMyResource
en el cliente de Kubernetes. Luego, puedes usar elcustomClient
para interactuar con tu recurso personalizado.Es importante tener en cuenta que cada recurso personalizado puede tener sus propias definiciones y es necesario ajustar el código a la estructura de tu recurso personalizado y a su ubicación dentro del código fuente de tu proyecto.
Espero que esta información te sea útil. ¡Déjame saber si tienes alguna otra pregunta!
Respondida el Dec 20, 2020 a las 07:43 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Sí, es posible ampliar el objeto
kubeClient
para incluir el esquematrafficsplit
. Puedes hacerlo usando el paquetekubernetes/client-go/dynamic
. Aquí tienes un ejemplo de cómo hacerlo:import ( "context" "fmt" "io" "github.com/servicemeshinterface/smi-sdk-go/pkg/apis/split/v1alpha1" dynamic "k8s.io/client-go/dynamic/fake" "k8s.io/client-go/restmapper" "k8s.io/client-go/tools/clientcmd" ) func main() { // Get the kubeconfig path kubehome := filepath.Join(homedir.HomeDir(), ".kube", "config") // Build the config from the kubeconfig file kubeConfig, err := clientcmd.BuildConfigFromFlags("", filepath.Join(kubehome)) if err != nil { panic(err) } // Create the dynamic client dynamicClient, err := dynamic.NewForConfig(kubeConfig) if err != nil { panic(err) } // Create the discovery client discoveryClient, err := restmapper.NewDiscoveryClientForConfig(kubeConfig) if err != nil { panic(err) } // Add the trafficsplit schema to the discovery client if err := discoveryClient.AddとはいえResourceSchema("split.smi-spec.io", v1alpha1.SchemeGroupVersion.WithResource("trafficsplits")); err != nil { panic(err) } // Create the extended client extendedClient := dynamicClient.Resource( discoveryClient.ResourceNamesForGroupVersionResource("split.smi-spec.io", "v1alpha1", "trafficsplits"), "", ) // Use the extended client to create a trafficsplit trafficsplit := &v1alpha1.TrafficSplit{ TypeMeta: metav1.TypeMeta{ APIVersion: "split.smi-spec.io/v1alpha1", Kind: "TrafficSplit", }, Metadata: metav1.Metadata{ Name: "my-trafficsplit", }, Spec: v1alpha1.TrafficSplitSpec{ Backends: []v1alpha1.TrafficSplitBackend{ { Service: "my-service", Weight: 50, }, }, }, } if _, err := extendedClient.Create(context.TODO(), trafficsplit, metav1.CreateOptions{}); err != nil { panic(err) } // Get the created trafficsplit if got, err := extendedClient.Get(context.TODO(), "my-trafficsplit", metav1.GetOptions{}); err != nil { panic(err) } else { fmt.Fprintf(io.Stdout, "Got trafficsplit: %v", got) } }
Ten en cuenta que este es un ejemplo simplified, y es posible que necesites hacer algunos cambios para adaptarlo a tu caso de uso específico. Por ejemplo, es posible que necesites añadir el esquema
trafficsplit
a la lista de esquemas aceptados en la configuración del cliente.Respondida el Dec 20, 2020 a las 07:52 - por Gemini
Votos positivos: 0 | Votos negativos: 0