5.3. Opérateurs basés sur le Go


5.3.1. Premiers pas avec Operator SDK pour les opérateurs basés sur Go

Pour démontrer les bases de la configuration et de l'exécution d'un opérateur basé sur Go à l'aide des outils et des bibliothèques fournis par le SDK Operator, les développeurs d'opérateurs peuvent construire un exemple d'opérateur basé sur Go pour Memcached, un magasin de valeurs clés distribué, et le déployer dans un cluster.

5.3.1.1. Conditions préalables

  • Operator SDK CLI installé
  • OpenShift CLI (oc) v4.12 installé
  • Go v1.19
  • Connexion à un cluster OpenShift Container Platform 4.12 avec oc avec un compte qui a les permissions cluster-admin
  • Pour permettre au cluster d'extraire l'image, le dépôt où vous avez poussé votre image doit être défini comme public, ou vous devez configurer un secret d'extraction d'image

5.3.1.2. Création et déploiement d'opérateurs basés sur Go

Vous pouvez construire et déployer un simple opérateur basé sur Go pour Memcached en utilisant le SDK Operator.

Procédure

  1. Create a project.

    1. Créez votre répertoire de projet :

      $ mkdir memcached-operator
    2. Allez dans le répertoire du projet :

      $ cd memcached-operator
    3. Exécutez la commande operator-sdk init pour initialiser le projet :

      $ operator-sdk init \
          --domain=example.com \
          --repo=github.com/example-inc/memcached-operator

      La commande utilise par défaut le plugin Go.

  2. Create an API.

    Créer une API Memcached simple :

    $ operator-sdk create api \
        --resource=true \
        --controller=true \
        --group cache \
        --version v1 \
        --kind Memcached
  3. Build and push the Operator image.

    Utilisez les cibles par défaut de Makefile pour construire et pousser votre opérateur. Définissez IMG avec une spécification d'extraction pour votre image qui utilise un registre vers lequel vous pouvez pousser :

    $ make docker-build docker-push IMG=<registry>/<user>/<image_name>:<tag>
  4. Run the Operator.

    1. Installer le CRD :

      $ make install
    2. Déployez le projet sur le cluster. Définissez IMG sur l'image que vous avez poussée :

      $ make deploy IMG=<registry>/<user>/<image_name>:<tag>
  5. Create a sample custom resource (CR).

    1. Créer un échantillon de CR :

      $ oc apply -f config/samples/cache_v1_memcached.yaml \
          -n memcached-operator-system
    2. Il faut s'attendre à ce que le CR réconcilie l'opérateur :

      $ oc logs deployment.apps/memcached-operator-controller-manager \
          -c manager \
          -n memcached-operator-system
  6. Delete a CR

    Supprimez un CR en exécutant la commande suivante :

    $ oc delete -f config/samples/cache_v1_memcached.yaml -n memcached-operator-system
  7. Clean up.

    Exécutez la commande suivante pour nettoyer les ressources qui ont été créées dans le cadre de cette procédure :

    $ make undeploy

5.3.1.3. Prochaines étapes

5.3.2. Didacticiel sur le SDK pour les opérateurs basés sur Go

Les développeurs d'opérateurs peuvent profiter de la prise en charge du langage de programmation Go dans le SDK de l'opérateur pour créer un exemple d'opérateur basé sur Go pour Memcached, un magasin de valeurs clés distribué, et gérer son cycle de vie.

Ce processus est réalisé à l'aide de deux pièces maîtresses du cadre de l'opérateur :

SDK de l'opérateur
L'outil CLI operator-sdk et la bibliothèque API controller-runtime
Gestionnaire du cycle de vie des opérateurs (OLM)
Installation, mise à niveau et contrôle d'accès basé sur les rôles (RBAC) des opérateurs sur un cluster
Note

5.3.2.1. Conditions préalables

  • Operator SDK CLI installé
  • OpenShift CLI (oc) v4.12 installé
  • Go v1.19
  • Connexion à un cluster OpenShift Container Platform 4.12 avec oc avec un compte qui a les permissions cluster-admin
  • Pour permettre au cluster d'extraire l'image, le dépôt où vous avez poussé votre image doit être défini comme public, ou vous devez configurer un secret d'extraction d'image

5.3.2.2. Création d'un projet

Utilisez l'interface de programmation Operator SDK pour créer un projet appelé memcached-operator.

Procédure

  1. Créer un répertoire pour le projet :

    $ mkdir -p $HOME/projects/memcached-operator
  2. Accédez au répertoire :

    $ cd $HOME/projects/memcached-operator
  3. Activer le support pour les modules Go :

    $ export GO111MODULE=on
  4. Exécutez la commande operator-sdk init pour initialiser le projet :

    $ operator-sdk init \
        --domain=example.com \
        --repo=github.com/example-inc/memcached-operator
    Note

    La commande operator-sdk init utilise par défaut le plugin Go.

    La commande operator-sdk init génère un fichier go.mod à utiliser avec les modules Go. Le drapeau --repo est nécessaire lors de la création d'un projet en dehors de $GOPATH/src/, car les fichiers générés nécessitent un chemin de module valide.

5.3.2.2.1. Dossier PROJET

Parmi les fichiers générés par la commande operator-sdk init figure un fichier Kubebuilder PROJECT. Les commandes operator-sdk suivantes, ainsi que la sortie help, qui sont exécutées à partir de la racine du projet, lisent ce fichier et savent que le type de projet est Go. Par exemple :

domain: example.com
layout:
- go.kubebuilder.io/v3
projectName: memcached-operator
repo: github.com/example-inc/memcached-operator
version: "3"
plugins:
  manifests.sdk.operatorframework.io/v2: {}
  scorecard.sdk.operatorframework.io/v2: {}
  sdk.x-openshift.io/v1: {}
5.3.2.2.2. À propos du gestionnaire

