Cómo acceder a la definición de recursos personalizados (CRD) de Kubernetes desde Client-go

Introducción

Kubernetes es una popular plataforma de orquestación de contenedores responsable de crear y administrar contenedores que permiten que las aplicaciones de software se escalen para manejar la creciente carga de trabajo de los usuarios. Además de los recursos integrados, como pods o implementaciones, Kubernetes proporciona compatibilidad con la definición de recursos personalizados (CRD) para que pueda definir sus recursos con el formato exacto que necesita. Kubernetes CRD le proporciona los siguientes beneficios:

  • Puede utilizar la potente utilidad de línea de comandos kubectl con una serie de funcionalidades como crear o actualizar recursos.

  • Kubernetes administra directamente los recursos personalizados para que puedan escalar horizontal o verticalmente cuando sea necesario.

  • Kubernetes también proporciona una herramienta de cliente que le permite interactuar con los recursos de Kubernetes mediante programación.

  • Kubernetes admite varios lenguajes de programación populares para herramientas de cliente, como Python, Java, Javascript o Go.

Este artículo le mostrará cómo acceder y manipular Kubernetes CRDS usando el cliente-ir .

Escenario de demostración

Supongamos que su departamento de software confía en Kubernetes para crear aplicaciones y herramientas tanto para producción como para fines internos. Al implementar una nueva aplicación, se pregunta si el clúster de Kubernetes existente ya proporcionó la base de datos que necesita para almacenar datos para la nueva aplicación. Para resolver ese problema, cree un recurso personalizado para administrar las bases de datos dentro del clúster de Kubernetes. Puede buscar más información sobre el nuevo database recurso, como la base de datos admitida actualmente en Kubernetes, el número total de instancias de base de datos o las instancias de base de datos disponibles para cada base de datos.

requisitos previos

Para seguir el artículo, necesitas:

  • Un Ubuntu 20.04 recién implementado Servidor en la nube Vultr .

  • A Motor Vultr Kubernetes (VKE) clúster. Esta guía utiliza la versión 1.24.4.

  • Un entorno de Go instalado en su estación de trabajo local, que se utiliza para crear la herramienta con el cliente-go de Kubernetes para interactuar con el database recurso personalizado. Esta demostración utiliza la versión 1.19 de Go.

  • los kubectl herramienta instalada en su estación de trabajo local, utilizada para interactuar con el clúster de Kubernetes desde la línea de comandos.

Acceda al clúster de VKE mediante kubectl

Después de implementar el clúster de VKE, descargue el archivo de configuración de Kubernetes desde la página de descripción general de VKE. Necesita ese archivo de configuración para acceder al clúster Vultr Kubernetes.

  1. Navegar a la sección VKE del portal de clientes de Vultr.

  2. Haga clic en el nombre de su clúster de VKE para abrir la página de descripción general.

  3. Hacer clic Descargar configuración para descargar el archivo de configuración.

    El archivo descargado tendrá un nombre como “vke-example-6b5a-4e5e-a92e-example.yaml”. Debe cambiarle el nombre a “vke.yaml” y moverlo a su directorio de inicio para mayor comodidad. Suponiendo que descargó el archivo en el ~/Downloads directorio, abra su terminal y escriba los siguientes comandos:

                              
                                $ cd ~/Downloads
    
    $ mv ${your_config_file.yaml} ~/vke.yaml
    
                              
                            
  4. Exporte el archivo de configuración como una variable de entorno para el kubectl herramienta de línea de comandos para acceder al clúster de Kubernetes. Ejecute los siguientes comandos:

                              
                                $ cd ~
    
    
    
    // Get your current home directory path 
    
    $ echo $HOME 
    
    $ export KUBECONFIG='${path_to_your_home_directory}/vke.yaml'
    
    $ kubectl get node
    
                              
                            
  5. Debería poder ver los nodos que tiene el clúster de Kubernetes, similar al siguiente:

                              
                                NAME                   STATUS   ROLES    AGE     VERSION
    
    k8s-crd-ba11fd0aaa9b   Ready    <none>   6d20h   v1.24.4
    
    k8s-crd-e29c4afea916   Ready    <none>   6d20h   v1.24.4
    
                              
                            

Ahora que puede acceder con éxito al clúster de Kubernetes usando kubectl pasemos a la siguiente sección para ver cómo crear el database definición de recurso personalizado usando kubectl .

Crear la definición de recursos personalizados de Kubernetes mediante kubectl

