5.17. La migration vers l’opérateur SDK v0.1.0


Ce guide décrit comment migrer un projet d’opérateur construit à l’aide de l’opérateur SDK v0.0.x vers la structure du projet requise par l’opérateur SDK v0.1.0.

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 d’opérateur, est dépréciée et devrait être supprimée dans une version ultérieure d’OpenShift Dedicated. 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 des futures versions d’OpenShift Dedicated.

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 OpenShift Dedicated 4 pour maintenir leurs projets et créer des versions d’opérateur ciblant des versions plus récentes d’OpenShift Dedicated.

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

La méthode recommandée pour migrer votre projet est de:

  1. Initialisez un nouveau projet v0.1.0.
  2. Copiez votre code dans le nouveau projet.
  3. Changer le nouveau projet comme décrit pour v0.1.0.

Ce guide utilise l’opérateur memcached, le projet exemple du SDK de l’opérateur, pour illustrer les étapes de migration. Consultez les structures de projet memcached-operator v0.0.7 et v0.1.0 memcached-operator pour les exemples de pré- et post-migration, respectivement.

5.17.1. Création d’un nouveau projet Operator SDK v0.1.0

Donnez un nouveau nom à votre projet Operator SDK v0.0.x et créez un nouveau projet v0.1.0 à sa place.

Conditions préalables

  • L’opérateur SDK v0.1.0 CLI installé sur le poste de travail de développement
  • le projet Memcached-operator précédemment déployé à l’aide d’une version antérieure de l’opérateur SDK

Procédure

  1. Assurez-vous que la version SDK est v0.1.0:

    $ operator-sdk --version
    operator-sdk version 0.1.0
    Copy to Clipboard Toggle word wrap
  2. Créer un nouveau projet:

    $ mkdir -p $GOPATH/src/github.com/example-inc/
    $ cd $GOPATH/src/github.com/example-inc/
    $ mv memcached-operator old-memcached-operator
    $ operator-sdk new memcached-operator --skip-git-init
    $ ls
    memcached-operator old-memcached-operator
    Copy to Clipboard Toggle word wrap
  3. Copier .git de l’ancien projet:

    $ cp -rf old-memcached-operator/.git memcached-operator/.git
    Copy to Clipboard Toggle word wrap

Faites migrer les types personnalisés de votre projet vers l’utilisation mise à jour du SDK de l’opérateur v0.1.0.

Conditions préalables

  • L’opérateur SDK v0.1.0 CLI installé sur le poste de travail de développement
  • le projet Memcached-operator précédemment déployé à l’aide d’une version antérieure de l’opérateur SDK
  • Création d’un nouveau projet à l’aide de l’opérateur SDK v0.1.0

