5.3. 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 Go pour Memcached, un magasin à valeur clé distribué, et gérer son cycle de vie.

Important

La version prise en charge par Red Hat de l’outil Operator SDK CLI, y compris les outils d’échafaudage et de test connexes pour les projets Opérateur, est dépréciée et devrait être supprimée dans une future version de Red Hat OpenShift Service sur AWS. Le Red Hat fournira des corrections de bogues et une prise en charge de cette fonctionnalité pendant le cycle de vie de la version actuelle, mais cette fonctionnalité ne recevra plus d’améliorations et sera supprimée du futur service Red Hat OpenShift sur les versions AWS.

La version prise en charge par Red Hat du SDK de l’opérateur n’est pas recommandée pour la création de nouveaux projets d’opérateur. Les auteurs d’opérateurs avec des projets d’opérateur existants peuvent utiliser la version de l’outil Operator SDK CLI publié avec Red Hat OpenShift Service sur AWS 4 pour maintenir leurs projets et créer des versions d’opérateur ciblant de nouvelles versions de Red Hat OpenShift Service sur AWS.

Les images de base suivantes pour les projets d’opérateur ne sont pas dépréciées. Les fonctionnalités d’exécution et les API de configuration de ces images de base sont toujours prises en charge pour les corrections de bogues et pour l’adressage des CVE.

  • L’image de base pour les projets d’opérateurs basés sur Ansible
  • L’image de base pour les projets d’opérateur basé sur Helm

Afin d’obtenir de l’information sur la version non prise en charge et gérée par la communauté du SDK de l’opérateur, voir Operator SDK (Operator Framework).

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

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

Ce tutoriel va plus en détail que commencer avec Operator SDK pour les opérateurs Go dans la documentation OpenShift Container Platform.

5.3.1.1. Conditions préalables

  • L’opérateur SDK CLI installé
  • Installation d’OpenShift CLI (oc) 4+
  • Aller 1.21+
  • Connexion à un service Red Hat OpenShift sur AWS cluster avec un compte doté d’autorisations d’administration dédiées
  • Afin de permettre au cluster de tirer l’image, le référentiel où vous poussez votre image doit être défini comme public, ou vous devez configurer une image pull secret

5.3.1.2. Créer un projet

Faites appel à l’opérateur SDK CLI 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
    Copy to Clipboard Toggle word wrap
  2. Changement dans le répertoire:

    $ cd $HOME/projects/memcached-operator
    Copy to Clipboard Toggle word wrap
  3. Activer la prise en charge des modules Go:

    $ export GO111MODULE=on
    Copy to Clipboard Toggle word wrap
  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
    Copy to Clipboard Toggle word wrap
    Note

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

    La commande operator-sdk init génère un fichier go.mod à utiliser avec les modules Go. L’indicateur --repo est requis 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 chemin de module valide.

5.3.1.2.1. Fichier PROJET

Il y a parmi les fichiers générés par la commande operator-sdk init un fichier Kubebuilder PROJECT. Les commandes ultérieures de l’opérateur-sdk, ainsi que la sortie d’aide, qui sont exécutées à partir de la racine du projet lisent ce fichier et sont conscientes que le type de projet est Go. À titre d’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: {}
Copy to Clipboard Toggle word wrap
5.3.1.2.2. À propos du gestionnaire

Le programme principal pour l’opérateur est le fichier main.go, qui initialise et exécute le gestionnaire. Le gestionnaire enregistre automatiquement le Schéma pour toutes les définitions de l’API de ressources personnalisées (CR) et configure et exécute des contrôleurs et des webhooks.

Le gestionnaire peut restreindre l’espace de noms que tous les contrôleurs surveillent pour les ressources:

mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: namespace})
Copy to Clipboard Toggle word wrap

Le gestionnaire surveille par défaut l’espace de noms où l’opérateur s’exécute. Afin de regarder tous les espaces de noms, vous pouvez laisser l’option namespace vide:

mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: ""})
Copy to Clipboard Toggle word wrap

Il est également possible d’utiliser la fonction MultiNamespacedCacheBuilder pour regarder un ensemble spécifique d’espaces de noms:

var namespaces []string 
1

mgr, err := ctrl.NewManager(cfg, manager.Options{ 
2

   NewCache: cache.MultiNamespacedCacheBuilder(namespaces),
})
Copy to Clipboard Toggle word wrap
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.1.2.3. À propos des API multi-groupes

Avant de créer une API et un contrôleur, examinez si votre opérateur nécessite plusieurs groupes d’API. Ce tutoriel couvre le cas par défaut d’une API de groupe unique, mais pour modifier la mise en page de votre projet pour prendre en charge les API multi-groupes, vous pouvez exécuter la commande suivante:

$ operator-sdk edit --multigroup=true
Copy to Clipboard Toggle word wrap

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