Uso de Kubernetes yaml archivos como instrucciones para permitir que los clientes interactúen con el servidor de Kubernetes. El archivo de definición de recurso personalizado (archivo CRD) está en yaml formato. El archivo CRD proporciona información como apiVersion , metadata , spec y scope del recurso Verificar Guía de Kubernetes para crear definiciones de recursos personalizadas para obtener más detalles sobre cómo funciona el archivo CRD.

Primero, agregue un nuevo database definición de recurso personalizado. Ejecute los siguientes comandos para crear el archivo de definición de recursos personalizado:

                      
                        $ mkdir k8s-crd-demo

$ cd k8s-crd-demo

$ nano dbs_crd.k8s.yaml

                      
                    

Luego, copie las siguientes definiciones de yaml en dbs_crd.k8s.yaml y guarde el archivo.

                      
                        apiVersion: apiextensions.k8s.io/v1

kind: CustomResourceDefinition

metadata:

name: databases.resource.googlesyndication.com

spec:

group: resource.googlesyndication.com

versions:

    - name: v1

    served: true

    storage: true

    schema:

        openAPIV3Schema:

        type: object

        properties:

            spec:

            type: object

            properties:

                dbName:

                  type: string

                  nullable: false

                description:

                  type: string

                  nullable: false

                total:

                  type: integer

                  default: 10

                  minimum: 1

                  maximum: 100

                available:

                  type: integer

                  default: 10

                  minimum: 1

                  maximum: 100

                dbType:

                  type: string

                  enum:

                  - sql

                  - noSQL

                  - timeSeries

                  - messageQueue

                  - caching

                  nullable: false

                tags:

                  type: string

                  nullable: true

            required: ["dbName", "total", "available", "dbType"]

        required: ["spec"]

scope: Cluster

names:

    plural: databases

    singular: database

    kind: Database

    shortNames:

    - db

                      
                    
  • Tú definiste el apiVersion para el recurso personalizado con apiextensions.k8s.io/v1 que es la versión 1 para las extensiones de API de Kubernetes.

  • El nombre del CRD es databases.resource.googlesyndication.com .

  • El nombre del grupo de recursos es resource.googlesyndication.com . Debe utilizar estos nombres cuando interactúe con los recursos personalizados de Kubernetes mediante la herramienta Go-Client de Kubernetes.

  • los scope del recurso personalizado por defecto es Cluster lo que significa que puede acceder a la personalización desde cualquier lugar dentro del clúster de Kubernetes.

  • También puede configurar el scope valor a Namespace para restringir el acceso al recurso personalizado dentro de un espacio de nombres particular.

los database recurso personalizado tiene información sobre dbName , description , total , available , dbType y tags . los total y available campos que restringe para ser integer tipos de datos y tienen valores en el rango de 1 a 100 instancias. los dbType debe ser string y solo puede ser uno de los valores como sql , noSQL , timeSeries , messageQueue o caching .

Para crear esto database recurso personalizado en el clúster de Kubernetes, ejecute el siguiente comando:

                      
                        $ kubectl apply -f dbs_crd.k8s.yaml

                      
                    

Utilizando el apply opción con kubectl le dice al clúster de Kubernetes que cree o actualice el recurso de destino. los -f La opción indica que está utilizando un archivo para aplicar la acción. Debería poder ver resultados similares como:

                      
                        customresourcedefinition.apiextensions.k8s.io/databases.resource.googlesyndication.com created

                      
                    

Ahora ha creado con éxito la definición de recurso personalizado. Pasemos a agregar una nueva base de datos a database definición de recurso personalizado.

Agregar un nuevo elemento de recurso de base de datos en el database definición de recurso personalizado. Para hacerlo, crea mysql_resource_object.yaml con su editor:

                      
                        $ nano mysql_resource_object.yaml

                      
                    

Copie el siguiente contenido en mysql_resource_object.yaml :

                      
                        apiVersion: "resource.googlesyndication.com/v1"

kind: Database

metadata:

  name: mysql

spec:

  dbName: mysql

  description: Used for storing relation structured data.

  total: 50

  available: 50

  dbType: sql

  tags: Web Development, Data Engineering, Embedded software

                      
                    
  • Tu configuraste el apiVersion para la definición de recurso con el valor resource.googlesyndication.com/v1 .

  • los apiVersion debe estar en el formato de resourceGroup.version .

  • los kind de recurso es Database y debe coincidir con el kind de la definición de recurso personalizado que ya creó anteriormente.

  • El nombre de database el elemento es “mysql” con dbType como “sql” y available instancias son 50.

Ejecute el siguiente comando para agregar el mysql elemento de la base de datos al database definición de recurso.

                      
                        $ kubectl apply -f mysql_resource_object.yaml

                      
                    