Le programme principal de l'opérateur est le fichier main.go, qui initialise et exécute le gestionnaire. Ce dernier enregistre automatiquement le schéma pour toutes les définitions d'API de ressources personnalisées (CR) et met en place et exécute les contrôleurs et les webhooks.

Le gestionnaire peut restreindre l'espace de noms que tous les contrôleurs surveillent à la recherche de ressources :

mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: namespace})

Par défaut, le gestionnaire surveille l'espace de noms dans lequel l'opérateur s'exécute. Pour surveiller tous les espaces de noms, vous pouvez laisser l'option namespace vide :

mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: ""})

Vous pouvez également utiliser la fonction MultiNamespacedCacheBuilder pour surveiller un ensemble spécifique d'espaces de noms :

var namespaces []string 1
mgr, err := ctrl.NewManager(cfg, manager.Options{ 2
   NewCache: cache.MultiNamespacedCacheBuilder(namespaces),
})
1
Liste des espaces de noms.
2
Crée une structure Cmd pour fournir des dépendances partagées et des composants de démarrage.
5.3.2.2.3. À propos des API multigroupes

Avant de créer une API et un contrôleur, demandez-vous si votre opérateur a besoin de plusieurs groupes d'API. Ce didacticiel couvre le cas par défaut d'une API à groupe unique, mais pour modifier la présentation de votre projet afin de prendre en charge des API à groupes multiples, vous pouvez exécuter la commande suivante :

$ operator-sdk edit --multigroup=true

Cette commande met à jour le fichier PROJECT, qui devrait ressembler à l'exemple suivant :

domain: example.com
layout: go.kubebuilder.io/v3
multigroup: true
...

Pour les projets multi-groupes, les fichiers de type API Go sont créés dans le répertoire apis/<group>/<version>/, et les contrôleurs sont créés dans le répertoire controllers/<group>/. Le fichier Dockerfile est ensuite mis à jour en conséquence.

Ressource supplémentaire

5.3.2.3. Création d'une API et d'un contrôleur

Utilisez le SDK CLI de l'opérateur pour créer une API et un contrôleur de définition de ressources personnalisées (CRD).

Procédure

  1. Exécutez la commande suivante pour créer une API avec le groupe cache, la version v1 et le type Memcached:

    $ operator-sdk create api \
        --group=cache \
        --version=v1 \
        --kind=Memcached
  2. Lorsque vous y êtes invité, entrez y pour créer la ressource et le contrôleur :

    Create Resource [y/n]
    y
    Create Controller [y/n]
    y

    Exemple de sortie

    Writing scaffold for you to edit...
    api/v1/memcached_types.go
    controllers/memcached_controller.go
    ...

Ce processus génère la ressource Memcached API à l'adresse api/v1/memcached_types.go et le contrôleur à l'adresse controllers/memcached_controller.go.

5.3.2.3.1. Définition de l'API

Définir l'API pour la ressource personnalisée (CR) Memcached.

Procédure

  1. Modifiez les définitions du type Go à l'adresse api/v1/memcached_types.go pour obtenir spec et status:

    // MemcachedSpec defines the desired state of Memcached
    type MemcachedSpec struct {
    	// +kubebuilder:validation:Minimum=0
    	// Size is the size of the memcached deployment
    	Size int32 `json:"size"`
    }
    
    // MemcachedStatus defines the observed state of Memcached
    type MemcachedStatus struct {
    	// Nodes are the names of the memcached pods
    	Nodes []string `json:"nodes"`
    }
  2. Mettre à jour le code généré pour le type de ressource :

    $ make generate
    Astuce

    Après avoir modifié un fichier *_types.go, vous devez exécuter la commande make generate pour mettre à jour le code généré pour ce type de ressource.

    La cible Makefile ci-dessus invoque l'utilitaire controller-gen pour mettre à jour le fichier api/v1/zz_generated.deepcopy.go. Cela permet de s'assurer que les définitions de type de l'API Go implémentent l'interface runtime.Object que tous les types Kind doivent implémenter.

5.3.2.3.2. Générer des manifestes CRD

Une fois l'API définie avec les champs spec et status et les marqueurs de validation de la définition des ressources personnalisées (CRD), vous pouvez générer des manifestes CRD.

Procédure

  • Exécutez la commande suivante pour générer et mettre à jour les manifestes CRD :

    $ make manifests

    Cette cible Makefile invoque l'utilitaire controller-gen pour générer les manifestes CRD dans le fichier config/crd/bases/cache.example.com_memcacheds.yaml.

5.3.2.3.2.1. À propos de la validation de l'OpenAPI

Les schémas OpenAPIv3 sont ajoutés aux manifestes CRD dans le bloc spec.validation lorsque les manifestes sont générés. Ce bloc de validation permet à Kubernetes de valider les propriétés d'une ressource personnalisée Memcached (CR) lors de sa création ou de sa mise à jour.

Des marqueurs, ou annotations, sont disponibles pour configurer les validations de votre API. Ces marqueurs ont toujours un préfixe kubebuilder:validation.

Ressources supplémentaires

5.3.2.4. Mise en œuvre du contrôleur

Après avoir créé une nouvelle API et un nouveau contrôleur, vous pouvez mettre en œuvre la logique du contrôleur.