domain: example.com
layout: go.kubebuilder.io/v3
multigroup: true
...
Copy to Clipboard Toggle word wrap

Dans le cas des projets multigroupes, les fichiers de type API Go sont créés dans le répertoire apis/<group>/&lt;version&gt;/ et les contrôleurs sont créés dans le répertoire Controllers/<group>/ /. Le Dockerfile est ensuite mis à jour en conséquence.

B) Ressources supplémentaires

  • Consultez la documentation Kubebuilder pour plus de détails sur la migration vers un projet multigroupe.

5.3.1.3. Création d’une API et d’un contrôleur

Faites appel à l’opérateur SDK CLI 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 cache de groupe, version, v1, et sortez Memcached:

    $ operator-sdk create api \
        --group=cache \
        --version=v1 \
        --kind=Memcached
    Copy to Clipboard Toggle word wrap
  2. Lorsque vous l’invitez, entrez y pour créer à la fois la ressource et le contrôleur:

    Create Resource [y/n]
    y
    Create Controller [y/n]
    y
    Copy to Clipboard Toggle word wrap

    Exemple de sortie

    Writing scaffold for you to edit...
    api/v1/memcached_types.go
    controllers/memcached_controller.go
    ...
    Copy to Clipboard Toggle word wrap

Ce processus génère l’API de ressource Memcached sur api/v1/memcached_types.go et le contrôleur à Controllers/memcached_controller.go.

5.3.1.3.1. Définir l’API

Définissez l’API pour la ressource personnalisée Memcached (CR).

Procédure

  1. De modifier les définitions de type Go sur api/v1/memcached_types.go pour avoir les spécifications et le statut suivants:

    // 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"`
    }
    Copy to Clipboard Toggle word wrap
  2. Actualisez le code généré pour le type de ressource:

    $ make generate
    Copy to Clipboard Toggle word wrap
    Astuce

    Après avoir modifié un fichier *_types.go, vous devez exécuter la commande make Generator 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 garantit que vos définitions de type API Go implémentent l’interface runtime.Object que tous les types de type doivent implémenter.

5.3.1.3.2. Générer des manifestes CRD

Après que l’API est définie avec des champs de spécification et d’état et des marqueurs de validation de la définition de 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
    Copy to Clipboard Toggle word wrap

    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.1.3.2.1. À propos de la validation 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 dans une ressource personnalisée Memcached (CR) lorsqu’elle est créée ou mise à jour.

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

5.3.1.4. Implémentation du contrôleur

Après avoir créé une nouvelle API et un nouveau contrôleur, vous pouvez implémenter la logique du contrôleur.

Procédure

  • Dans cet exemple, remplacez les contrôleurs de fichiers de contrôleur générés/memcached_controller.go par une implémentation d’exemple suivante:

    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"
            ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
    
            cachev1 "github.com/example-inc/memcached-operator/api/v1"
    )
    
    // 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)
            log := ctrllog.FromContext(ctx)
            // Fetch the Memcached instance
            memcached := &cachev1.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 *cachev1.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(&cachev1.Memcached{}).
                    Owns(&appsv1.Deployment{}).
                    Complete(r)
    }
    Copy to Clipboard Toggle word wrap

    Le contrôleur d’exemple exécute la logique de réconciliation suivante pour chaque ressource personnalisée Memcached (CR):

    • Créez un déploiement Memcached s’il n’existe pas.
    • Assurez-vous que la taille de déploiement est la même que celle spécifiée par la spécification CR Memcached.
    • Actualisez le statut de Memcached CR avec les noms des pods memcached.

Les sous-sections suivantes expliquent comment le contrôleur dans l’exemple de mise en œuvre surveille les ressources et comment la boucle de rapprochement est déclenchée. Ces sous-sections peuvent passer directement à Running the Operator.

5.3.1.4.1. Les ressources surveillées par le contrôleur

La fonction SetupWithManager() dans Controllers/memcached_controller.go spécifie comment le contrôleur est conçu pour regarder 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)
}
Copy to Clipboard Toggle word wrap

Le NewControllerManagedBy() fournit un constructeur de contrôleur qui permet diverses configurations de contrôleur.

For(&amp;cachev1.Memcached{}) spécifie le type Memcached comme ressource principale à regarder. Dans chaque événement Ajouter, mettre à jour ou Supprimer pour un type Memcached, la boucle de réconciliation reçoit un argument Demande réconciliée, qui se compose d’un espace de noms et d’une clé de nom, pour cet objet Memcached.

Owns(&amp;appsv1.Deployment{}) spécifie le type de déploiement comme ressource secondaire à regarder. Dans chaque type de déploiement Ajouter, mettre à jour ou supprimer un événement, le gestionnaire d’événements cartographie 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.1.4.2. Configurations du contrôleur