Similar a la creación de la definición de recurso, utilice kubectl con el apply opción para agregar un nuevo recurso. Debería poder ver resultados similares como:

                      
                        database.resource.googlesyndication.com/mysql created

                      
                    

Ahora agregó con éxito el recurso “mysql” al database definición de recurso personalizado. Para verificar las bases de datos disponibles en el clúster de Kubernetes, ejecute lo siguiente:

                      
                        $ kubectl get db

                      
                    

Debería poder ver la salida como:

                      
                        NAME    AGE

mysql   2m58s

                      
                    

O puede obtener información detallada para el database definición de recurso personalizado usando el siguiente comando:

                      
                        $ kubectl get db -o yaml

                      
                    

La salida debería verse así:

                      
                        apiVersion: v1

items:

  - apiVersion: resource.googlesyndication.com/v1

kind: Database

metadata:

    annotations:

    kubectl.kubernetes.io/last-applied-configuration: |

        {"apiVersion":"resource.googlesyndication.com/v1","kind":"Database","metadata":{"annotations":{},"name":"mysql"},"spec":   {"available":50,"dbName":"mysql","dbType":"sql","description":"Used for storing relation structured data.","tags":"Web  Development, Data Engineering, Embedded software","total":50}}

    creationTimestamp: "2022-11-17T17:58:30Z"

    generation: 1

    name: mysql

    resourceVersion: "1419745"

    uid: 40ed6d7e-a372-4f64-8400-20376fd8fdba

spec:

    available: 50

    dbName: mysql

    dbType: sql

    description: Used for storing relation structured data.

    tags: Web Development, Data Engineering, Embedded software

    total: 50

kind: List

metadata:

resourceVersion: ""

                      
                    

En este paso, crea con éxito el database definición de recurso personalizado y agregó el mysql base de datos.

Pasemos a ver cómo puede acceder programáticamente al database definición de recurso personalizado usando Go con la ayuda de Herramienta de cliente de Kubernetes .

Interactuar con los recursos personalizados de Kubernetes usando go-client

Debe iniciar un entorno de módulo go e instalar las dependencias necesarias para crear una aplicación que interactúe con los recursos personalizados de Kubernetes.

I. Instalar las dependencias necesarias

Abra la terminal y escriba lo siguiente go mod comando para inicializar el entorno del módulo go.

                      
                        $ go mod init k8s-resource.com/m

                      
                    

El módulo go creará automáticamente un go.mod expediente. Agregue las siguientes dependencias en su aplicación go.mod archivo para conectarse con el clúster de Kubernetes.

                      
                        require k8s.io/client-go v0.24.4



require (

    github.com/google/go-cmp v0.5.9 // indirect

    github.com/kr/pretty v0.3.0 // indirect

    github.com/rogpeppe/go-internal v1.8.0 // indirect

    github.com/stretchr/testify v1.7.1 // indirect

    gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect

    sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect

    sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect

    sigs.k8s.io/yaml v1.2.0 // indirect

    )



require (

    k8s.io/api v0.24.4 // indirect

    k8s.io/apimachinery v0.24.4

    )



require (

    github.com/davecgh/go-spew v1.1.1 // indirect

    github.com/go-logr/logr v1.2.3 // indirect

    github.com/gogo/protobuf v1.3.2 // indirect

    github.com/golang/protobuf v1.5.2 // indirect

    github.com/google/gofuzz v1.2.0 // indirect

    github.com/imdario/mergo v0.3.13 // indirect; indirectap

    github.com/json-iterator/go v1.1.12 // indirect

    github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect

    github.com/modern-go/reflect2 v1.0.2 // indirect

    github.com/spf13/pflag v1.0.5 // indirect

    golang.org/x/net v0.2.0 // indirect

    golang.org/x/oauth2 v0.2.0 // indirect

    golang.org/x/sys v0.2.0 // indirect

    golang.org/x/term v0.2.0 // indirect

    golang.org/x/text v0.4.0 // indirect

    golang.org/x/time v0.2.0 // indirect

    google.golang.org/appengine v1.6.7 // indirect

    google.golang.org/protobuf v1.28.1 // indirect

    gopkg.in/inf.v0 v0.9.1 // indirect

    gopkg.in/yaml.v2 v2.4.0 // indirect

    k8s.io/klog/v2 v2.80.1 // indirect

    k8s.io/utils v0.0.0-20221108210102-8e77b1f39fe2 // indirect

    )

                      
                    

NOTA Nota: la versión de la biblioteca go-client debe coincidir con la versión del clúster de Kubernetes para evitar problemas de incompatibilidad. Verificar esta guía para detalles de la matriz de compatibilidad.