Procédure

  • Pour cet exemple, remplacez le fichier de contrôleur généré controllers/memcached_controller.go par l'exemple de mise en œuvre suivant :

    Exemple 5.1. Exemple memcached_controller.go

    /*
    Copyright 2020.
    
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    */
    
    package controllers
    
    import (
    	appsv1 "k8s.io/api/apps/v1"
    	corev1 "k8s.io/api/core/v1"
    	"k8s.io/apimachinery/pkg/api/errors"
    	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    	"k8s.io/apimachinery/pkg/types"
    	"reflect"
    
    	"context"
    
    	"github.com/go-logr/logr"
    	"k8s.io/apimachinery/pkg/runtime"
    	ctrl "sigs.k8s.io/controller-runtime"
    	"sigs.k8s.io/controller-runtime/pkg/client"
    
    	cachev1alpha1 "github.com/example/memcached-operator/api/v1alpha1"
    )
    
    // MemcachedReconciler reconciles a Memcached object
    type MemcachedReconciler struct {
    	client.Client
    	Log    logr.Logger
    	Scheme *runtime.Scheme
    }
    
    // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
    // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch
    // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update
    // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
    // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;
    
    // Reconcile is part of the main kubernetes reconciliation loop which aims to
    // move the current state of the cluster closer to the desired state.
    // TODO(user): Modify the Reconcile function to compare the state specified by
    // the Memcached object against the actual cluster state, and then
    // perform operations to make the cluster state reflect the state specified by
    // the user.
    //
    // For more details, check Reconcile and its Result here:
    // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.7.0/pkg/reconcile
    func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    	log := r.Log.WithValues("memcached", req.NamespacedName)
    
    	// Fetch the Memcached instance
    	memcached := &cachev1alpha1.Memcached{}
    	err := r.Get(ctx, req.NamespacedName, memcached)
    	if err != nil {
    		if errors.IsNotFound(err) {
    			// Request object not found, could have been deleted after reconcile request.
    			// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
    			// Return and don't requeue
    			log.Info("Memcached resource not found. Ignoring since object must be deleted")
    			return ctrl.Result{}, nil
    		}
    		// Error reading the object - requeue the request.
    		log.Error(err, "Failed to get Memcached")
    		return ctrl.Result{}, err
    	}
    
    	// Check if the deployment already exists, if not create a new one
    	found := &appsv1.Deployment{}
    	err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found)
    	if err != nil && errors.IsNotFound(err) {
    		// Define a new deployment
    		dep := r.deploymentForMemcached(memcached)
    		log.Info("Creating a new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
    		err = r.Create(ctx, dep)
    		if err != nil {
    			log.Error(err, "Failed to create new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
    			return ctrl.Result{}, err
    		}
    		// Deployment created successfully - return and requeue
    		return ctrl.Result{Requeue: true}, nil
    	} else if err != nil {
    		log.Error(err, "Failed to get Deployment")
    		return ctrl.Result{}, err
    	}
    
    	// Ensure the deployment size is the same as the spec
    	size := memcached.Spec.Size
    	if *found.Spec.Replicas != size {
    		found.Spec.Replicas = &size
    		err = r.Update(ctx, found)
    		if err != nil {
    			log.Error(err, "Failed to update Deployment", "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name)
    			return ctrl.Result{}, err
    		}
    		// Spec updated - return and requeue
    		return ctrl.Result{Requeue: true}, nil
    	}
    
    	// Update the Memcached status with the pod names
    	// List the pods for this memcached's deployment
    	podList := &corev1.PodList{}
    	listOpts := []client.ListOption{
    		client.InNamespace(memcached.Namespace),
    		client.MatchingLabels(labelsForMemcached(memcached.Name)),
    	}
    	if err = r.List(ctx, podList, listOpts...); err != nil {
    		log.Error(err, "Failed to list pods", "Memcached.Namespace", memcached.Namespace, "Memcached.Name", memcached.Name)
    		return ctrl.Result{}, err
    	}
    	podNames := getPodNames(podList.Items)
    
    	// Update status.Nodes if needed
    	if !reflect.DeepEqual(podNames, memcached.Status.Nodes) {
    		memcached.Status.Nodes = podNames
    		err := r.Status().Update(ctx, memcached)
    		if err != nil {
    			log.Error(err, "Failed to update Memcached status")
    			return ctrl.Result{}, err
    		}
    	}
    
    	return ctrl.Result{}, nil
    }
    
    // deploymentForMemcached returns a memcached Deployment object
    func (r *MemcachedReconciler) deploymentForMemcached(m *cachev1alpha1.Memcached) *appsv1.Deployment {
    	ls := labelsForMemcached(m.Name)
    	replicas := m.Spec.Size
    
    	dep := &appsv1.Deployment{
    		ObjectMeta: metav1.ObjectMeta{
    			Name:      m.Name,
    			Namespace: m.Namespace,
    		},
    		Spec: appsv1.DeploymentSpec{
    			Replicas: &replicas,
    			Selector: &metav1.LabelSelector{
    				MatchLabels: ls,
    			},
    			Template: corev1.PodTemplateSpec{
    				ObjectMeta: metav1.ObjectMeta{
    					Labels: ls,
    				},
    				Spec: corev1.PodSpec{
    					Containers: []corev1.Container{{
    						Image:   "memcached:1.4.36-alpine",
    						Name:    "memcached",
    						Command: []string{"memcached", "-m=64", "-o", "modern", "-v"},
    						Ports: []corev1.ContainerPort{{
    							ContainerPort: 11211,
    							Name:          "memcached",
    						}},
    					}},
    				},
    			},
    		},
    	}
    	// Set Memcached instance as the owner and controller
    	ctrl.SetControllerReference(m, dep, r.Scheme)
    	return dep
    }
    
    // labelsForMemcached returns the labels for selecting the resources
    // belonging to the given memcached CR name.
    func labelsForMemcached(name string) map[string]string {
    	return map[string]string{"app": "memcached", "memcached_cr": name}
    }
    
    // getPodNames returns the pod names of the array of pods passed in
    func getPodNames(pods []corev1.Pod) []string {
    	var podNames []string
    	for _, pod := range pods {
    		podNames = append(podNames, pod.Name)
    	}
    	return podNames
    }
    
    // SetupWithManager sets up the controller with the Manager.
    func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {
    	return ctrl.NewControllerManagedBy(mgr).
    		For(&cachev1alpha1.Memcached{}).
    		Owns(&appsv1.Deployment{}).
    		Complete(r)
    }

    Le contrôleur de l'exemple exécute la logique de rapprochement suivante pour chaque ressource personnalisée (CR) Memcached:

    • Créer un déploiement Memcached s'il n'existe pas.
    • Assurez-vous que la taille du déploiement est la même que celle spécifiée par la spécification CR de Memcached.
    • Mettre à jour l'état de Memcached CR avec les noms des pods memcached.

Les sous-sections suivantes expliquent comment le contrôleur de l'exemple de mise en œuvre surveille les ressources et comment la boucle de rapprochement est déclenchée. Vous pouvez sauter ces sous-sections pour passer directement à l'exécution de l'opérateur.

5.3.2.4.1. Ressources surveillées par le contrôleur

La fonction SetupWithManager() dans controllers/memcached_controller.go spécifie comment le contrôleur est construit pour surveiller un CR et d'autres ressources qui sont détenues et gérées par ce contrôleur.

import (
	...
	appsv1 "k8s.io/api/apps/v1"
	...
)

func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&cachev1.Memcached{}).
		Owns(&appsv1.Deployment{}).
		Complete(r)
}