Il est possible d’initialiser un contrôleur en utilisant de nombreuses autres configurations utiles. À titre d’exemple:

  • Définissez le nombre maximal de rapprochements simultanés pour le contrôleur en utilisant l’option MaxConcurrentReconciles, qui par défaut à 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)
    }
    Copy to Clipboard Toggle word wrap
  • Filtrez les événements à l’aide de prédicats.
  • Choisissez le type d’EventHandler pour changer la façon dont un événement montre se traduit pour concilier les demandes de la boucle de réconciliation. Dans le cas des relations avec les opérateurs qui sont plus complexes que les ressources primaires et secondaires, vous pouvez utiliser le gestionnaire EnqueueRequestsFromMapFunc pour transformer un événement de montre en un ensemble arbitraire de demandes de rapprochement.

Consultez le Builder et le contrôleur GoDocs en amont pour plus de détails sur ces configurations et d’autres.

5.3.1.4.3. Boucle de réconciliation

Chaque contrôleur a un objet réconciliateur avec une méthode Reconcile() qui implémente la boucle de réconciliation. La boucle de réconciliation est passée l’argument Demande, qui est un espace de noms et la clé de nom utilisé 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)
  ...
}
Copy to Clipboard Toggle word wrap

Basé sur les valeurs de retour, le résultat et l’erreur, la requête peut être requeued et la boucle de réconciliation 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
Copy to Clipboard Toggle word wrap

Après une période de grâce, vous pouvez définir le résultat.Requeue Après avoir requelé la demande:

import "time"

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

Il est possible de retourner Résultat avec Requeue après ensemble pour réconcilier périodiquement un CR.

En savoir plus sur les réconciliateurs, les clients et les interactions avec les événements de ressources, consultez la documentation de l’API Controller Runtime Client.

5.3.1.4.4. Autorisations et manifestations RBAC

Le contrôleur nécessite certaines autorisations RBAC pour interagir avec les ressources qu’il gère. Ceux-ci sont spécifiés à 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) {
  ...
}
Copy to Clipboard Toggle word wrap

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

5.3.1.5. Activer le support proxy

Les auteurs d’opérateurs peuvent développer des opérateurs qui prennent en charge les proxys réseau. Les administrateurs dotés du rôle d’administrateur dédié configurent la prise en charge du proxy pour les variables d’environnement qui sont gérées par Operator Lifecycle Manager (OLM). Afin de prendre en charge les clusters proxiés, votre opérateur doit inspecter l’environnement pour les variables proxy standard suivantes et transmettre les valeurs à Operands:

  • HTTP_PROXY
  • HTTPS_PROXY
  • AUCUN_PROXY
Note

Ce tutoriel utilise HTTP_PROXY comme exemple de variable d’environnement.

Conditions préalables

  • C’est un cluster doté d’un proxy de sortie à l’échelle du cluster activé.

Procédure

  1. Éditez le fichier Controllers/memcached_controller.go pour inclure ce qui suit:

    1. Importer le paquet proxy à partir de la bibliothèque de l’opérateur-lib:

      import (
        ...
         "github.com/operator-framework/operator-lib/proxy"
      )
      Copy to Clipboard Toggle word wrap
    2. Ajouter la fonction d’aide proxy.ReadProxyVarsFromEnv à la boucle de réconciliation et ajouter 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()...)
      }
      ...
      Copy to Clipboard Toggle word wrap
  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"
    Copy to Clipboard Toggle word wrap

5.3.1.6. Exécution de l’opérateur

Afin de construire et d’exécuter votre opérateur, utilisez l’opérateur SDK CLI pour regrouper votre opérateur, puis utilisez le gestionnaire de cycle de vie de l’opérateur (OLM) pour le déploiement sur le cluster.

Note

Lorsque vous souhaitez déployer votre opérateur sur un cluster OpenShift Container Platform au lieu d’un service Red Hat OpenShift sur AWS, deux options de déploiement supplémentaires sont disponibles:

  • Exécutez localement en dehors du cluster en tant que programme Go.
  • Exécutez comme un déploiement sur le cluster.
Note

Avant d’exécuter votre opérateur Go-based en tant que paquet utilisant OLM, assurez-vous que votre projet a été mis à jour pour utiliser les images prises en charge.

5.3.1.6.1.1. Groupement d’un opérateur

Le format de paquet Opérateur est la méthode d’emballage par défaut pour Operator SDK et Operator Lifecycle Manager (OLM). En utilisant le SDK de l’opérateur, vous pouvez préparer votre opérateur à une utilisation sur OLM pour construire et pousser votre projet Opérateur en tant qu’image groupée.

Conditions préalables

  • L’opérateur SDK CLI installé sur un poste de travail de développement
  • Installation d’OpenShift CLI (oc) v4+
  • Le projet d’opérateur initialisé à l’aide du SDK de l’opérateur
  • Dans le cas où votre opérateur est Go-based, votre projet doit être mis à jour pour utiliser les images prises en charge pour s’exécuter sur Red Hat OpenShift Service sur AWS