Procédure

  1. Créez l’API d’échafaudage pour les types personnalisés.

    1. Créez l’API pour votre ressource personnalisée (CR) dans le nouveau projet avec operator-sdk ajouter api --api-version=<apiversion> --kind=<kind>:

      $ cd memcached-operator
      $ operator-sdk add api --api-version=cache.example.com/v1alpha1 --kind=Memcached
      
      $ tree pkg/apis
      pkg/apis/
      ├── addtoscheme_cache_v1alpha1.go
      ├── apis.go
      └── cache
          └── v1alpha1
              ├── doc.go
              ├── memcached_types.go
              ├── register.go
              └── zz_generated.deepcopy.go
      Copy to Clipboard Toggle word wrap
    2. Répétez la commande précédente pour autant de types personnalisés que vous l’avez défini dans votre ancien projet. Chaque type sera défini dans le fichier pkg/apis/<group>/&lt;version&gt;/&lt;kind&gt;_types.go.
  2. Copiez le contenu du type.

    1. Copiez le contenu Spec and Status du fichier pkg/apis/<group>/&lt;version&gt;/types.go de l’ancien projet vers le fichier<group>pkg/apis/ /&lt;version&gt;/&lt;kind&gt;_types.go du nouveau projet.
    2. Chaque fichier &lt;kind&gt;_types.go a une fonction init(). Assurez-vous de ne pas supprimer cela puisque cela enregistre le type avec le schéma du gestionnaire:

      func init() {
      	SchemeBuilder.Register(&Memcached{}, &MemcachedList{})
      Copy to Clipboard Toggle word wrap

5.17.3. Code de conciliation migratoire

Faites migrer le code de rapprochement de votre projet vers l’utilisation de l’opérateur SDK v0.1.0 de mise à jour.

Conditions préalables

  • L’opérateur SDK v0.1.0 CLI installé sur le poste de travail de développement
  • le projet Memcached-operator précédemment déployé à l’aide d’une version antérieure de l’opérateur SDK
  • Les types personnalisés ont migré à partir de pkg/apis/

Procédure

  1. Ajoutez un contrôleur pour regarder votre CR.

    Dans les projets v0.0.x, les ressources à regarder étaient précédemment définies dans cmd/&lt;operator-name&gt;/main.go:

    sdk.Watch("cache.example.com/v1alpha1", "Memcached", "default", time.Duration(5)*time.Second)
    Copy to Clipboard Toggle word wrap

    Dans le cas des projets v0.1.0, vous devez définir un contrôleur pour surveiller les ressources:

    1. Ajoutez un contrôleur pour regarder votre type CR avec le contrôleur --api-version=&lt;apiversion&gt; --kind=&lt;kind&gt;.

      $ operator-sdk add controller --api-version=cache.example.com/v1alpha1 --kind=Memcached
      
      $ tree pkg/controller
      pkg/controller/
      ├── add_memcached.go
      ├── controller.go
      └── memcached
          └── memcached_controller.go
      Copy to Clipboard Toggle word wrap
    2. Inspectez la fonction add() dans votre fichier pkg/controller/&lt;kind&gt;/&lt;kind&gt;_controller.go:

      import (
          cachev1alpha1 "github.com/example-inc/memcached-operator/pkg/apis/cache/v1alpha1"
          ...
      )
      
      func add(mgr manager.Manager, r reconcile.Reconciler) error {
          c, err := controller.New("memcached-controller", mgr, controller.Options{Reconciler: r})
      
          // Watch for changes to the primary resource Memcached
          err = c.Watch(&source.Kind{Type: &cachev1alpha1.Memcached{}}, &handler.EnqueueRequestForObject{})
      
          // Watch for changes to the secondary resource pods and enqueue reconcile requests for the owner Memcached
          err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForOwner{
      		IsController: true,
      		OwnerType:    &cachev1alpha1.Memcached{},
      	})
      }
      Copy to Clipboard Toggle word wrap

      Enlevez la deuxième Watch() ou modifiez-la pour regarder un type de ressource secondaire qui appartient à votre CR.

      La visualisation de plusieurs ressources vous permet de déclencher la boucle de réconciliation pour plusieurs ressources pertinentes à votre application. Consultez la documentation de surveillance et de traitement des événements et la documentation des conventions du contrôleur Kubernetes pour plus de détails.

      Lorsque votre opérateur regarde plus d’un type CR, vous pouvez faire l’un des éléments suivants en fonction de votre demande:

      • Lorsque le CR appartient à votre CR primaire, regardez-la comme ressource secondaire dans le même contrôleur pour déclencher la boucle de réconciliation pour la ressource primaire.

        // Watch for changes to the primary resource Memcached
            err = c.Watch(&source.Kind{Type: &cachev1alpha1.Memcached{}}, &handler.EnqueueRequestForObject{})
        
            // Watch for changes to the secondary resource AppService and enqueue reconcile requests for the owner Memcached
            err = c.Watch(&source.Kind{Type: &appv1alpha1.AppService{}}, &handler.EnqueueRequestForOwner{
        		IsController: true,
        		OwnerType:    &cachev1alpha1.Memcached{},
        	})
        Copy to Clipboard Toggle word wrap
      • Ajoutez un nouveau contrôleur pour regarder et réconcilier le CR indépendamment de l’autre CR.

        $ operator-sdk add controller --api-version=app.example.com/v1alpha1 --kind=AppService
        Copy to Clipboard Toggle word wrap
          // Watch for changes to the primary resource AppService
            err = c.Watch(&source.Kind{Type: &appv1alpha1.AppService{}}, &handler.EnqueueRequestForObject{})
        Copy to Clipboard Toggle word wrap
  2. Copiez et modifiez le code de réconciliation de pkg/stub/handler.go.

    Dans un projet v0.1.0, le code de conciliation est défini dans la méthode Reconcile() du Reconciler d’un contrôleur. Ceci est similaire à la fonction Handle() dans l’ancien projet. À noter la différence dans les arguments et les valeurs de retour:

    • Concilier:

          func (r *ReconcileMemcached) Reconcile(request reconcile.Request) (reconcile.Result, error)
      Copy to Clipboard Toggle word wrap
    • La poignée:

          func (h *Handler) Handle(ctx context.Context, event sdk.Event) error
      Copy to Clipboard Toggle word wrap

    Au lieu de recevoir un événement sdk.Event (avec l’objet), la fonction Reconcile() reçoit une requête (clé Nom/Namespace) pour rechercher l’objet.

    Lorsque la fonction Reconcile() renvoie une erreur, le contrôleur requeue et réessaye la Demande. Dans le cas où aucune erreur n’est retournée, en fonction du résultat, le responsable du traitement ne réessayera pas la demande, ne sera pas immédiatement réessayer, ou réessayera après une durée spécifiée.

    1. Copiez le code de la fonction Handle() de l’ancien projet vers le code existant dans la fonction Reconcile() de votre contrôleur. Assurez-vous de conserver la section initiale dans le code Reconcile() qui recherche l’objet de la demande et vérifie si elle est supprimée.

      import (
          apierrors "k8s.io/apimachinery/pkg/api/errors"
          cachev1alpha1 "github.com/example-inc/memcached-operator/pkg/apis/cache/v1alpha1"
          ...
      )
      func (r *ReconcileMemcached) Reconcile(request reconcile.Request) (reconcile.Result, error) {
          // Fetch the Memcached instance
      	instance := &cachev1alpha1.Memcached{}
          err := r.client.Get(context.TODO()
          request.NamespacedName, instance)
          if err != nil {
              if apierrors.IsNotFound(err) {
                  // Request object not found, could have been deleted after reconcile request.
                  // Owned objects are automatically garbage collected.
                  // Return and don't requeue
                  return reconcile.Result{}, nil
              }
              // Error reading the object - requeue the request.
              return reconcile.Result{}, err
          }
      
          // Rest of your reconcile code goes here.
          ...
      }
      Copy to Clipboard Toggle word wrap
    2. Changez les valeurs de retour dans votre code de rapprochement:

      1. Il faut remplacer l’erreur de retour par le retour réconcilié.Result{}, erreur.
      2. Il faut remplacer le retour zéro par le retour réconcilié.Result{}, nil.
    3. Afin de réconcilier périodiquement un CR dans votre contrôleur, vous pouvez définir le champ Requeue After pour réconcilier.Result. Cela fera que le contrôleur requeue la demande et déclenchera le rapprochement après la durée souhaitée. A noter que la valeur par défaut de 0 signifie aucune requeue.

      reconcilePeriod := 30 * time.Second
      reconcileResult := reconcile.Result{RequeueAfter: reconcilePeriod}
      ...
      
      // Update the status
      err := r.client.Update(context.TODO(), memcached)
      if err != nil {
          log.Printf("failed to update memcached status: %v", err)
          return reconcileResult, err
      }
      return reconcileResult, nil
      Copy to Clipboard Toggle word wrap
    4. En remplacement des appels au client SDK (Créer, mettre à jour, Supprimer, obtenir, liste) par le client du conciliateur.

      Consultez les exemples ci-dessous et la documentation API du contrôleur-runtimeclient dans le projet opérateur-sdk pour plus de détails:

      // Create
      dep := &appsv1.Deployment{...}
      err := sdk.Create(dep)
      // v0.0.1
      err := r.client.Create(context.TODO(), dep)
      
      // Update
      err := sdk.Update(dep)
      // v0.0.1
      err := r.client.Update(context.TODO(), dep)
      
      // Delete
      err := sdk.Delete(dep)
      // v0.0.1
      err := r.client.Delete(context.TODO(), dep)
      
      // List
      podList := &corev1.PodList{}
      labelSelector := labels.SelectorFromSet(labelsForMemcached(memcached.Name))
      listOps := &metav1.ListOptions{LabelSelector: labelSelector}
      err := sdk.List(memcached.Namespace, podList, sdk.WithListOptions(listOps))
      // v0.1.0
      listOps := &client.ListOptions{Namespace: memcached.Namespace, LabelSelector: labelSelector}
      err := r.client.List(context.TODO(), listOps, podList)
      
      // Get
      dep := &appsv1.Deployment{APIVersion: "apps/v1", Kind: "Deployment", Name: name, Namespace: namespace}
      err := sdk.Get(dep)
      // v0.1.0
      dep := &appsv1.Deployment{}
      err = r.client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: namespace}, dep)
      Copy to Clipboard Toggle word wrap
    5. Copiez et initialisez tous les autres champs de votre structure Handler dans la structure Reconcile&lt;Kind&gt;:

      // newReconciler returns a new reconcile.Reconciler
      func newReconciler(mgr manager.Manager) reconcile.Reconciler {
      	return &ReconcileMemcached{client: mgr.GetClient(), scheme: mgr.GetScheme(), foo: "bar"}
      }
      
      // ReconcileMemcached reconciles a Memcached object
      type ReconcileMemcached struct {
          client client.Client
          scheme *runtime.Scheme
          // Other fields
          foo string
      }
      Copy to Clipboard Toggle word wrap
  3. Copiez les modifications de main.go.

    La fonction principale d’un opérateur v0.1.0 dans cmd/manager/main.go configure le gestionnaire, qui enregistre les ressources personnalisées et démarre tous les contrôleurs.

    Il n’y a pas besoin de migrer les fonctions SDK sdk.Watch(), sdk.Handle(), et sdk.Run() à partir de l’ancien main.go puisque cette logique est maintenant définie dans un contrôleur.

    Cependant, s’il existe des drapeaux ou paramètres spécifiques à l’opérateur définis dans l’ancien fichier main.go, copiez-les.

    Lorsque vous avez des types de ressources tiers enregistrés avec le système SDK, consultez les sujets avancés dans le projet opérateur-sdk pour savoir comment les enregistrer avec le schéma du gestionnaire dans le nouveau projet.

  4. Copiez des fichiers définis par l’utilisateur.

    En cas de pkg, de scripts ou de documentation défini par l’utilisateur dans l’ancien projet, copiez ces fichiers dans le nouveau projet.

  5. Copiez les modifications apportées aux manifestes de déploiement.

    Dans le cas des mises à jour apportées aux manifestes suivants dans l’ancien projet, copiez les modifications apportées à leurs fichiers correspondants dans le nouveau projet. Faites attention à ne pas écraser directement les fichiers, mais inspectez et apportez les modifications nécessaires:

    • fichier Tmp/Build/Dockerfile à construire/Dockerfile

      • Il n’y a pas de répertoire tmp dans la nouvelle disposition du projet
    • Les règles RBAC sont mises à jour depuis le déploiement/rbac.yaml pour déployer/role.yaml et déployer/role_binding.yaml
    • déployez/cr.yaml pour déployer/crds/<group>_&lt;version&gt;_&lt;kind&gt;_cr.yaml
    • déployez/crd.yaml pour déployer/crds/<group>_&lt;version&gt;_&lt;kind&gt;_crd.yaml
  6. Copiez les dépendances définies par l’utilisateur.

    Dans le cas des dépendances définies par l’utilisateur ajoutées au Gopkg.toml de l’ancien projet, copiez-les et ajoutez-les au Gopkg.toml du nouveau projet. Exécutez dep assurez-vous de mettre à jour le fournisseur dans le nouveau projet.

  7. Confirmez vos changements.

    Créez et exécutez votre opérateur pour vérifier qu’il fonctionne.

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