NewControllerManagedBy() fournit un constructeur de contrôleurs qui permet différentes configurations de contrôleurs.

For(&cachev1.Memcached{}) spécifie le type Memcached en tant que ressource primaire à surveiller. Pour chaque événement d'ajout, de mise à jour ou de suppression d'un type Memcached, la boucle de rapprochement reçoit un argument de rapprochement Request, composé d'un espace de noms et d'une clé de nom, pour cet objet Memcached.

Owns(&appsv1.Deployment{}) spécifie le type Deployment comme ressource secondaire à surveiller. Pour chaque événement d'ajout, de mise à jour ou de suppression du type Deployment, le gestionnaire d'événements associe chaque événement à une demande de rapprochement pour le propriétaire du déploiement. Dans ce cas, le propriétaire est l'objet Memcached pour lequel le déploiement a été créé.

5.3.2.4.2. Configurations du contrôleur

Vous pouvez initialiser un contrôleur en utilisant de nombreuses autres configurations utiles. Par exemple, il est possible d'initialiser un contrôleur en utilisant de nombreuses autres configurations utiles :

  • Définissez le nombre maximum de rapprochements simultanés pour le contrôleur en utilisant l'option MaxConcurrentReconciles, dont la valeur par défaut est 1:

    func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {
        return ctrl.NewControllerManagedBy(mgr).
            For(&cachev1.Memcached{}).
            Owns(&appsv1.Deployment{}).
            WithOptions(controller.Options{
                MaxConcurrentReconciles: 2,
            }).
            Complete(r)
    }
  • Filtrer les événements de veille à l'aide de prédicats.
  • Choisissez le type de EventHandler pour modifier la façon dont un événement de surveillance se traduit en demandes de rapprochement pour la boucle de rapprochement. Pour les relations entre opérateurs qui sont plus complexes que les ressources primaires et secondaires, vous pouvez utiliser le gestionnaire EnqueueRequestsFromMapFunc pour transformer un événement de surveillance en un ensemble arbitraire de demandes de rapprochement.

Pour plus de détails sur ces configurations et d'autres, voir les GoDocs sur les constructeurs et les contrôleurs en amont.

5.3.2.4.3. Boucle de réconciliation

Chaque contrôleur possède un objet de rapprochement avec une méthode Reconcile() qui met en œuvre la boucle de rapprochement. La boucle de rapprochement reçoit l'argument Request, qui est une clé d'espace de noms et de noms utilisée pour trouver l'objet de ressource primaire, Memcached, à partir du cache :

import (
	ctrl "sigs.k8s.io/controller-runtime"

	cachev1 "github.com/example-inc/memcached-operator/api/v1"
	...
)

func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
  // Lookup the Memcached instance for this reconcile request
  memcached := &cachev1.Memcached{}
  err := r.Get(ctx, req.NamespacedName, memcached)
  ...
}

En fonction des valeurs de retour, du résultat et de l'erreur, la demande peut être remise en file d'attente et la boucle de rapprochement peut être déclenchée à nouveau :

// Reconcile successful - don't requeue
return ctrl.Result{}, nil
// Reconcile failed due to error - requeue
return ctrl.Result{}, err
// Requeue for any reason other than an error
return ctrl.Result{Requeue: true}, nil

Vous pouvez également paramétrer le site Result.RequeueAfter pour qu'il relance la demande après un délai de grâce :

import "time"

// Reconcile for any reason other than an error after 5 seconds
return ctrl.Result{RequeueAfter: time.Second*5}, nil
Note

Vous pouvez renvoyer Result avec RequeueAfter pour réconcilier périodiquement un CR.

Pour en savoir plus sur les réconciliateurs, les clients et l'interaction avec les événements de ressources, consultez la documentation de l 'API Controller Runtime Client.

5.3.2.4.4. Permissions et manifestes RBAC

Le contrôleur a besoin de certaines autorisations RBAC pour interagir avec les ressources qu'il gère. Ces autorisations sont spécifiées à l'aide de marqueurs RBAC, tels que les suivants :

// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;

func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
  ...
}

Le manifeste de l'objet ClusterRole à l'adresse config/rbac/role.yaml est généré à partir des marqueurs précédents à l'aide de l'utilitaire controller-gen chaque fois que la commande make manifests est exécutée.

5.3.2.5. Activation de la prise en charge du proxy

Les auteurs d'opérateurs peuvent développer des opérateurs qui prennent en charge les proxys réseau. Les administrateurs de clusters configurent la prise en charge du proxy pour les variables d'environnement qui sont gérées par Operator Lifecycle Manager (OLM). Pour prendre en charge les clusters proxy, votre opérateur doit inspecter l'environnement à la recherche des variables proxy standard suivantes et transmettre les valeurs aux opérateurs :

  • HTTP_PROXY
  • HTTPS_PROXY
  • NO_PROXY