Entonces corre go mod tidy para instalar estas dependencias:

                      
                        $ go mod tidy

                      
                    

Ahora que ha instalado las dependencias, escribamos código para interactuar con Kubernetes database recursos personalizados.

II. Escriba el código para interactuar con los recursos personalizados de Kubernetes

Escribamos el código que permite a la aplicación:

  • Crear un nuevo recurso personalizado

  • Eliminar uno existente

  • Obtenga todos los recursos personalizados actuales

  • Obtenga el recurso personalizado por el nombre del recurso

Para hacerlo, utiliza varios métodos integrados de Kubernetes go-client:

                      
                        type Interface interface {

    GetRateLimiter() flowcontrol.RateLimiter

    Verb(verb string) *Request

    Post() *Request

    Put() *Request

    Patch(pt types.PatchType) *Request

    Get() *Request

    Delete() *Request

    APIVersion() schema.GroupVersion

}

                      
                    

usas el Post método para crear un nuevo recurso, Get para recuperar todos los recursos o un recurso específico por su nombre, y Delete para eliminar un recurso existente.

II.1. Estructuras y métodos de base de datos implementados para interactuar con el tiempo de ejecución de Kubernetes

  1. Crear Database estructuras

    Debes crear estructuras para DatabaseSpec , Database y DatabaseList para interactuar con lo existente database definición de recurso personalizado. Ejecute los siguientes comandos para crear un nuevo database.go expediente.

                              
                                $ mkdir api
    
    $ cd api
    
    $ nano database.go
    
                              
                            

    Copie los siguientes códigos en el database.go expediente:

                              
                                package api
    
    
    
    import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    
    
    
    type DatabaseSpec struct {
    
    DbName      string `json:"dbName"`
    
    Description string `json:"description,omitempty"`
    
    Total       int    `json:"total"`
    
    Available   int    `json:"available"`
    
    DbType      string `json:"dbType"`
    
    Tags        string `json:"tags,omitempty"`
    
    }
    
    
    
    // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
    
    type Database struct {
    
    metav1.TypeMeta   `json:",inline"`
    
    metav1.ObjectMeta `json:"metadata,omitempty"`
    
    
    
    Spec DatabaseSpec `json:"spec"`
    
    }
    
    
    
    // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
    
    type DatabaseList struct {
    
    metav1.TypeMeta `json:",inline"`
    
    metav1.ListMeta `json:"metadata,omitempty"`
    
    
    
    Items []Database `json:"items"`
    
    }
    
                              
                            

    los DatabaseSpec tener campos que coincidan con la especificación actual database definición de recurso son dbName , description , total , available , dbType y tags . Del mismo modo, el Database y DatabaseList Las estructuras constan de campos que coinciden con database información de metadatos de definición de recursos.

  2. Crear deepcopy métodos. creas un deepcopy.go para definir métodos para que su aplicación pueda interactuar con el tiempo de ejecución de Kubernetes.

                              
                                $ nano deepcopy.go
    
                              
                            

    Copie el siguiente código en el deepcopy.go expediente.

                              
                                package api
    
    
    
    import "k8s.io/apimachinery/pkg/runtime"
    
    
    
    func (in *Database) DeepCopyInto(out *Database) {
    
    out.TypeMeta = in.TypeMeta
    
    out.ObjectMeta = in.ObjectMeta
    
    out.Spec = DatabaseSpec{
    
        DbName:      in.Spec.DbName,
    
        Description: in.Spec.Description,
    
        Total:       in.Spec.Total,
    
        Available:   in.Spec.Available,
    
        DbType:      in.Spec.DbType,
    
        Tags:        in.Spec.Tags,
    
        }
    
    }
    
    
    
    func (in *Database) DeepCopyObject() runtime.Object {
    
        out := Database{}
    
        in.DeepCopyInto(&out)
    
    
    
        return &out
    
    }
    
    
    
    func (in *DatabaseList) DeepCopyObject() runtime.Object {
    
        out := DatabaseList{}
    
        out.TypeMeta = in.TypeMeta
    
        out.ListMeta = in.ListMeta
    
    
    
        if in.Items != nil {
    
            out.Items = make([]Database, len(in.Items))
    
            for i := range in.Items {
    
                in.Items[i].DeepCopyInto(&out.Items[i])
    
        }
    
        }
    
    
    
    return &out
    
    }
    
                              
                            

    Aquí se define el DeepCopyInto método para el Database estructura, la DeepCopyObject método para el Database estructura, y otra DeepCopyObject método para el DatabaseList struct para que el tiempo de ejecución de Kubernetes pueda interactuar con estas estructuras definidas.

  3. Agregar tipos de esquema para trabajar con el tiempo de ejecución de Kubernetes. Crear el register.go archivo para agregar tipos de esquema para trabajar con el tiempo de ejecución de Kubernetes.

                              
                                $ nano register.go
    
                              
                            

    Copie el siguiente código en register.go expediente:

                              
                                package api
    
    
    
    import (
    
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    
        "k8s.io/apimachinery/pkg/runtime"
    
        "k8s.io/apimachinery/pkg/runtime/schema"
    
    )
    
    
    
    const GroupName = "resource.googlesyndication.com"
    
    const GroupVersion = "v1"
    
    
    
    var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: GroupVersion}
    
    
    
    var (
    
        SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
    
        AddToScheme   = SchemeBuilder.AddToScheme
    
    )
    
    
    
    func addKnownTypes(scheme *runtime.Scheme) error {
    
        scheme.AddKnownTypes(SchemeGroupVersion,
    
        &Database{},
    
        &DatabaseList{},
    
        )
    
    
    
        metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
    
        return nil
    
    }
    
                              
                            