Procédure

  1. Exécutez les commandes suivantes dans votre répertoire de projet Opérateur pour construire et pousser l’image de votre opérateur. Modifiez l’argument IMG dans les étapes suivantes pour faire référence à un référentiel auquel vous avez accès. Il est possible d’obtenir un compte de stockage 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>
      Copy to Clipboard Toggle word wrap
      Note

      Le Dockerfile généré par le SDK pour l’opérateur renvoie explicitement GOARCH=amd64 pour la construction de go. Cela peut être modifié à GOARCH=$TARGETARCH pour les architectures non-AMD64. Docker définira automatiquement la variable d’environnement à la valeur spécifiée par -platform. Avec Buildah, le -build-arg devra être utilisé à cet effet. En savoir plus, consultez Multiple Architectures.

    2. Appuyez sur l’image vers un référentiel:

      $ make docker-push IMG=<registry>/<user>/<operator_image_name>:<tag>
      Copy to Clipboard Toggle word wrap
  2. Créez votre paquet Opérateur manifeste en exécutant la commande make bundle, qui invoque plusieurs commandes, y compris l’opérateur SDK génère des paquets et des sous-commandes validant:

    $ make bundle IMG=<registry>/<user>/<operator_image_name>:<tag>
    Copy to Clipboard Toggle word wrap

    Les manifestes de paquets pour un opérateur décrivent comment afficher, créer et gérer une application. La commande make bundle crée les fichiers et répertoires suivants dans votre projet Opérateur:

    • Le bundle manifeste un répertoire nommé bundle/manifests qui contient un objet ClusterServiceVersion
    • Annuaire de métadonnées groupé nommé bundle/metadata
    • L’ensemble des définitions de ressources personnalisées (CRD) dans un répertoire config/crd
    • Dockerfile bundle.Dockerfile

    Ces fichiers sont ensuite automatiquement validés en utilisant le bundle opérateur-sdk valide pour s’assurer que la représentation des faisceaux sur disque est correcte.

  3. Créez et poussez votre image de paquet en exécutant les commandes suivantes. L’OLM consomme des faisceaux d’opérateurs à l’aide d’une image d’index, qui référence à une ou plusieurs images groupées.

    1. Construisez l’image du bundle. Définissez BUNDLE_IMG avec les détails du registre, de l’espace de noms d’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>
      Copy to Clipboard Toggle word wrap
    2. Appuyez sur l’image du paquet:

      $ docker push <registry>/<user>/<bundle_image_name>:<tag>
      Copy to Clipboard Toggle word wrap