Note

Ce tutoriel utilise HTTP_PROXY comme variable d'environnement.

Conditions préalables

  • Un cluster dont le proxy de sortie à l'échelle du cluster est activé.

Procédure

  1. Modifiez le fichier controllers/memcached_controller.go pour y inclure les éléments suivants :

    1. Importez le paquet proxy à partir de la operator-lib bibliothèque :

      import (
        ...
         "github.com/operator-framework/operator-lib/proxy"
      )
    2. Ajoutez la fonction d'aide proxy.ReadProxyVarsFromEnv à la boucle de rapprochement et ajoutez les résultats aux environnements Operand :

      for i, container := range dep.Spec.Template.Spec.Containers {
      		dep.Spec.Template.Spec.Containers[i].Env = append(container.Env, proxy.ReadProxyVarsFromEnv()...)
      }
      ...
  2. Définissez la variable d'environnement sur le déploiement de l'opérateur en ajoutant ce qui suit au fichier config/manager/manager.yaml:

    containers:
     - args:
       - --leader-elect
       - --leader-election-id=ansible-proxy-demo
       image: controller:latest
       name: manager
       env:
         - name: "HTTP_PROXY"
           value: "http_proxy_test"

5.3.2.6. Fonctionnement de l'opérateur

Vous pouvez utiliser l'interface de programmation de l'opérateur SDK de trois manières différentes pour créer et exécuter votre opérateur :

  • Exécuter localement en dehors du cluster comme un programme Go.
  • Exécuter en tant que déploiement sur le cluster.
  • Regroupez votre opérateur et utilisez Operator Lifecycle Manager (OLM) pour le déployer sur le cluster.
Note

Avant d'exécuter votre opérateur basé sur Go en tant que déploiement sur OpenShift Container Platform ou en tant que bundle utilisant OLM, assurez-vous que votre projet a été mis à jour pour utiliser les images prises en charge.

5.3.2.6.1. Exécution locale en dehors du cluster

Vous pouvez exécuter votre projet Operator en tant que programme Go en dehors du cluster. Ceci est utile pour le développement afin d'accélérer le déploiement et les tests.

Procédure

  • Exécutez la commande suivante pour installer les définitions de ressources personnalisées (CRD) dans le cluster configuré dans votre fichier ~/.kube/config et exécutez l'opérateur localement :

    $ make install run

    Exemple de sortie

    ...
    2021-01-10T21:09:29.016-0700	INFO	controller-runtime.metrics	metrics server is starting to listen	{"addr": ":8080"}
    2021-01-10T21:09:29.017-0700	INFO	setup	starting manager
    2021-01-10T21:09:29.017-0700	INFO	controller-runtime.manager	starting metrics server	{"path": "/metrics"}
    2021-01-10T21:09:29.018-0700	INFO	controller-runtime.manager.controller.memcached	Starting EventSource	{"reconciler group": "cache.example.com", "reconciler kind": "Memcached", "source": "kind source: /, Kind="}
    2021-01-10T21:09:29.218-0700	INFO	controller-runtime.manager.controller.memcached	Starting Controller	{"reconciler group": "cache.example.com", "reconciler kind": "Memcached"}
    2021-01-10T21:09:29.218-0700	INFO	controller-runtime.manager.controller.memcached	Starting workers	{"reconciler group": "cache.example.com", "reconciler kind": "Memcached", "worker count": 1}

5.3.2.6.2. Exécution en tant que déploiement sur le cluster

Vous pouvez exécuter votre projet Operator en tant que déploiement sur votre cluster.

Conditions préalables

  • Préparez votre opérateur basé sur Go à fonctionner sur OpenShift Container Platform en mettant à jour le projet pour utiliser les images prises en charge

Procédure

  1. Exécutez les commandes make suivantes pour construire et pousser l'image de l'opérateur. Modifiez l'argument IMG dans les étapes suivantes pour référencer un référentiel auquel vous avez accès. Vous pouvez obtenir un compte pour stocker des conteneurs sur des sites de dépôt tels que Quay.io.

    1. Construire l'image :

      $ make docker-build IMG=<registry>/<user>/<image_name>:<tag>
      Note

      Le fichier Docker généré par le SDK pour l'Operator fait explicitement référence à GOARCH=amd64 pour go build. Cette référence peut être modifiée en GOARCH=$TARGETARCH pour les architectures non-AMD64. Docker définira automatiquement la variable d'environnement à la valeur spécifiée par –platform. Avec Buildah, il faudra utiliser –build-arg à cette fin. Pour plus d'informations, voir Architectures multiples.

    2. Transférer l'image dans un référentiel :

      $ make docker-push IMG=<registry>/<user>/<image_name>:<tag>
      Note

      Le nom et la balise de l'image, par exemple IMG=<registry>/<user>/<image_name>:<tag>, dans les deux commandes peuvent également être définis dans votre Makefile. Modifiez la valeur de IMG ?= controller:latest pour définir votre nom d'image par défaut.

  2. Exécutez la commande suivante pour déployer l'opérateur :

    $ make deploy IMG=<registry>/<user>/<image_name>:<tag>

    Par défaut, cette commande crée un espace de noms avec le nom de votre projet Operator sous la forme <project_name>-system et est utilisé pour le déploiement. Cette commande installe également les manifestes RBAC à partir de config/rbac.

  3. Exécutez la commande suivante pour vérifier que l'opérateur fonctionne :

    oc get deployment -n <nom_du_projet>-système

    Exemple de sortie

    NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
    <project_name>-controller-manager       1/1     1            1           8m

5.3.2.6.3. Regroupement d'un opérateur et déploiement avec Operator Lifecycle Manager
5.3.2.6.3.1. Regroupement d'un opérateur