Tu configuraste el GroupName y GroupVersion que coincidan con el nombre del grupo y la versión del grupo del database definición de recurso personalizado. Luego dentro del addKnownTypes función, agrega el tipo para Database y DatabaseList al tiempo de ejecución de Kubernetes.

Acaba de implementar las estructuras, funciones y métodos de Go para interactuar con el tiempo de ejecución de Kubernetes en este paso. La siguiente parte del artículo trata sobre la definición del cliente y los métodos de Kubernetes para:

  • Crear un nuevo recurso

  • Obtener recursos existentes

  • Eliminar uno existente.

II.2. Implementación de clientes y métodos de Kubernetes para interactuar con recursos personalizados de Kubernetes

  1. Defina la configuración para el cliente Rest de Kubernetes. Debe definir la configuración para el cliente de Kubernetes Rest. Ejecute los siguientes comandos para crear un nuevo api.go expediente.

                              
                                $ cd ..
    
    $ mkdir clientset
    
    $ cd clientset
    
    $ nano api.go
    
                              
                            

    Copie el siguiente código en api.go :

                              
                                package clientset
    
    
    
    import (
    
        "context"
    
    
    
        "k8s-resource.com/m/api"
    
        "k8s.io/apimachinery/pkg/runtime/schema"
    
        "k8s.io/client-go/kubernetes/scheme"
    
        "k8s.io/client-go/rest"
    
    )
    
    
    
    type ExampleInterface interface {
    
    Databases(ctx context.Context) DatabaseInterface
    
    }
    
    
    
    type ExampleClient struct {
    
    restClient rest.Interface
    
    }
    
    
    
    func NewForConfig(c *rest.Config) (*ExampleClient, error) {
    
    config := *c
    
    config.ContentConfig.GroupVersion = &schema.GroupVersion{Group: api.GroupName, Version: api.GroupVersion}
    
    config.APIPath = "/apis"
    
    config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
    
    config.UserAgent = rest.DefaultKubernetesUserAgent()
    
    
    
    client, err := rest.RESTClientFor(&config)
    
    if err != nil {
    
        return nil, err
    
    }
    
    
    
    return &ExampleClient{restClient: client}, nil
    
    }
    
    
    
    func (c *ExampleClient) Databases(ctx context.Context) DatabaseInterface {
    
    return &databaseClient{
    
        restClient: c.restClient,
    
        ctx:        ctx,
    
    }
    
    }
    
                              
                            

    Aquí agrega la configuración restante para que el cliente de Kubernetes se conecte database recursos personalizados.

  2. Agregue métodos para crear, eliminar y obtener recursos personalizados. Necesitas crear un nuevo archivo llamado databases.go .

                              
                                $ nano databases.go
    
                              
                            

    Copie el siguiente código en el databases.go expediente.

                              
                                package clientset
    
    
    
    import (
    
    "context"
    
    
    
    "k8s-resource.com/m/api"
    
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    
    "k8s.io/client-go/kubernetes/scheme"
    
    "k8s.io/client-go/rest"
    
    )
    
    
    
    type DatabaseInterface interface {
    
    List(opts metav1.ListOptions) (*api.DatabaseList, error)
    
    Get(name string, options metav1.GetOptions) (*api.Database, error)
    
    Create(*api.Database) (*api.Database, error)
    
    Delete(name string, options metav1.DeleteOptions) (*api.Database, error)
    
    }
    
    
    
    type databaseClient struct {
    
    restClient rest.Interface
    
    ctx        context.Context
    
    }
    
    
    
    func (c *databaseClient) List(opts metav1.ListOptions) (*api.DatabaseList, error) {
    
    result := api.DatabaseList{}
    
    err := c.restClient.
    
        Get().
    
        AbsPath("/apis/resource.googlesyndication.com/v1/databases").
    
        Do(c.ctx).
    
        Into(&result)
    
    
    
    return &result, err
    
    }
    
    
    
    func (c *databaseClient) Get(name string, opts metav1.GetOptions) (*api.Database, error) {
    
    result := api.Database{}
    
    err := c.restClient.
    
        Get().
    
        AbsPath("/apis/resource.googlesyndication.com/v1/databases").
    
        Name(name).
    
        VersionedParams(&opts, scheme.ParameterCodec).
    
        Do(c.ctx).
    
        Into(&result)
    
    
    
    return &result, err
    
    }
    
    
    
    func (c *databaseClient) Create(database *api.Database) (*api.Database, error) {
    
    result := api.Database{}
    
    err := c.restClient.
    
        Post().
    
        AbsPath("/apis/resource.googlesyndication.com/v1/databases").
    
        Body(database).
    
        Do(c.ctx).
    
        Into(&result)
    
    
    
    return &result, err
    
    }
    
    
    
    func (c *databaseClient) Delete(name string, opts metav1.DeleteOptions) (*api.Database, error) {
    
    
    
    result := api.Database{}
    
    
    
    err := c.restClient.
    
        Delete().
    
        AbsPath("/apis/resource.googlesyndication.com/v1/databases").
    
        Name(name).
    
        VersionedParams(&opts, scheme.ParameterCodec).
    
        Do(c.ctx).Into(&result)
    
    return &result, err
    
    }
    
                              
                            