Le gestionnaire de cycle de vie de l’opérateur (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. Le système OLM est installé par défaut sur Red Hat OpenShift Service sur AWS et s’exécute sous forme d’extension Kubernetes afin que vous puissiez utiliser la console Web et OpenShift CLI (oc) pour toutes les fonctions de gestion du cycle de vie de l’opérateur sans outils supplémentaires.

Le format de paquet opérateur est la méthode d’emballage par défaut pour l’opérateur SDK et OLM. Le SDK de l’opérateur permet d’exécuter rapidement une image groupée sur OLM afin de s’assurer qu’elle fonctionne correctement.

Conditions préalables

  • L’opérateur SDK CLI installé sur un poste de travail de développement
  • Ensemble d’image de l’opérateur construit et poussé à un registre
  • Installation OLM sur un cluster basé sur Kubernetes (v1.16.0 ou version ultérieure si vous utilisez apiextensions.k8s.io/v1 CRDs, par exemple Red Hat OpenShift Service sur AWS 4)
  • Connexion au cluster avec oc à l’aide d’un compte avec des autorisations d’administration dédiées
  • Dans le cas où votre opérateur est Go-based, votre projet doit être mis à jour pour utiliser les images prises en charge pour s’exécuter sur Red Hat OpenShift Service sur AWS

Procédure

  • Entrez 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
    Copy to Clipboard Toggle word wrap
    1
    La commande run bundle crée un catalogue basé sur des fichiers valide et installe le paquet Opérateur sur votre cluster en utilisant OLM.
    2
    Facultatif: Par défaut, la commande installe l’opérateur dans le projet actuellement actif dans votre fichier ~/.kube/config. Il est possible d’ajouter le drapeau -n pour définir un espace de noms différent pour l’installation.
    3
    Dans le cas où vous ne spécifiez pas une image, la commande utilise quay.io/operator-framework/opm:latest comme image d’index par défaut. Lorsque vous spécifiez une image, la commande utilise l’image du faisceau lui-même comme image d’index.
    Important

    À partir de Red Hat OpenShift Service sur AWS 4.11, la commande run bundle prend en charge le format de catalogue basé sur des fichiers pour les catalogues d’opérateurs par défaut. Le format de base de données SQLite obsolète pour les catalogues d’opérateurs continue d’être pris en charge; cependant, il sera supprimé dans une version ultérieure. Il est recommandé aux auteurs de l’opérateur de migrer leurs flux de travail vers le format de catalogue basé sur les fichiers.

    Cette commande effectue les actions suivantes:

    • Créez une image d’index faisant référence à votre image de paquet. L’image de l’index est opaque et éphémère, mais reflète avec précision comment 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 dans votre cluster en créant un groupe d’opérateurs, un abonnement, un plan d’installation et toutes les autres ressources requises, y compris RBAC.

5.3.1.7. Créer une ressource personnalisée

Après l’installation de votre opérateur, 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 Memcached CR, installé sur un cluster

Procédure

  1. Changer l’espace de noms où votre opérateur est installé. À titre d’exemple, si vous avez déployé l’opérateur à l’aide de la commande make deployment:

    $ oc project memcached-operator-system
    Copy to Clipboard Toggle word wrap
  2. Éditer l’échantillon Memcached CR manifeste à config/samples/cache_v1_memcached.yaml pour contenir les spécifications suivantes:

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    ...
    spec:
    ...
      size: 3
    Copy to Clipboard Toggle word wrap
  3. Créer le CR:

    $ oc apply -f config/samples/cache_v1_memcached.yaml
    Copy to Clipboard Toggle word wrap
  4. Assurez-vous que l’opérateur Memcached crée le déploiement de l’échantillon CR avec la bonne taille:

    $ oc get deployments
    Copy to Clipboard Toggle word wrap

    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
    Copy to Clipboard Toggle word wrap

  5. Consultez le statut des pods et CR pour confirmer que le statut est mis à jour avec les noms de pod de Memcached.

    1. Consultez les gousses:

      $ oc get pods
      Copy to Clipboard Toggle word wrap

      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
      Copy to Clipboard Toggle word wrap

    2. Consultez l’état CR:

      $ oc get memcached/memcached-sample -o yaml
      Copy to Clipboard Toggle word wrap

      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
      Copy to Clipboard Toggle word wrap

  6. Actualisez la taille du déploiement.

    1. Actualisez 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
      Copy to Clipboard Toggle word wrap
    2. Confirmez que l’opérateur modifie la taille du déploiement:

      $ oc get deployments
      Copy to Clipboard Toggle word wrap

      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
      Copy to Clipboard Toggle word wrap

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

    $ oc delete -f config/samples/cache_v1_memcached.yaml
    Copy to Clipboard Toggle word wrap
  8. Nettoyez les ressources qui ont été créées dans le cadre de ce tutoriel.

    • Lorsque vous avez utilisé la commande make deployment pour tester l’opérateur, exécutez la commande suivante:

      $ make undeploy
      Copy to Clipboard Toggle word wrap
    • Lorsque vous avez utilisé la commande operator-sdk run bundle pour tester l’opérateur, exécutez la commande suivante:

      $ operator-sdk cleanup <project_name>
      Copy to Clipboard Toggle word wrap

5.3.2. Aménagement du projet pour les opérateurs Go-based

L’opérateur-sdk CLI peut générer, ou échafauder, un certain nombre de paquets et de fichiers pour chaque projet d’opérateur.

Important

La version prise en charge par Red Hat de l’outil Operator SDK CLI, y compris les outils d’échafaudage et de test connexes pour les projets Opérateur, est dépréciée et devrait être supprimée dans une future version de Red Hat OpenShift Service sur AWS. Le Red Hat fournira des corrections de bogues et une prise en charge de cette fonctionnalité pendant le cycle de vie de la version actuelle, mais cette fonctionnalité ne recevra plus d’améliorations et sera supprimée du futur service Red Hat OpenShift sur les versions AWS.

La version prise en charge par Red Hat du SDK de l’opérateur n’est pas recommandée pour la création de nouveaux projets d’opérateur. Les auteurs d’opérateurs avec des projets d’opérateur existants peuvent utiliser la version de l’outil Operator SDK CLI publié avec Red Hat OpenShift Service sur AWS 4 pour maintenir leurs projets et créer des versions d’opérateur ciblant de nouvelles versions de Red Hat OpenShift Service sur AWS.

Les images de base suivantes pour les projets d’opérateur ne sont pas dépréciées. Les fonctionnalités d’exécution et les API de configuration de ces images de base sont toujours prises en charge pour les corrections de bogues et pour l’adressage des CVE.

  • L’image de base pour les projets d’opérateurs basés sur Ansible
  • L’image de base pour les projets d’opérateur basé sur Helm

Afin d’obtenir de l’information sur la version non prise en charge et gérée par la communauté du SDK de l’opérateur, voir Operator SDK (Operator Framework).

5.3.2.1. Configuration du projet Go-based

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

Expand
Fichier ou répertoireBut

à propos de Main.go

Le programme principal de l’opérateur. Ceci 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 contrôleurs / répertoire.

APIs/

Arbre de répertoire qui définit les API des CRDs. Il faut modifier les fichiers apis/&lt;version&gt;/&lt;kind&gt;_types.go pour définir l’API pour chaque type de ressource et importer ces paquets dans vos contrôleurs pour surveiller ces types de ressources.

contrôleurs/

Implémentations de contrôleur. Éditez les fichiers Controller/&lt;kind&gt;_controller.go pour définir la logique de réconciliation du contrôleur pour gérer un type de ressource du type spécifié.

configuration/

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

À propos de 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.

les manifestes/

Kubernetes se manifeste pour l’enregistrement des CRD, la mise en place de RBAC et le déploiement de l’opérateur en tant que déploiement.

Le service OpenShift Red Hat sur AWS 4 prend en charge le SDK 1.38.0 de l’opérateur. Lorsque vous disposez déjà du 1.36.1 CLI installé sur votre poste de travail, vous pouvez mettre à jour le CLI à 1.38.0 en installant la dernière version.

Important

La version prise en charge par Red Hat de l’outil Operator SDK CLI, y compris les outils d’échafaudage et de test connexes pour les projets Opérateur, est dépréciée et devrait être supprimée dans une future version de Red Hat OpenShift Service sur AWS. Le Red Hat fournira des corrections de bogues et une prise en charge de cette fonctionnalité pendant le cycle de vie de la version actuelle, mais cette fonctionnalité ne recevra plus d’améliorations et sera supprimée du futur service Red Hat OpenShift sur les versions AWS.

La version prise en charge par Red Hat du SDK de l’opérateur n’est pas recommandée pour la création de nouveaux projets d’opérateur. Les auteurs d’opérateurs avec des projets d’opérateur existants peuvent utiliser la version de l’outil Operator SDK CLI publié avec Red Hat OpenShift Service sur AWS 4 pour maintenir leurs projets et créer des versions d’opérateur ciblant de nouvelles versions de Red Hat OpenShift Service sur AWS.

Les images de base suivantes pour les projets d’opérateur ne sont pas dépréciées. Les fonctionnalités d’exécution et les API de configuration de ces images de base sont toujours prises en charge pour les corrections de bogues et pour l’adressage des CVE.

  • L’image de base pour les projets d’opérateurs basés sur Ansible
  • L’image de base pour les projets d’opérateur basé sur Helm

Afin d’obtenir de l’information sur la version non prise en charge et gérée par la communauté du SDK de l’opérateur, voir Operator SDK (Operator Framework).

Cependant, pour s’assurer que vos projets d’opérateur existants maintiennent la compatibilité avec le SDK 1.38.0 de l’opérateur, des étapes de mise à jour sont nécessaires pour les modifications de rupture associées introduites depuis 1.36.1. Les étapes de mise à jour doivent être exécutées manuellement dans l’un de vos projets Opérateurs qui ont été précédemment créés ou maintenus avec 1.36.1.

La procédure suivante met à jour un projet existant d’opérateur basé sur Go pour la compatibilité avec 1.38.0.

Conditions préalables

  • L’opérateur SDK 1.38.0 installé
  • Création ou maintenance d’un projet opérateur avec l’opérateur SDK 1.36.1

Procédure

  1. Éditez le Makefile de votre projet Opérateur pour mettre à jour la version SDK de l’opérateur vers 1.38.0, comme indiqué dans l’exemple suivant:

    Exemple de Makefile

    # Set the Operator SDK version to use. By default, what is installed on the system is used.
    # This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit.
    OPERATOR_SDK_VERSION ?= v1.38.0 
    1
    Copy to Clipboard Toggle word wrap

    1
    Changer la version de 1.36.1 à 1.38.0.
  2. Il faut mettre à niveau les versions Kubernetes de votre projet Opérateur pour utiliser 1.30 et Kubebuilder v4.

    Astuce

    Cette mise à jour comprend des changements complexes d’échafaudage en raison de l’élimination du kube-rbac-proxy. Lorsque ces migrations deviennent difficiles à suivre, échafauder un nouveau projet d’échantillon à des fins de comparaison.

    1. Actualisez votre fichier go.mod avec les modifications suivantes pour mettre à jour vos dépendances:

      go 1.22.0
      
      github.com/onsi/ginkgo/v2 v2.17.1
      github.com/onsi/gomega v1.32.0
      k8s.io/api v0.30.1
      k8s.io/apimachinery v0.30.1
      k8s.io/client-go v0.30.1
      sigs.k8s.io/controller-runtime v0.18.4
      Copy to Clipboard Toggle word wrap
    2. Les dépendances mises à niveau sont téléchargées en exécutant la commande suivante:

      $ go mod tidy
      Copy to Clipboard Toggle word wrap
    3. Actualisez votre Makefile avec les modifications suivantes:

      - ENVTEST_K8S_VERSION = 1.29.0
      + ENVTEST_K8S_VERSION = 1.30.0
      Copy to Clipboard Toggle word wrap
      - KUSTOMIZE ?= $(LOCALBIN)/kustomize-$(KUSTOMIZE_VERSION)
      - CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION)
      - ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION)
      - GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
      + KUSTOMIZE ?= $(LOCALBIN)/kustomize
      + CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
      + ENVTEST ?= $(LOCALBIN)/setup-envtest
      + GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
      Copy to Clipboard Toggle word wrap
      - KUSTOMIZE_VERSION ?= v5.3.0
      - CONTROLLER_TOOLS_VERSION ?= v0.14.0
      - ENVTEST_VERSION ?= release-0.17
      - GOLANGCI_LINT_VERSION ?= v1.57.2
      + KUSTOMIZE_VERSION ?= v5.4.2
      + CONTROLLER_TOOLS_VERSION ?= v0.15.0
      + ENVTEST_VERSION ?= release-0.18
      + GOLANGCI_LINT_VERSION ?= v1.59.1
      Copy to Clipboard Toggle word wrap
      - $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,${GOLANGCI_LINT_VERSION})
      + $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))
      Copy to Clipboard Toggle word wrap
      - $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,${GOLANGCI_LINT_VERSION})
      + $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))
      Copy to Clipboard Toggle word wrap
      - @[ -f $(1) ] || { \
      + @[ -f "$(1)-$(3)" ] || { \
        echo "Downloading $${package}" ;\
      + rm -f $(1) || true ;\
      - mv "$$(echo "$(1)" | sed "s/-$(3)$$//")" $(1) ;\
      - }
      + mv $(1) $(1)-$(3) ;\
      + } ;\
      + ln -sf $(1)-$(3) $(1)
      Copy to Clipboard Toggle word wrap
    4. Actualisez votre fichier .golangci.yml avec les modifications suivantes:

      -  exportloopref
      +     - ginkgolinter
            - prealloc
      +     - revive
      +
      + linters-settings:
      +   revive:
      +     rules:
      +       - name: comment-spacings
      Copy to Clipboard Toggle word wrap
    5. Actualisez votre Dockerfile avec les modifications suivantes:

      - FROM golang:1.21 AS builder
      + FROM golang:1.22 AS builder
      Copy to Clipboard Toggle word wrap
    6. Actualisez votre fichier main.go avec les modifications suivantes:

           "sigs.k8s.io/controller-runtime/pkg/log/zap"
      +    "sigs.k8s.io/controller-runtime/pkg/metrics/filters"
      
           var enableHTTP2 bool
      -    flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
      +    var tlsOpts []func(*tls.Config)
      +    flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
      +        "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
           flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
           flag.BoolVar(&enableLeaderElection, "leader-elect", false,
               "Enable leader election for controller manager. "+
                   "Enabling this will ensure there is only one active controller manager.")
      -    flag.BoolVar(&secureMetrics, "metrics-secure", false,
      -        "If set the metrics endpoint is served securely")
      +    flag.BoolVar(&secureMetrics, "metrics-secure", true,
      +        "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
      
      -    tlsOpts := []func(*tls.Config){}
      
      +    // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
      +    // More info:
      +    // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.18.4/pkg/metrics/server
      +    // - https://book.kubebuilder.io/reference/metrics.html
      +    metricsServerOptions := metricsserver.Options{
      +        BindAddress:   metricsAddr,
      +        SecureServing: secureMetrics,
      +        // TODO(user): TLSOpts is used to allow configuring the TLS config used for the server. If certificates are
      +        // not provided, self-signed certificates will be generated by default. This option is not recommended for
      +        // production environments as self-signed certificates do not offer the same level of trust and security
      +        // as certificates issued by a trusted Certificate Authority (CA). The primary risk is potentially allowing
      +        // unauthorized access to sensitive metrics data. Consider replacing with CertDir, CertName, and KeyName
      +        // to provide certificates, ensuring the server communicates using trusted and secure certificates.
      +        TLSOpts: tlsOpts,
      +    }
      +
      +    if secureMetrics {
      +        // FilterProvider is used to protect the metrics endpoint with authn/authz.
      +        // These configurations ensure that only authorized users and service accounts
      +        // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
      +        // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.18.4/pkg/metrics/filters#WithAuthenticationAndAuthorization
      +        metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
      +    }
      +
           mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
      -        Scheme: scheme,
      -        Metrics: metricsserver.Options{
      -            BindAddress:   metricsAddr,
      -            SecureServing: secureMetrics,
      -            TLSOpts:       tlsOpts,
      -        },
      +        Scheme:                 scheme,
      +        Metrics:                metricsServerOptions,
      Copy to Clipboard Toggle word wrap
    7. Actualisez votre fichier config/default/kustomization.yaml avec les modifications suivantes:

        # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
        #- ../prometheus
      + # [METRICS] Expose the controller manager metrics service.
      + - metrics_service.yaml
      
      + # Uncomment the patches line if you enable Metrics, and/or are using webhooks and cert-manager
        patches:
      - # Protect the /metrics endpoint by putting it behind auth.
      - # If you want your controller-manager to expose the /metrics
      - # endpoint w/o any authn/z, please comment the following line.
      - - path: manager_auth_proxy_patch.yaml
      + # [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443.
      + # More info: https://book.kubebuilder.io/reference/metrics
      + - path: manager_metrics_patch.yaml
      +   target:
      +     kind: Deployment
      Copy to Clipboard Toggle word wrap
    8. Enlevez les fichiers config/default/manager_auth_proxy_patch.yaml et config/default/manager_config_patch.yaml.
    9. Créez un fichier config/default/manager_metrics_patch.yaml avec le contenu suivant:

      # This patch adds the args to allow exposing the metrics endpoint using HTTPS
      - op: add
        path: /spec/template/spec/containers/0/args/0
        value: --metrics-bind-address=:8443
      Copy to Clipboard Toggle word wrap
    10. Créez un fichier config/default/metrics_service.yaml avec le contenu suivant:

      apiVersion: v1
      kind: Service
      metadata:
        labels:
          control-plane: controller-manager
          app.kubernetes.io/name: <operator-name>
          app.kubernetes.io/managed-by: kustomize
        name: controller-manager-metrics-service
        namespace: system
      spec:
        ports:
          - name: https
            port: 8443
            protocol: TCP
            targetPort: 8443
        selector:
          control-plane: controller-manager
      Copy to Clipboard Toggle word wrap
    11. Actualisez votre fichier config/manager/manager.yaml avec les modifications suivantes:

        - --leader-elect
      + - --health-probe-bind-address=:8081
      Copy to Clipboard Toggle word wrap
    12. Actualisez votre fichier config/prometheus/monitor.yaml avec les modifications suivantes:

           - path: /metrics
      -      port: https
      +      port: https # Ensure this is the name of the port that exposes HTTPS metrics
             tlsConfig:
      +        # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables
      +        # certificate verification. This poses a significant security risk by making the system vulnerable to
      +        # man-in-the-middle attacks, where an attacker could intercept and manipulate the communication between
      +        # Prometheus and the monitored services. This could lead to unauthorized access to sensitive metrics data,
      +        # compromising the integrity and confidentiality of the information.
      +        # Please use the following options for secure configurations:
      +        # caFile: /etc/metrics-certs/ca.crt
      +        # certFile: /etc/metrics-certs/tls.crt
      +        # keyFile: /etc/metrics-certs/tls.key
               insecureSkipVerify: true
      Copy to Clipboard Toggle word wrap
    13. Supprimez les fichiers suivants du répertoire config/rbac/:

      • auth_proxy_client_clusterrole.yaml
      • auth_proxy_role.yaml
      • auth_proxy_role_binding.yaml
      • auth_proxy_service.yaml
    14. Actualisez votre fichier config/rbac/kustomization.yaml avec les modifications suivantes:

        - leader_election_role_binding.yaml
      - # Comment the following 4 lines if you want to disable
      - # the auth proxy (https://github.com/brancz/kube-rbac-proxy)
      - # which protects your /metrics endpoint.
      - - auth_proxy_service.yaml
      - - auth_proxy_role.yaml
      - - auth_proxy_role_binding.yaml
      - - auth_proxy_client_clusterrole.yaml
      + # The following RBAC configurations are used to protect
      + # the metrics endpoint with authn/authz. These configurations
      + # ensure that only authorized users and service accounts
      + # can access the metrics endpoint. Comment the following
      + # permissions if you want to disable this protection.
      + # More info: https://book.kubebuilder.io/reference/metrics.html
      + - metrics_auth_role.yaml
      + - metrics_auth_role_binding.yaml
      + - metrics_reader_role.yaml
      Copy to Clipboard Toggle word wrap
    15. Créez un fichier config/rbac/metrics_auth_role_binding.yaml avec le contenu suivant:

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: metrics-auth-rolebinding
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: metrics-auth-role
      subjects:
        - kind: ServiceAccount
          name: controller-manager
          namespace: system
      Copy to Clipboard Toggle word wrap
    16. Créez un fichier config/rbac/metrics_reader_role.yaml avec le contenu suivant:

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: metrics-reader
      rules:
      - nonResourceURLs:
        - "/metrics"
        verbs:
        - get
      Copy to Clipboard Toggle word wrap
Retour au début
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. Découvrez nos récentes mises à jour.

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 le Blog 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.

Theme

© 2025 Red Hat