Le format Operator bundle est la méthode d'emballage par défaut pour Operator SDK et Operator Lifecycle Manager (OLM). Vous pouvez préparer votre Operator pour une utilisation sur OLM en utilisant Operator SDK pour construire et pousser votre projet Operator en tant qu'image groupée.

Conditions préalables

  • Operator SDK CLI installé sur un poste de développement
  • OpenShift CLI (oc) v4.12 installé
  • Projet d'opérateur initialisé à l'aide de l'Operator SDK
  • Si votre opérateur est basé sur Go, votre projet doit être mis à jour pour utiliser les images prises en charge pour fonctionner sur OpenShift Container Platform

Procédure

  1. Exécutez les commandes make suivantes dans le répertoire de votre projet Operator pour construire et pousser votre image Operator. Modifiez l'argument IMG dans les étapes suivantes pour référencer un référentiel auquel vous avez accès. Vous pouvez obtenir un compte pour stocker des conteneurs sur des sites de dépôt tels que Quay.io.

    1. Construire l'image :

      $ make docker-build IMG=<registry>/<user>/<operator_image_name>:<tag>
      Note

      Le fichier Docker généré par le SDK pour l'Operator fait explicitement référence à GOARCH=amd64 pour go build. Cette référence peut être modifiée en GOARCH=$TARGETARCH pour les architectures non-AMD64. Docker définira automatiquement la variable d'environnement à la valeur spécifiée par –platform. Avec Buildah, il faudra utiliser –build-arg à cette fin. Pour plus d'informations, voir Architectures multiples.

    2. Transférer l'image dans un référentiel :

      $ make docker-push IMG=<registry>/<user>/<operator_image_name>:<tag>
  2. Créez votre manifeste Operator bundle en exécutant la commande make bundle, qui invoque plusieurs commandes, dont les sous-commandes Operator SDK generate bundle et bundle validate:

    $ make bundle IMG=<registry>/<user>/<operator_image_name>:<tag>

    Les manifestes de l'offre groupée d'un opérateur décrivent la manière d'afficher, de créer et de gérer une application. La commande make bundle crée les fichiers et répertoires suivants dans votre projet Operator :

    • Un répertoire bundle manifests nommé bundle/manifests qui contient un objet ClusterServiceVersion
    • Un répertoire de métadonnées de la liasse nommé bundle/metadata
    • Toutes les définitions de ressources personnalisées (CRD) dans un répertoire config/crd
    • Un fichier Docker bundle.Dockerfile

    Ces fichiers sont ensuite automatiquement validés à l'aide de operator-sdk bundle validate afin de s'assurer que la représentation du paquet sur le disque est correcte.

  3. Construisez et poussez votre image de bundle en exécutant les commandes suivantes. OLM consomme les liasses d'opérateurs à l'aide d'une image d'index, qui fait référence à une ou plusieurs images de liasses.

    1. Créez l'image de l'ensemble. Définissez BUNDLE_IMG avec les détails du registre, de l'espace de noms de l'utilisateur et de la balise d'image où vous avez l'intention de pousser l'image :

      $ make bundle-build BUNDLE_IMG=<registry>/<user>/<bundle_image_name>:<tag>
    2. Pousser l'image de la liasse :

      $ docker push <registry>/<user>/<bundle_image_name>:<tag>
5.3.2.6.3.2. Déploiement d'un opérateur avec Operator Lifecycle Manager

Operator Lifecycle Manager (OLM) vous aide à installer, mettre à jour et gérer le cycle de vie des opérateurs et de leurs services associés sur un cluster Kubernetes. OLM est installé par défaut sur OpenShift Container Platform et s'exécute en tant qu'extension Kubernetes afin que vous puissiez utiliser la console web et l'OpenShift CLI (oc) pour toutes les fonctions de gestion du cycle de vie des opérateurs sans outils supplémentaires.

Le format Operator bundle est la méthode d'emballage par défaut pour Operator SDK et OLM. Vous pouvez utiliser Operator SDK pour exécuter rapidement une image de bundle sur OLM afin de vous assurer qu'elle fonctionne correctement.

Conditions préalables

  • Operator SDK CLI installé sur un poste de développement
  • L'image de l'ensemble de l'opérateur est construite et poussée vers un registre
  • OLM installé sur un cluster basé sur Kubernetes (v1.16.0 ou version ultérieure si vous utilisez apiextensions.k8s.io/v1 CRD, par exemple OpenShift Container Platform 4.12)
  • Connexion au cluster avec oc en utilisant un compte avec les permissions de cluster-admin
  • Si votre opérateur est basé sur Go, votre projet doit être mis à jour pour utiliser les images prises en charge pour fonctionner sur OpenShift Container Platform

Procédure

  1. Saisissez la commande suivante pour exécuter l'opérateur sur le cluster :

    $ operator-sdk run bundle \1
        -n <namespace> \2
        <registry>/<user>/<bundle_image_name>:<tag> 3
    1
    La commande run bundle crée un catalogue de fichiers valide et installe le paquet Operator sur votre cluster à l'aide d'OLM.
    2
    Facultatif : Par défaut, la commande installe l'opérateur dans le projet actif dans votre fichier ~/.kube/config. Vous pouvez ajouter l'option -n pour définir un espace de noms différent pour l'installation.
    3
    Si vous ne spécifiez pas d'image, la commande utilise quay.io/operator-framework/opm:latest comme image d'index par défaut. Si vous spécifiez une image, la commande utilise l'image du paquet elle-même comme image d'index.
    Important

    Depuis OpenShift Container Platform 4.11, la commande run bundle prend en charge par défaut le format de catalogue basé sur des fichiers pour les catalogues Operator. Le format de base de données SQLite déprécié pour les catalogues Operator continue d'être pris en charge ; cependant, il sera supprimé dans une prochaine version. Il est recommandé aux auteurs d'Operator de migrer leurs flux de travail vers le format de catalogue basé sur des fichiers.

    Cette commande permet d'effectuer les actions suivantes :

    • Créez une image d'index faisant référence à votre image de liasse. L'image d'index est opaque et éphémère, mais elle reflète fidèlement la manière dont un paquet serait ajouté à un catalogue en production.
    • Créez une source de catalogue qui pointe vers votre nouvelle image d'index, ce qui permet à OperatorHub de découvrir votre opérateur.
    • Déployez votre opérateur sur votre cluster en créant un site OperatorGroup, Subscription, InstallPlan, et toutes les autres ressources nécessaires, y compris RBAC.

