5.4. Opérateurs basés sur Ansible


5.4.1. Démarrer avec Operator SDK pour les opérateurs basés sur Ansible

Le SDK Operator comprend des options permettant de générer un projet Operator qui exploite les playbooks et modules Ansible existants pour déployer des ressources Kubernetes en tant qu'application unifiée, sans avoir à écrire de code Go.

Pour démontrer les bases de la configuration et de l'exécution d'un opérateur basé sur Ansible à 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 Ansible pour Memcached, un magasin de valeurs clés distribué, et le déployer sur un cluster.

5.4.1.1. Conditions préalables

  • Operator SDK CLI installé
  • OpenShift CLI (oc) v4.12 installé
  • Ansible v2.9.0
  • Ansible Runner v2.0.2
  • Ansible Runner HTTP Event Emitter plugin v1.0.0
  • Python 3.8.6
  • Client OpenShift Python v0.12.0
  • 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.4.1.2. Créer et déployer des opérateurs basés sur Ansible

Vous pouvez construire et déployer un simple opérateur Ansible pour Memcached en utilisant le SDK de l'opérateur.

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 avec le plugin ansible pour initialiser le projet :

      $ operator-sdk init \
          --plugins=ansible \
          --domain=example.com
  2. Create an API.

    Créer une API Memcached simple :

    $ operator-sdk create api \
        --group cache \
        --version v1 \
        --kind Memcached \
        --generate-role 1
    1
    Génère un rôle Ansible pour l'API.
  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

      Exemple de sortie

      ...
      I0205 17:48:45.881666       7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator
      {"level":"info","ts":1612547325.8819902,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
      {"level":"info","ts":1612547325.98242,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
      {"level":"info","ts":1612547325.9824686,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":4}
      {"level":"info","ts":1612547348.8311093,"logger":"runner","msg":"Ansible-runner exited successfully","job":"4037200794235010051","name":"memcached-sample","namespace":"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.4.1.3. Prochaines étapes

5.4.2. Tutoriel sur le SDK pour les opérateurs basés sur Ansible

Les développeurs d'opérateurs peuvent profiter de la prise en charge d'Ansible dans le SDK Operator pour construire un exemple d'opérateur basé sur Ansible pour Memcached, un magasin de valeurs clés distribué, et gérer son cycle de vie. Ce tutoriel décrit le processus suivant :

  • Créer un déploiement Memcached
  • Veillez à ce que la taille du déploiement soit la même que celle spécifiée par la spécification de ressource personnalisée (CR) de Memcached
  • Mettre à jour le statut du CR Memcached en utilisant le rédacteur de statut avec les noms des pods memcached

Ce processus est réalisé en utilisant 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.4.2.1. Conditions préalables

  • Operator SDK CLI installé
  • OpenShift CLI (oc) v4.12 installé
  • Ansible v2.9.0
  • Ansible Runner v2.0.2
  • Ansible Runner HTTP Event Emitter plugin v1.0.0
  • Python 3.8.6
  • Client OpenShift Python v0.12.0
  • 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.4.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. Exécutez la commande operator-sdk init avec le plugin ansible pour initialiser le projet :

    $ operator-sdk init \
        --plugins=ansible \
        --domain=example.com
5.4.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 Ansible. Par exemple :

domain: example.com
layout: ansible.sdk.operatorframework.io/v1
projectName: memcached-operator
version: 3

5.4.2.3. Création d'une API

Utilisez le SDK CLI de l'opérateur pour créer une API Memcached.

Procédure

  • 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 \
        --generate-role 1
    1
    Génère un rôle Ansible pour l'API.

Après avoir créé l'API, votre projet Operator est mis à jour avec la structure suivante :

Memcached CRD
Inclut un exemple de ressource Memcached
Gestionnaire

Programme qui réconcilie l'état de la grappe avec l'état désiré en utilisant :

  • Un réconciliateur, soit un rôle Ansible, soit un playbook
  • Un fichier watches.yaml, qui connecte la ressource Memcached au rôle Ansible memcached

5.4.2.4. Modifier le gestionnaire

Mettez à jour votre projet Operator pour fournir la logique de rapprochement, sous la forme d'un rôle Ansible, qui s'exécute chaque fois qu'une ressource Memcached est créée, mise à jour ou supprimée.

Procédure

  1. Mettez à jour le fichier roles/memcached/tasks/main.yml avec la structure suivante :

    ---
    - name: start memcached
      community.kubernetes.k8s:
        definition:
          kind: Deployment
          apiVersion: apps/v1
          metadata:
            name: '{{ ansible_operator_meta.name }}-memcached'
            namespace: '{{ ansible_operator_meta.namespace }}'
          spec:
            replicas: "{{size}}"
            selector:
              matchLabels:
                app: memcached
            template:
              metadata:
                labels:
                  app: memcached
              spec:
                containers:
                - name: memcached
                  command:
                  - memcached
                  - -m=64
                  - -o
                  - modern
                  - -v
                  image: "docker.io/memcached:1.4.36-alpine"
                  ports:
                    - containerPort: 11211

    Ce rôle memcached garantit l'existence d'un déploiement memcached et définit la taille du déploiement.

  2. Définissez des valeurs par défaut pour les variables utilisées dans votre rôle Ansible en modifiant le fichier roles/memcached/defaults/main.yml:

    ---
    # defaults file for Memcached
    size: 1
  3. Mettez à jour l'exemple de ressource Memcached dans le fichier config/samples/cache_v1_memcached.yaml avec la structure suivante :

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    spec:
      size: 3

    Les paires clé-valeur de la spécification des ressources personnalisées (CR) sont transmises à Ansible en tant que variables supplémentaires.

Note

Les noms de toutes les variables dans le champ spec sont convertis en snake case, c'est-à-dire en minuscules avec un trait de soulignement, par l'opérateur avant d'exécuter Ansible. Par exemple, serviceAccount dans la spécification devient service_account dans Ansible.

Vous pouvez désactiver cette conversion en définissant l'option snakeCaseParameters sur false dans votre fichier watches.yaml. Il est recommandé d'effectuer une validation de type dans Ansible sur les variables afin de s'assurer que votre application reçoit les données attendues.

5.4.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. Ajoutez les variables d'environnement au déploiement en mettant à jour le fichier roles/memcached/tasks/main.yml avec ce qui suit :

    ...
    env:
       - name: HTTP_PROXY
         value: '{{ lookup("env", "HTTP_PROXY") | default("", True) }}'
       - name: http_proxy
         value: '{{ lookup("env", "HTTP_PROXY") | default("", True) }}'
    ...
  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.4.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.
5.4.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

    ...
    {"level":"info","ts":1612589622.7888272,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612589622.7897573,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    {"level":"info","ts":1612589622.789971,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    {"level":"info","ts":1612589622.7899997,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612589622.8904517,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612589622.8905244,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}

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

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.4.2.6.3. Regroupement d'un opérateur et déploiement avec Operator Lifecycle Manager
5.4.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

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

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.4.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.4.2.8. Ressources supplémentaires

5.4.3. Présentation du projet pour les opérateurs basés sur Ansible

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

5.4.3.1. Mise en place d'un projet basé sur Ansible

Les projets Operator basés sur Ansible générés à l'aide de la commande operator-sdk init --plugins ansible contiennent les répertoires et fichiers suivants :

Fichier ou répertoireObjectif

Dockerfile

Fichier Docker pour construire l'image du conteneur pour l'opérateur.

Makefile

Cibles pour la construction, la publication et le déploiement de l'image du conteneur qui contient le binaire de l'opérateur, et cibles pour l'installation et la désinstallation de la définition des ressources personnalisées (CRD).

PROJECT

Fichier YAML contenant des informations sur les métadonnées de l'opérateur.

config/crd

Fichiers CRD de base et paramètres du fichier kustomization.yaml.

config/default

Rassemble tous les manifestes d'opérateurs pour le déploiement. Utilisé par la commande make deploy.

config/manager

Déploiement du gestionnaire de contrôleur.

config/prometheus

ServiceMonitor pour le suivi de l'opérateur.

config/rbac

Rôle et liaison de rôle pour l'élection du leader et le proxy d'authentification.

config/samples

Exemple de ressources créées pour les CRD.

config/testing

Exemples de configurations à tester.

playbooks/

Un sous-répertoire pour les playbooks à exécuter.

roles/

Sous-répertoire dans lequel l'arbre des rôles doit être exécuté.

watches.yaml

Groupe/version/genre (GVK) des ressources à surveiller, et la méthode d'invocation Ansible. Les nouvelles entrées sont ajoutées à l'aide de la commande create api.

requirements.yml

Fichier YAML contenant les collections Ansible et les dépendances de rôle à installer lors d'une compilation.

molecule/

Scénarios moléculaires pour tester de bout en bout votre rôle et votre opérateur.

5.4.4. Mise à jour des projets pour les nouvelles versions du SDK de l'opérateur

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.4.4.1. Mise à jour des projets Operator basés sur Ansible pour Operator SDK 1.25.4

La procédure suivante met à jour un projet d'opérateur existant basé sur Ansible 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. Pour permettre la prise en charge des architectures arm64 dans votre projet Operator, apportez les modifications suivantes à votre projet Makefile:

      Ancienne Makefile

      OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
      ARCH := $(shell uname -m | sed 's/x86_64/amd64/')

      Nouveau Makefile

      OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
      ARCH := $(shell uname -m | sed 's/x86_64/amd64/' |  sed 's/aarch64/arm64/')

    3. Mettez à jour la version de Kustomize à v4.5.5 comme indiqué dans l'exemple suivant :

      Ancienne Makefile

      .PHONY: kustomize
      KUSTOMIZE = $(shell pwd)/bin/kustomize
      kustomize: ## Download kustomize locally if necessary.
      ifeq (,$(wildcard $(KUSTOMIZE)))
      ifeq (,$(shell which kustomize 2>/dev/null))
      	@{ \
      	set -e ;\
      	mkdir -p $(dir $(KUSTOMIZE)) ;\
      	curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.8.7/kustomize_v3.8.7_$(OS)_$(ARCH).tar.gz | \
      	tar xzf - -C bin/ ;\
      	}
      else

      Nouveau Makefile

      .PHONY: kustomize
      KUSTOMIZE = $(shell pwd)/bin/kustomize
      kustomize: ## Download kustomize locally if necessary.
      ifeq (,$(wildcard $(KUSTOMIZE)))
      ifeq (,$(shell which kustomize 2>/dev/null))
      	@{ \
      	set -e ;\
      	mkdir -p $(dir $(KUSTOMIZE)) ;\
      	curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v4.5.5/kustomize_v4.5.5_$(OS)_$(ARCH).tar.gz | \ 1
      	tar xzf - -C bin/ ;\
      	}
      else

      1
      Mise à jour de la version v3.8.7 vers v4.5.5.
      Important

      La version de Kustomize 4.0.0 a supprimé le plugin go-getter et a introduit des changements qui ne sont pas compatibles avec les versions antérieures. Les projets d'opérateurs qui s'appuient sur des versions antérieures de Kustomize pourraient ne pas fonctionner avec les nouvelles versions.

    4. Pour appliquer les changements à votre Makefile et reconstruire votre Opérateur, entrez la commande suivante :

      $ make
  3. Mettez à jour votre fichier config/default/kustomizations.yaml comme indiqué dans les exemples suivants :

    Exemple de fichier kustomizations.yaml

    # Adds namespace to all resources.
    namespace: memcached-operator-system
    # Value of this field is prepended to the
    # names of all resources, e.g. a deployment named
    # "wordpress" becomes "alices-wordpress".
    # Note that it should also match with the prefix (text before '-') of the namespace
    # field above.
    namePrefix: memcached-operator-
    
    # Labels to add to all resources and selectors.
    #labels: 1
    #- includeSelectors: true 2
    #  pairs:
    #    someName: someValue
    
    resources: 3
    - ../crd
    - ../rbac
    - ../manager

    1
    Remplacer le champ commonLabels par le champ labels.
    2
    Ajouter includeSelectors: true.
    3
    Remplacer le champ bases par le champ resources.
  4. Mettez à jour votre fichier molecule/default/kustomize.yml en y apportant les modifications suivantes :

    Exemple de fichier molecule/default/kustomize.yml

    ---
    - name: Build kustomize testing overlay
      # load_restrictor must be set to none so we can load patch files from the default overlay
      command: '{{ kustomize }} build --load-restrictor LoadRestrictionsNone' 1
      args:
        chdir: '{{ config_dir }}/testing'
      register: resources
      changed_when: false

    1
    Remplacer --load_restrictor none . par --load-restrictor LoadRestrictionNone.

5.4.4.2. Ressources supplémentaires

5.4.5. Prise en charge d'Ansible dans Operator SDK

5.4.5.1. Fichiers de ressources personnalisés

Les opérateurs utilisent le mécanisme d'extension de Kubernetes, les définitions de ressources personnalisées (CRD), de sorte que votre ressource personnalisée (CR) ressemble et agit comme les objets Kubernetes natifs intégrés.

Le format de fichier CR est un fichier de ressources Kubernetes. L'objet comporte des champs obligatoires et facultatifs :

Tableau 5.1. Champs de ressources personnalisés
FieldDescription

apiVersion

Version du CR à créer.

kind

Il s'agit en quelque sorte de la CR à créer.

metadata

Métadonnées spécifiques à Kubernetes à créer.

spec (facultatif)

Liste clé-valeur des variables qui sont transmises à Ansible. Ce champ est vide par défaut.

status

Résume l'état actuel de l'objet. Pour les opérateurs basés sur Ansible, la sous-ressourcestatus est activée pour les CRD et gérée par le module Ansible operator_sdk.util.k8s_status par défaut, qui inclut les informations condition dans le CR status.

annotations

Annotations spécifiques à Kubernetes à ajouter au CR.

La liste suivante d'annotations CR modifie le comportement de l'opérateur :

Tableau 5.2. Annotations d'opérateurs basées sur Ansible
AnnotationDescription

ansible.operator-sdk/reconcile-period

Spécifie l'intervalle de réconciliation pour le CR. Cette valeur est analysée à l'aide du paquet Golang standard time. Spécifiquement, ParseDuration est utilisé, ce qui applique le suffixe par défaut de s, donnant la valeur en secondes.

Exemple d'annotation d'opérateur basée sur Ansible

apiVersion: "test1.example.com/v1alpha1"
kind: "Test1"
metadata:
  name: "example"
annotations:
  ansible.operator-sdk/reconcile-period: "30s"

5.4.5.2. fichier watches.yaml

Un group/version/kind (GVK) est un identifiant unique pour une API Kubernetes. Le fichier watches.yaml contient une liste de correspondances entre des ressources personnalisées (CR), identifiées par leur GVK, et un rôle ou un playbook Ansible. L'opérateur attend ce fichier de mappage dans un emplacement prédéfini à l'adresse /opt/ansible/watches.yaml.

Tableau 5.3. watches.yaml mappages de fichiers
FieldDescription

group

Groupe de CR à suivre.

version

Version de la CR à regarder.

kind

Une sorte de CR à regarder

role (par défaut)

Chemin d'accès au rôle Ansible ajouté au conteneur. Par exemple, si votre répertoire roles se trouve à l'adresse /opt/ansible/roles/ et que votre rôle s'appelle busybox, cette valeur sera /opt/ansible/roles/busybox. Ce champ s'exclut mutuellement avec le champ playbook.

playbook

Chemin d'accès au playbook Ansible ajouté au conteneur. Ce playbook est censé être un moyen d'appeler des rôles. Ce champ s'exclut mutuellement avec le champ role.

reconcilePeriod (facultatif)

L'intervalle de réconciliation, c'est-à-dire la fréquence à laquelle le rôle ou le livre de jeu est exécuté, pour un CR donné.

manageStatus (facultatif)

Lorsque la valeur est true (valeur par défaut), l'opérateur gère l'état du CR de manière générique. Lorsqu'il vaut false, l'état du RC est géré ailleurs, par le rôle ou le cahier de jeu spécifié ou dans un contrôleur distinct.

Exemple de fichier watches.yaml

- version: v1alpha1 1
  group: test1.example.com
  kind: Test1
  role: /opt/ansible/roles/Test1

- version: v1alpha1 2
  group: test2.example.com
  kind: Test2
  playbook: /opt/ansible/playbook.yml

- version: v1alpha1 3
  group: test3.example.com
  kind: Test3
  playbook: /opt/ansible/test3.yml
  reconcilePeriod: 0
  manageStatus: false

1
Exemple simple de correspondance entre Test1 et le rôle test1.
2
Exemple simple de mappage de Test2 à un playbook.
3
Exemple plus complexe pour le type Test3. Désactive la remise en file d'attente et la gestion de l'état CR dans le playbook.
5.4.5.2.1. Options avancées

Les fonctions avancées peuvent être activées en les ajoutant à votre fichier watches.yaml par GVK. Elles peuvent être placées sous les champs group, version, kind et playbook ou role.

Certaines caractéristiques peuvent être modifiées par ressource à l'aide d'une annotation sur le CR. Les options qui peuvent être remplacées ont l'annotation spécifiée ci-dessous.

Tableau 5.4. Options avancées du fichier watches.yaml
FonctionnalitéClé YAMLDescriptionAnnotation pour l'annulationValeur par défaut

Période de réconciliation

reconcilePeriod

Délai entre deux rapprochements pour un CR donné.

ansible.operator-sdk/reconcile-period

1m

Gérer le statut

manageStatus

Permet à l'opérateur de gérer la section conditions de chaque section CR status.

 

true

Surveiller les ressources dépendantes

watchDependentResources

Permet à l'opérateur de surveiller dynamiquement les ressources créées par Ansible.

 

true

Surveiller les ressources gérées par les clusters

watchClusterScopedResources

Permet à l'opérateur de surveiller les ressources de type cluster qui sont créées par Ansible.

 

false

Artéfacts de coureur maximum

maxRunnerArtifacts

Gère le nombre de répertoires d'artefacts qu'Ansible Runner conserve dans le conteneur Operator pour chaque ressource individuelle.

ansible.operator-sdk/max-runner-artifacts

20

Exemple de fichier watches.yml avec des options avancées

- version: v1alpha1
  group: app.example.com
  kind: AppService
  playbook: /opt/ansible/playbook.yml
  maxRunnerArtifacts: 30
  reconcilePeriod: 5s
  manageStatus: False
  watchDependentResources: False

5.4.5.3. Variables supplémentaires envoyées à Ansible

Des variables supplémentaires peuvent être envoyées à Ansible, qui sont ensuite gérées par l'opérateur. La section spec de la ressource personnalisée (CR) transmet les paires clé-valeur en tant que variables supplémentaires. Cela équivaut à des variables supplémentaires transmises à la commande ansible-playbook.

L'opérateur transmet également des variables supplémentaires dans le champ meta pour le nom du CR et l'espace de noms du CR.

Pour l'exemple de CR suivant :

apiVersion: "app.example.com/v1alpha1"
kind: "Database"
metadata:
  name: "example"
spec:
  message: "Hello world 2"
  newParameter: "newParam"

La structure transmise à Ansible en tant que variables supplémentaires est la suivante :

{ "meta": {
        "name": "<cr_name>",
        "namespace": "<cr_namespace>",
  },
  "message": "Hello world 2",
  "new_parameter": "newParam",
  "_app_example_com_database": {
     <full_crd>
   },
}

Les champs message et newParameter sont définis au niveau supérieur en tant que variables supplémentaires, et meta fournit les métadonnées pertinentes pour le CR, telles que définies dans l'opérateur. Les champs meta sont accessibles en utilisant la notation par points dans Ansible, par exemple :

---
- debug:
    msg: "name: {{ ansible_operator_meta.name }}, {{ ansible_operator_meta.namespace }}"

5.4.5.4. Répertoire Ansible Runner

Ansible Runner conserve des informations sur les exécutions d'Ansible dans le conteneur. Il se trouve à l'adresse /tmp/ansible-operator/runner/<group>/<version>/<kind>/<namespace>/<name>.

Ressources supplémentaires

5.4.6. Collection Kubernetes pour Ansible

Pour gérer le cycle de vie de votre application sur Kubernetes à l'aide d'Ansible, vous pouvez utiliser la collection Kubernetes pour Ansible. Cette collection de modules Ansible permet à un développeur d'exploiter ses fichiers de ressources Kubernetes existants écrits en YAML ou d'exprimer la gestion du cycle de vie dans Ansible natif.

L'un des plus grands avantages de l'utilisation d'Ansible en conjonction avec les fichiers de ressources Kubernetes existants est la possibilité d'utiliser Jinja templating afin que vous puissiez personnaliser les ressources avec la simplicité de quelques variables dans Ansible.

Cette section détaille l'utilisation de la collection Kubernetes. Pour commencer, installez la collection sur votre poste de travail local et testez-la à l'aide d'un playbook avant de passer à son utilisation au sein d'un Operator.

5.4.6.1. Installation de la collection Kubernetes pour Ansible

Vous pouvez installer la Kubernetes Collection for Ansible sur votre poste de travail local.

Procédure

  1. Installer Ansible 2.9 :

    $ sudo dnf install ansible
  2. Installez le paquetage client OpenShift python:

    $ pip3 install openshift
  3. Installez la collection Kubernetes en utilisant l'une des méthodes suivantes :

    • Vous pouvez installer la collection directement depuis Ansible Galaxy :

      $ ansible-galaxy collection install community.kubernetes
    • Si vous avez déjà initialisé votre Opérateur, il se peut que vous ayez un fichier requirements.yml au niveau supérieur de votre projet. Ce fichier spécifie les dépendances Ansible qui doivent être installées pour que votre opérateur fonctionne. Par défaut, ce fichier installe la collection community.kubernetes ainsi que la collection operator_sdk.util, qui fournit des modules et des plugins pour les fonctions spécifiques à l'opérateur.

      Pour installer les modules dépendants du fichier requirements.yml:

      $ ansible-galaxy collection install -r requirements.yml

5.4.6.2. Tester la collection Kubernetes localement

Les développeurs de l'opérateur peuvent exécuter le code Ansible à partir de leur machine locale, au lieu d'exécuter et de reconstruire l'opérateur à chaque fois.

Conditions préalables

  • Initialiser un projet Operator basé sur Ansible et créer une API qui a un rôle Ansible généré en utilisant le SDK Operator
  • Installer la collection Kubernetes pour Ansible

Procédure

  1. Dans le répertoire de votre projet Operator basé sur Ansible, modifiez le fichier roles/<kind>/tasks/main.yml avec la logique Ansible que vous souhaitez. Le répertoire roles/<kind>/ est créé lorsque vous utilisez l'indicateur --generate-role lors de la création d'une API. Le remplaçable <kind> correspond au type que vous avez spécifié pour l'API.

    L'exemple suivant crée et supprime une carte de configuration en fonction de la valeur d'une variable nommée state:

    ---
    - name: set ConfigMap example-config to {{ state }}
      community.kubernetes.k8s:
        api_version: v1
        kind: ConfigMap
        name: example-config
        namespace: default 1
        state: "{{ state }}"
      ignore_errors: true 2
    1
    Modifiez cette valeur si vous souhaitez que la carte de configuration soit créée dans un espace de noms différent de celui de default.
    2
    Le fait de définir ignore_errors: true permet de s'assurer que la suppression d'une carte de configuration inexistante n'échoue pas.
  2. Modifiez le fichier roles/<kind>/defaults/main.yml pour que state soit remplacé par present par défaut :

    ---
    state: present
  3. Créez un playbook Ansible en créant un fichier playbook.yml dans le niveau supérieur de votre répertoire de projet, et incluez votre rôle <kind>:

    ---
    - hosts: localhost
      roles:
        - <kind>
  4. Exécutez le manuel de jeu :

    $ ansible-playbook playbook.yml

    Exemple de sortie

    [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [localhost] ********************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************
    ok: [localhost]
    
    TASK [memcached : set ConfigMap example-config to present] ********************************************************************************
    changed: [localhost]
    
    PLAY RECAP ********************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

  5. Vérifiez que la carte de configuration a été créée :

    $ oc get configmaps

    Exemple de sortie

    NAME               DATA   AGE
    example-config     0      2m1s

  6. Exécutez à nouveau le manuel de jeu en remplaçant state par absent:

    $ ansible-playbook playbook.yml --extra-vars state=absent

    Exemple de sortie

    [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [localhost] ********************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************
    ok: [localhost]
    
    TASK [memcached : set ConfigMap example-config to absent] ********************************************************************************
    changed: [localhost]
    
    PLAY RECAP ********************************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

  7. Vérifiez que la carte de configuration a été supprimée :

    $ oc get configmaps

5.4.6.3. Prochaines étapes

5.4.7. Utiliser Ansible à l'intérieur d'un opérateur

Après vous être familiarisé avec l'utilisation locale de Kubernetes Collection pour Ansible, vous pouvez déclencher la même logique Ansible à l'intérieur d'un opérateur lorsqu'une ressource personnalisée (CR) change. Cet exemple associe un rôle Ansible à une ressource Kubernetes spécifique que l'opérateur surveille. Ce mappage est effectué dans le fichier watches.yaml.

5.4.7.1. Fichiers de ressources personnalisés

Les opérateurs utilisent le mécanisme d'extension de Kubernetes, les définitions de ressources personnalisées (CRD), de sorte que votre ressource personnalisée (CR) ressemble et agit comme les objets Kubernetes natifs intégrés.

Le format de fichier CR est un fichier de ressources Kubernetes. L'objet comporte des champs obligatoires et facultatifs :

Tableau 5.5. Champs de ressources personnalisés
FieldDescription

apiVersion

Version du CR à créer.

kind

Il s'agit en quelque sorte de la CR à créer.

metadata

Métadonnées spécifiques à Kubernetes à créer.

spec (facultatif)

Liste clé-valeur des variables qui sont transmises à Ansible. Ce champ est vide par défaut.

status

Résume l'état actuel de l'objet. Pour les opérateurs basés sur Ansible, la sous-ressourcestatus est activée pour les CRD et gérée par le module Ansible operator_sdk.util.k8s_status par défaut, qui inclut les informations condition dans le CR status.

annotations

Annotations spécifiques à Kubernetes à ajouter au CR.

La liste suivante d'annotations CR modifie le comportement de l'opérateur :

Tableau 5.6. Annotations d'opérateurs basées sur Ansible
AnnotationDescription

ansible.operator-sdk/reconcile-period

Spécifie l'intervalle de réconciliation pour le CR. Cette valeur est analysée à l'aide du paquet Golang standard time. Spécifiquement, ParseDuration est utilisé, ce qui applique le suffixe par défaut de s, donnant la valeur en secondes.

Exemple d'annotation d'opérateur basée sur Ansible

apiVersion: "test1.example.com/v1alpha1"
kind: "Test1"
metadata:
  name: "example"
annotations:
  ansible.operator-sdk/reconcile-period: "30s"

5.4.7.2. Tester localement un opérateur basé sur Ansible

Vous pouvez tester la logique à l'intérieur d'un Operator basé sur Ansible qui s'exécute localement en utilisant la commande make run à partir du répertoire de premier niveau de votre projet Operator. La cible Makefile make run exécute localement le binaire ansible-operator, qui lit le fichier watches.yaml et utilise votre fichier ~/.kube/config pour communiquer avec un cluster Kubernetes, tout comme le font les modules k8s.

Note

Vous pouvez personnaliser le chemin des rôles en définissant la variable d'environnement ANSIBLE_ROLES_PATH ou en utilisant le drapeau ansible-roles-path. Si le rôle n'est pas trouvé dans la valeur ANSIBLE_ROLES_PATH, l'opérateur le cherche dans {{current directory}}/roles.

Conditions préalables

Procédure

  1. Installez votre définition de ressource personnalisée (CRD) et les définitions de contrôle d'accès basé sur les rôles (RBAC) appropriées pour votre ressource personnalisée (CR) :

    $ make install

    Exemple de sortie

    /usr/bin/kustomize build config/crd | kubectl apply -f -
    customresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created

  2. Exécutez la commande make run:

    $ make run

    Exemple de sortie

    /home/user/memcached-operator/bin/ansible-operator run
    {"level":"info","ts":1612739145.2871568,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.10.1","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"}
    ...
    {"level":"info","ts":1612739148.347306,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"}
    {"level":"info","ts":1612739148.3488882,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2}
    {"level":"info","ts":1612739148.3490262,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false}
    {"level":"info","ts":1612739148.3490646,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612739148.350217,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    {"level":"info","ts":1612739148.3506632,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    {"level":"info","ts":1612739148.350784,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612739148.5511978,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612739148.5512562,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}

    L'opérateur surveillant désormais les événements de votre CR, la création d'un CR déclenchera l'exécution de votre rôle Ansible.

    Note

    Prenons l'exemple d'un manifeste config/samples/<gvk>.yaml CR :

    apiVersion: <group>.example.com/v1alpha1
    kind: <kind>
    metadata:
      name: "<kind>-sample"

    Comme le champ spec n'est pas défini, Ansible est invoqué sans variables supplémentaires. Le passage de variables supplémentaires d'un CR à Ansible est abordé dans une autre section. Il est important de définir des valeurs par défaut raisonnables pour l'opérateur.

  3. Créez une instance de votre CR avec la variable par défaut state fixée à present:

    $ oc apply -f config/samples/<gvk>.yaml
  4. Vérifiez que la carte de configuration example-config a été créée :

    $ oc get configmaps

    Exemple de sortie

    NAME                    STATUS    AGE
    example-config          Active    3s

  5. Modifiez votre fichier config/samples/<gvk>.yaml pour que le champ state soit remplacé par absent. Par exemple :

    apiVersion: cache.example.com/v1
    kind: Memcached
    metadata:
      name: memcached-sample
    spec:
      state: absent
  6. Appliquez les modifications :

    $ oc apply -f config/samples/<gvk>.yaml
  7. Confirmez que la carte de configuration est supprimée :

    $ oc get configmap

5.4.7.3. Test d'un opérateur basé sur Ansible sur le cluster

Après avoir testé votre logique Ansible personnalisée localement à l'intérieur d'un opérateur, vous pouvez tester l'opérateur à l'intérieur d'un pod sur un cluster OpenShift Container Platform, ce qui est préférable pour une utilisation en production.

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

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.4.7.4. Journaux Ansible

Les opérateurs basés sur Ansible fournissent des journaux sur l'exécution d'Ansible, ce qui peut être utile pour déboguer vos tâches Ansible. Les journaux peuvent également contenir des informations détaillées sur les aspects internes de l'opérateur et ses interactions avec Kubernetes.

5.4.7.4.1. Visualisation des journaux Ansible

Conditions préalables

  • Opérateur basé sur Ansible fonctionnant comme un déploiement sur un cluster

Procédure

  • Pour afficher les journaux d'un opérateur basé sur Ansible, exécutez la commande suivante :

    $ oc logs deployment/<project_name>-controller-manager \
        -c manager \1
        -n <namespace> 2
    1
    Consulter les journaux du conteneur manager.
    2
    Si vous avez utilisé la commande make deploy pour exécuter l'opérateur en tant que déploiement, utilisez l'espace de noms <project_name>-system.

    Exemple de sortie

    {"level":"info","ts":1612732105.0579333,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.10.1","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"}
    {"level":"info","ts":1612732105.0587437,"logger":"cmd","msg":"WATCH_NAMESPACE environment variable not set. Watching all namespaces.","Namespace":""}
    I0207 21:08:26.110949       7 request.go:645] Throttling request took 1.035521578s, request: GET:https://172.30.0.1:443/apis/flowcontrol.apiserver.k8s.io/v1alpha1?timeout=32s
    {"level":"info","ts":1612732107.768025,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":"127.0.0.1:8080"}
    {"level":"info","ts":1612732107.768796,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2}
    {"level":"info","ts":1612732107.7688773,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false}
    {"level":"info","ts":1612732107.7688901,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"}
    {"level":"info","ts":1612732107.770032,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"}
    I0207 21:08:27.770185       7 leaderelection.go:243] attempting to acquire leader lease  memcached-operator-system/memcached-operator...
    {"level":"info","ts":1612732107.770202,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
    I0207 21:08:27.784854       7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator
    {"level":"info","ts":1612732107.7850506,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"}
    {"level":"info","ts":1612732107.8853772,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"}
    {"level":"info","ts":1612732107.8854098,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":4}

5.4.7.4.2. L'activation de l'intégralité d'Ansible génère des logs

Vous pouvez définir la variable d'environnement ANSIBLE_DEBUG_LOGS à True pour permettre de vérifier le résultat complet d'Ansible dans les journaux, ce qui peut être utile lors du débogage.

Procédure

  • Modifiez les fichiers config/manager/manager.yaml et config/default/manager_auth_proxy_patch.yaml pour y inclure la configuration suivante :

          containers:
          - name: manager
            env:
            - name: ANSIBLE_DEBUG_LOGS
              value: "True"
5.4.7.4.3. Activation de la débogage verbose dans les journaux

Lors du développement d'un opérateur basé sur Ansible, il peut être utile d'activer un débogage supplémentaire dans les journaux.

Procédure

  • Ajoutez l'annotation ansible.sdk.operatorframework.io/verbosity à votre ressource personnalisée pour activer le niveau de verbosité que vous souhaitez. Par exemple :

    apiVersion: "cache.example.com/v1alpha1"
    kind: "Memcached"
    metadata:
      name: "example-memcached"
      annotations:
        "ansible.sdk.operatorframework.io/verbosity": "4"
    spec:
      size: 4

5.4.8. Gestion personnalisée de l'état des ressources

5.4.8.1. À propos de l'état des ressources personnalisées dans les opérateurs basés sur Ansible

Les opérateurs basés sur Ansible mettent automatiquement à jour les sous-ressources des ressources personnalisées (CR) status avec des informations génériques sur l'exécution précédente d'Ansible. Cela inclut le nombre de tâches réussies et échouées, ainsi que les messages d'erreur pertinents, comme indiqué :

status:
  conditions:
  - ansibleResult:
      changed: 3
      completion: 2018-12-03T13:45:57.13329
      failures: 1
      ok: 6
      skipped: 0
    lastTransitionTime: 2018-12-03T13:45:57Z
    message: 'Status code was -1 and not [200]: Request failed: <urlopen error [Errno
      113] No route to host>'
    reason: Failed
    status: "True"
    type: Failure
  - lastTransitionTime: 2018-12-03T13:46:13Z
    message: Running reconciliation
    reason: Running
    status: "True"
    type: Running

Les opérateurs basés sur Ansible permettent également aux auteurs d'opérateurs de fournir des valeurs d'état personnalisées avec le module Ansible k8s_status, qui est inclus dans la collectionoperator_sdk.util . Cela permet à l'auteur de mettre à jour le site status à partir d'Ansible avec n'importe quelle paire clé-valeur.

Par défaut, les opérateurs basés sur Ansible incluent toujours la sortie générique de l'exécution Ansible, comme indiqué ci-dessus. Si vous préférez que votre application not mette à jour l'état avec la sortie Ansible, vous pouvez suivre l'état manuellement à partir de votre application.

5.4.8.2. Suivi manuel du statut des ressources personnalisées

Vous pouvez utiliser la collection operator_sdk.util pour modifier votre opérateur basé sur Ansible afin de suivre manuellement l'état des ressources personnalisées (CR) à partir de votre application.

Conditions préalables

  • Projet Operator basé sur Ansible créé en utilisant le SDK Operator

Procédure

  1. Mettre à jour le fichier watches.yaml avec un champ manageStatus défini comme false:

    - version: v1
      group: api.example.com
      kind: <kind>
      role: <role>
      manageStatus: false
  2. Utilisez le module Ansible operator_sdk.util.k8s_status pour mettre à jour la sous-ressource. Par exemple, pour mettre à jour la clé test et la valeur data, operator_sdk.util peut être utilisé comme indiqué :

    - operator_sdk.util.k8s_status:
        api_version: app.example.com/v1
        kind: <kind>
        name: "{{ ansible_operator_meta.name }}"
        namespace: "{{ ansible_operator_meta.namespace }}"
        status:
          test: data
  3. Vous pouvez déclarer des collections dans le fichier meta/main.yml pour le rôle, qui est inclus pour les opérateurs basés sur Ansible :

    collections:
      - operator_sdk.util
  4. Après avoir déclaré les collections dans le méta-rôle, vous pouvez invoquer directement le module k8s_status:

    k8s_status:
      ...
      status:
        key1: value1
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.