Aquí se define el Create método para crear un nuevo recurso, el Get método para obtener un recurso por nombre, el List para obtener todos los recursos actuales, y el Delete para eliminar un recurso existente que ya no se necesita.

Ahora ha agregado los códigos para definir el cliente y los métodos de Kubernetes para interactuar con los recursos personalizados de Kubernetes. Pasemos a crear un main.go expediente.

II.3. Creando un main.go para interactuar con los recursos de Kubernetes.

Suponga que en su próximo proyecto de software necesita usar MongoDB para almacenar datos para su aplicación. Para agregar la base de datos “mongodb” a la database definición de recurso personalizado, debe realizar los siguientes pasos:

  1. Copia el vke.yaml archivo de configuración en el directorio actual.

                              
                                $ cd ..
    
    $ cp ~/vke.yaml .
    
                              
                            
  2. Crear un main.go expediente.

                              
                                $ cd ..
    
    $ nano main.go
    
                              
                            
  3. Agregue el siguiente código a la main.go expediente:

                              
                                package main
    
    
    
    import (
    
    "context"
    
    "flag"
    
    "fmt"
    
    "log"
    
    "os"
    
    
    
    "k8s-resource.com/m/api"
    
    client "k8s-resource.com/m/clientset"
    
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    
    "k8s.io/client-go/tools/clientcmd"
    
    
    
    "k8s.io/client-go/kubernetes/scheme"
    
    "k8s.io/client-go/rest"
    
    )
    
    
    
    var kubeconfig string
    
    
    
    func init() {
    
    path, err := os.Getwd()
    
    if err != nil {
    
        log.Println(err)
    
    }
    
    flag.StringVar(&kubeconfig, "kubeconfig", path+"/vke.yaml", "path to Kubernetes config file")
    
    flag.Parse()
    
    }
    
    
    
    func main() {
    
    var config *rest.Config
    
    var err error
    
    
    
    if kubeconfig == "" {
    
        log.Printf("using in-cluster configuration")
    
        config, err = rest.InClusterConfig()
    
    } else {
    
        log.Printf("using configuration from '%s'", kubeconfig)
    
        config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
    
    }
    
    
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    api.AddToScheme(scheme.Scheme)
    
    
    
    clientSet, err := client.NewForConfig(config)
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    context := context.TODO()
    
    
    
    newDatabase := new(api.Database) // pa == &Student{"", 0}
    
    newDatabase.Name = "mongodb"
    
    newDatabase.Kind = "Database" // pa == &Student{"Alice", 0}
    
    newDatabase.APIVersion = "resource.googlesyndication.com/v1"
    
    newDatabase.Spec.DbName = "mongodb"
    
    newDatabase.Spec.Description = "Used storing unstructured data"
    
    newDatabase.Spec.Total = 100
    
    newDatabase.Spec.Available = 50
    
    newDatabase.Spec.DbType = "noSQL"
    
    newDatabase.Spec.Tags = "Web Development, nosql data"
    
    newDatabase.Spec.Available = 70
    
    
    
    projectCreated, err := clientSet.Databases(context).Create(newDatabase)
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    fmt.Println(projectCreated)
    
    }
    
                              
                            

    Aquí llamas a la Create método para agregar mongodb base de datos a la database definición de recurso personalizado.

  4. Ejecutar la acción. ejecutar el main.go expediente.

                              
                                $ go run main.go
    
                              
                            

    Después de ejecutar este comando, debería ver un resultado similar a continuación:

                              
                                2022/11/18 02:14:55 using configuration from '/home/example/Projects/Personal/vultr/k8s-crd/k8s-crd-full-    demo/vke.yaml'
    
    &{{ } {mongodb    f8ba273e-fd1f-4b40-b036-cf13b8c72366 1430720 1 2022-11-18 02:14:55 +0700 +07 <nil> <nil>  map[] map[] [] []  [{main Update resource.googlesyndication.com/v1 2022-11-18 02:14:55 +0700 +07 FieldsV1 {"f:spec":{".":{},"f:available":{},"f:dbName":{},"f:dbType":{},"f:description":{},"f:tags":{},"f:total":{}}} }]} {mongodb Used storing unstructured data 100 70 noSQL Web Development, nosql data}}
    
                              
                            

    Acaba de agregar la base de datos “mongodb”. Intentemos obtener información detallada sobre la base de datos “mongodb” usando el Get método.

  5. Obtenga información detallada para la base de datos “mongodb”. Para hacer esto, reemplace el main.go código con el siguiente código.

                              
                                package main
    
    
    
    import (
    
    "context"
    
    "flag"
    
    "fmt"
    
    "log"
    
    "os"
    
    
    
    "k8s-resource.com/m/api"
    
    client "k8s-resource.com/m/clientset"
    
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    
    "k8s.io/client-go/tools/clientcmd"
    
    
    
    "k8s.io/client-go/kubernetes/scheme"
    
    "k8s.io/client-go/rest"
    
    )
    
    
    
    var kubeconfig string
    
    
    
    func init() {
    
    path, err := os.Getwd()
    
    if err != nil {
    
        log.Println(err)
    
    }
    
    flag.StringVar(&kubeconfig, "kubeconfig", path+"/vke.yaml", "path to Kubernetes config file")
    
    flag.Parse()
    
    }
    
    
    
    func main() {
    
    var config *rest.Config
    
    var err error
    
    
    
    if kubeconfig == "" {
    
        log.Printf("using in-cluster configuration")
    
        config, err = rest.InClusterConfig()
    
    } else {
    
        log.Printf("using configuration from '%s'", kubeconfig)
    
        config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
    
    }
    
    
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    api.AddToScheme(scheme.Scheme)
    
    
    
    clientSet, err := client.NewForConfig(config)
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    context := context.TODO()
    
    
    
    projectGet, err := clientSet.Databases(context).Get("mongodb", metav1.GetOptions{})
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    fmt.Println(projectGet)
    
    
    
    }
    
                              
                            

    Luego ejecuta el comando:

                              
                                $ go run main.go
    
                              
                            

    Debería ver una salida similar a la siguiente:

                              
                                2022/11/18 02:18:20 using configuration from '/home/example/Projects/Personal/vultr/k8s-crd/k8s-crd-full-demo/vke.yaml'
    
    &{{ } {mongodb    f8ba273e-fd1f-4b40-b036-cf13b8c72366 1430720 1 2022-11-18 02:14:55 +0700 +07 <nil> <nil> map[] map[] [] []  [{main Update resource.googlesyndication.com/v1 2022-11-18 02:14:55 +0700 +07 FieldsV1 {"f:spec":{".":{},"f:available":{},"f:dbName":{},"f:dbType":{},"f:description":{},"f:tags":{},"f:total":{}}} }]} {mongodb Used storing unstructured data 100 70 noSQL Web Development, nosql data}}
    
                              
                            
  6. Eliminar la base de datos “mysql” del clúster de Kubernetes. Digamos que ya no necesita el mysql base de datos en el clúster de Kubernetes. para quitar el mysql recurso del clúster de Kubernetes, reemplace el código en main.go con el siguiente código:

                              
                                package main
    
    
    
    import (
    
    "context"
    
    "flag"
    
    "log"
    
    "os"
    
    
    
    "k8s-resource.com/m/api"
    
    client "k8s-resource.com/m/clientset"
    
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    
    "k8s.io/client-go/tools/clientcmd"
    
    
    
    "k8s.io/client-go/kubernetes/scheme"
    
    "k8s.io/client-go/rest"
    
    )
    
    
    
    var kubeconfig string
    
    
    
    func init() {
    
    path, err := os.Getwd()
    
    if err != nil {
    
        log.Println(err)
    
    }
    
    flag.StringVar(&kubeconfig, "kubeconfig", path+"/vke.yaml", "path to Kubernetes config file")
    
    flag.Parse()
    
    }
    
    
    
    func main() {
    
    var config *rest.Config
    
    var err error
    
    
    
    if kubeconfig == "" {
    
        log.Printf("using in-cluster configuration")
    
        config, err = rest.InClusterConfig()
    
    } else {
    
        log.Printf("using configuration from '%s'", kubeconfig)
    
        config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
    
    }
    
    
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    api.AddToScheme(scheme.Scheme)
    
    
    
    clientSet, err := client.NewForConfig(config)
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    context := context.TODO()
    
    
    
    _, err = clientSet.Databases(context).Delete("mysql", metav1.DeleteOptions{})
    
    if err != nil {
    
        panic(err)
    
    }
    
    
    
    }
    
                              
                            

    Entonces corre:

                              
                                $ go run main.go
    
                              
                            
  7. Compruebe si la base de datos “mysql” se eliminó realmente. Ahora, intentemos obtener todos los recursos personalizados actuales para ver si eliminó con éxito la base de datos “mysql”. Reemplace el código existente en el main.go archivo con el siguiente contenido:

                              
                                package main
    
    
    
    import (
    
    "context"
    
    "flag"
    
    "fmt"
    
    "log"
    
    "os"
    
    
    
    "k8s-resource.com/m/api"
    
    client "k8s-resource.com/m/clientset"
    
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    
    "k8s.io/client-go/tools/clientcmd"
    
    
    
    "k8s.io/client-go/kubernetes/scheme"
    
    "k8s.io/client-go/rest"
    
    )
    
    
    
    var kubeconfig string
    
    
    
    func init() {
    
    path, err := os.Getwd()
    
    if err != nil {
    
    log.Println(err)
    
    }
    
    flag.StringVar(&kubeconfig, "kubeconfig", path+"/vke.yaml", "path to Kubernetes config file")
    
    flag.Parse()
    
    }
    
    
    
    func main() {
    
    var config *rest.Config
    
    var err error
    
    
    
    if kubeconfig == "" {
    
    log.Printf("using in-cluster configuration")
    
    config, err = rest.InClusterConfig()
    
    } else {
    
    log.Printf("using configuration from '%s'", kubeconfig)
    
    config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
    
    }
    
    
    
    if err != nil {
    
    panic(err)
    
    }
    
    
    
    api.AddToScheme(scheme.Scheme)
    
    
    
    clientSet, err := client.NewForConfig(config)
    
    if err != nil {
    
    panic(err)
    
    }
    
    
    
    context := context.TODO()
    
    
    
    projects, err := clientSet.Databases(context).List(metav1.ListOptions{})
    
    if err != nil {
    
    panic(err)
    
    }
    
    
    
    for _, k := range projects.Items {
    
    
    
    fmt.Println(k.Name)
    
    
    
    }
    
    
    
    }
    
                              
                            

    Ejecutemos el main.go expediente:

                              
                                $ go run main.go
    
                              
                            

    Solo debe ver el mongodb base de datos que se muestra en la salida.

                              
                                2022/11/18 02:24:08 using configuration from '/home/example/Projects/Personal/vultr/k8s-crd/k8s-crd-full-  demo/vke.yaml'
    
    mongodb
    
                              
                            

Y así es como puede interactuar con los recursos personalizados de Kubernetes utilizando la herramienta Go-Client de Kubernetes.

Conclusión

El artículo explica qué es Kubernetes CRD, por qué querría usar Kubernetes CRD en su proyecto de trabajo actual y cómo usar la herramienta Go-Client de Kubernetes para interactuar con Kubernetes CRD mediante programación. Trabajar con Kubernetes es divertido y desafiante, así que prepárese para enfrentar nuevos obstáculos cuando trabaje con él. Si desea obtener más información sobre otros casos de uso de Kubernetes go-client, consulte:

  • Escriba su infraestructura de Kubernetes en Go con cdk8s

  • Cree y administre trabajos de Kubernetes en Go con la API client-go

Título del artículo Nombre (opcional) Correo electrónico (opcional) Descripción

Enviar sugerencia

Related Posts