5.3.2.7. Création d'une ressource personnalisée

Une fois votre opérateur installé, vous pouvez le tester en créant une ressource personnalisée (CR) qui est maintenant fournie sur le cluster par l'opérateur.

Conditions préalables

  • Exemple Memcached Operator, qui fournit le CR Memcached, installé sur un cluster

Procédure

  1. Passez à l'espace de noms dans lequel votre opérateur est installé. Par exemple, si vous avez déployé l'opérateur à l'aide de la commande make deploy:

    $ oc project memcached-operator-system
  2. Modifiez l'exemple de manifeste Memcached CR à l'adresse config/samples/cache_v1_memcached.yaml pour qu'il contienne la spécification suivante :

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    ...
    spec:
    ...
      size: 3
  3. Créer le CR :

    $ oc apply -f config/samples/cache_v1_memcached.yaml
  4. Assurez-vous que l'opérateur Memcached crée le déploiement pour l'échantillon de CR avec la taille correcte :

    $ oc get deployments

    Exemple de sortie

    NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
    memcached-operator-controller-manager   1/1     1            1           8m
    memcached-sample                        3/3     3            3           1m

  5. Vérifiez l'état des pods et du CR pour confirmer que l'état est mis à jour avec les noms des pods Memcached.

    1. Vérifier les gousses :

      $ oc get pods

      Exemple de sortie

      NAME                                  READY     STATUS    RESTARTS   AGE
      memcached-sample-6fd7c98d8-7dqdr      1/1       Running   0          1m
      memcached-sample-6fd7c98d8-g5k7v      1/1       Running   0          1m
      memcached-sample-6fd7c98d8-m7vn7      1/1       Running   0          1m

    2. Vérifier l'état de la CR :

      $ oc get memcached/memcached-sample -o yaml

      Exemple de sortie

      apiVersion: cache.example.com/v1
      kind: Memcached
      metadata:
      ...
        name: memcached-sample
      ...
      spec:
        size: 3
      status:
        nodes:
        - memcached-sample-6fd7c98d8-7dqdr
        - memcached-sample-6fd7c98d8-g5k7v
        - memcached-sample-6fd7c98d8-m7vn7

  6. Mettre à jour la taille du déploiement.

    1. Mettre à jour le fichier config/samples/cache_v1_memcached.yaml pour modifier le champ spec.size dans le CR Memcached de 3 à 5:

      $ oc patch memcached memcached-sample \
          -p '{"spec":{"size": 5}}' \
          --type=merge
    2. Confirmez que l'opérateur modifie la taille du déploiement :

      $ oc get deployments

      Exemple de sortie

      NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
      memcached-operator-controller-manager   1/1     1            1           10m
      memcached-sample                        5/5     5            5           3m

  7. Supprimez le CR en exécutant la commande suivante :

    $ oc delete -f config/samples/cache_v1_memcached.yaml
  8. Nettoyer les ressources qui ont été créées dans le cadre de ce tutoriel.

    • Si vous avez utilisé la commande make deploy pour tester l'opérateur, exécutez la commande suivante :

      $ make undeploy
    • Si vous avez utilisé la commande operator-sdk run bundle pour tester l'opérateur, exécutez la commande suivante :

      $ operator-sdk cleanup <nom_du_projet>

5.3.2.8. Ressources supplémentaires

5.3.3. Présentation du projet pour les opérateurs basés à Go

Le CLI operator-sdk peut générer, ou scaffold, un certain nombre de paquets et de fichiers pour chaque projet Operator.

5.3.3.1. Présentation d'un projet basé sur Go

Les projets Operator basés sur Go, le type par défaut, générés à l'aide de la commande operator-sdk init contiennent les fichiers et répertoires suivants :

Fichier ou répertoireObjectif

main.go

Programme principal de l'opérateur. Il instancie un nouveau gestionnaire qui enregistre toutes les définitions de ressources personnalisées (CRD) dans le répertoire apis/ et démarre tous les contrôleurs dans le répertoire controllers/.

apis/

Arborescence de répertoires qui définit les API des CRD. Vous devez modifier les fichiers apis/<version>/<kind>_types.go pour définir l'API de chaque type de ressource et importer ces paquets dans vos contrôleurs pour surveiller ces types de ressources.

controllers/

Implémentations de contrôleurs. Modifiez les fichiers controller/<kind>_controller.go afin de définir la logique de rapprochement du contrôleur pour la gestion d'un type de ressource du type spécifié.

config/

Manifestes Kubernetes utilisés pour déployer votre contrôleur sur un cluster, y compris les CRD, RBAC et les certificats.

Makefile

Cibles utilisées pour construire et déployer votre contrôleur.

Dockerfile

Instructions utilisées par un moteur de conteneur pour construire votre opérateur.

manifests/

Les manifestes Kubernetes pour l'enregistrement des CRD, la configuration du RBAC et le déploiement de l'opérateur en tant que déploiement.

5.3.4. Mise à jour des projets Operator basés sur Go pour les nouvelles versions du SDK Operator

OpenShift Container Platform 4.12 supporte Operator SDK 1.25.4. Si vous avez déjà le CLI 1.22.0 installé sur votre station de travail, vous pouvez mettre à jour le CLI vers 1.25.4 en installant la dernière version.

Cependant, pour que vos projets Operator existants restent compatibles avec Operator SDK 1.25.4, des étapes de mise à jour sont nécessaires pour les ruptures associées introduites depuis la version 1.22.0. Vous devez effectuer les étapes de mise à jour manuellement dans tous vos projets Operator qui ont été précédemment créés ou maintenus avec la version 1.22.0.

5.3.4.1. Mise à jour des projets Operator basés sur Go pour Operator SDK 1.25.4

La procédure suivante met à jour un projet Go-based Operator existant pour le rendre compatible avec la version 1.25.4.

Conditions préalables

  • Operator SDK 1.25.4 installé
  • Un projet Operator créé ou maintenu avec Operator SDK 1.22.0

Procédure

  1. Apportez les modifications suivantes au fichier config/default/manager_auth_proxy_patch.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: controller-manager
      namespace: system
    spec:
      template:
        spec:
          containers:
          - name: kube-rbac-proxy
            image: registry.redhat.io/openshift4/ose-kube-rbac-proxy:v4.12 1
            args:
            - "--secure-listen-address=0.0.0.0:8443"
            - "--upstream=http://127.0.0.1:8080/"
            - "--logtostderr=true"
            - "--v=0"
    ...
    1
    Mettre à jour la version de la balise de v4.11 à v4.12.
  2. Apportez les modifications suivantes à votre site Makefile:

    1. Pour activer la prise en charge des architectures multiples, ajoutez la cible docker-buildx à votre projet Makefile:

      Exemple Makefile

      # PLATFORMS defines the target platforms for  the manager image be build to provide support to multiple
      # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
      # - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
      # - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
      # - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> than the export will fail)
      # To properly provided solutions that supports more than one platform you should use this option.
      PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
      .PHONY: docker-buildx
      docker-buildx: test ## Build and push docker image for the manager for cross-platform support
      	# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
      	sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
      	- docker buildx create --name project-v3-builder
      	docker buildx use project-v3-builder
      	- docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross
      	- docker buildx rm project-v3-builder
      	rm Dockerfile.cross

    2. Mettez à jour l'échafaudage de votre projet pour prendre en charge les modifications apportées à kubebuilder, comme le montre l'exemple suivant :

      Ancienne Makefile

      .PHONY: test
      test: manifests generate fmt vet envtest ## Run tests.
       	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out

      Nouveau Makefile

      .PHONY: test
      test: manifests generate fmt vet envtest ## Run tests.
      	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)"  go test $(go list ./... | grep -v /test/) -coverprofile cover.out

    3. Pour s'assurer que les cibles de Makefile ne téléchargent pas des binaires déjà présents dans votre chemin binaire, apportez les modifications suivantes à votre fichier Makefile:

      Ancienne Makefile

      KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
      .PHONY: kustomize
      kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
      $(KUSTOMIZE): $(LOCALBIN)
      	{ curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); }
      
      .PHONY: controller-gen
      controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
      $(CONTROLLER_GEN): $(LOCALBIN)
      	test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION
      	GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
      
      .PHONY: envtest
      envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
      $(ENVTEST): $(LOCALBIN)
       	GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest

      Nouveau Makefile

      KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
      .PHONY: kustomize
      kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
      $(KUSTOMIZE): $(LOCALBIN)
      	test -s $(LOCALBIN)/kustomize || { curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); } 1
      
      .PHONY: controller-gen
      controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
      $(CONTROLLER_GEN): $(LOCALBIN)
      	test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) 2
      
      .PHONY: envtest
      envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
      $(ENVTEST): $(LOCALBIN)
      	test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest 3

      1
      Ajouter test -s $(LOCALBIN)/<binary-name> || avant l'instruction de téléchargement d'un binaire.
      2
      Ajouter test -s $(LOCALBIN)/<binary-name> || avant l'instruction de téléchargement d'un binaire.
      3
      Ajouter test -s $(LOCALBIN)/<binary-name> || avant l'instruction de téléchargement d'un binaire.
    4. Mettez à jour controller-tools vers la version v0.9.2 comme indiqué dans l'exemple suivant :

      Exemple `Makefile

      ## Tool Versions
      KUSTOMIZE_VERSION ?= v3.8.7
      CONTROLLER_TOOLS_VERSION ?= v0.9.2 1

      1
      Mise à jour de la version v0.9.0 vers v0.9.2.
    5. Pour appliquer les changements à votre Makefile et reconstruire votre Opérateur, entrez la commande suivante :

      $ make
  3. Pour mettre à jour Go et ses dépendances, apportez les modifications suivantes à votre fichier go.mod:

    go 1.19 1
    
    require (
      github.com/onsi/ginkgo/v2 v2.1.4 2
      github.com/onsi/gomega v1.19.0 3
      k8s.io/api v0.25.0 4
      k8s.io/apimachinery v0.25.0 5
      k8s.io/client-go v0.25.0 6
      sigs.k8s.io/controller-runtime v0.13.0 7
    )
    1
    Mise à jour de la version 1.18 vers 1.19.
    2
    Mise à jour de la version v1.16.5 vers v2.1.4.
    3
    Mise à jour de la version v1.18.1 vers v1.19.0.
    4
    Mise à jour de la version v0.24.0 vers v0.25.0.
    5
    Mise à jour de la version v0.24.0 vers v0.25.0.
    6
    Mise à jour de la version v0.24.0 vers v0.25.0.
    7
    Mise à jour de la version v0.12.1 vers v0.13.0.
  4. Pour télécharger les versions mises à jour, nettoyer les dépendances et appliquer les changements dans votre fichier go.mod, exécutez la commande suivante :

    $ go mod tidy

5.3.4.2. Ressources supplémentaires

Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.