Nous verrons comment utiliser les rôles publiés dans
Ansible Galaxy en tant qu'opérateurs qui gèrent les applications dans Kubernetes, et voyons comment créer un opérateur qui installe simplement l'application et ajuste de manière flexible son comportement en fonction de l'environnement.

Nous utiliserons
Ansible Operator et le
module k8s pour montrer comment utiliser Ansible pour créer des applications Kubernetes.
Ansible Operator fait partie du
SDK Operator et vous permet de formuler les règles de fonctionnement de l'application (comment elle doit être installée et maintenue) dans la langue des rôles et playbooks Ansible. Le module k8s, à son tour, étend la capacité de gérer des objets dans Kubernetes lors de la création de tels rôles et playbooks.
Un opérateur est créé comme ça juste comme ça.
FROM quay.io/operator-framework/ansible-operator RUN ansible-galaxy install djzager.hello_world_k8s RUN echo $'--- \n\ - version: v1alpha1\n\ group: examples.djzager.io\n\ kind: HelloWorld\n\ role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml
Touche de démarrage
Tout d'abord,
quelques mots sur
le module Ansible k8s . Il est apparu dans Ansible 2.6 et étend les possibilités de travail avec les objets Kubernetes d'Ansible, et dans toutes les distributions Kubernetes, y compris Red Hat OpenShift. Le blog Ansible avait un article
séparé sur ce module et le
client Python dynamique pour Red Hat OpenShift . À notre avis, travailler avec des objets Kubernetes via Ansible sans utiliser le module k8s est faux. Le mécanisme d'opérateur a été créé à l'origine pour exécuter des applications dans Kubernetes, et le SDK opérateur fournit des outils pour assembler, tester et conditionner les opérateurs. À son tour, Ansible Operator est nécessaire pour définir les règles de fonctionnement de l'application en langage Ansible. Le flux de travail correspondant est organisé tout simplement: d'abord, nous faisons operator-sdk new --type = Ansible pour générer les fichiers nécessaires pour l'opérateur Ansible, puis nous peignons Ansible, et enfin nous faisons operator-sdk build pour construire l'application pour travailler dans Kubernetes. Mais si nous avons déjà un rôle dans Ansible Galaxy, qui contrôle l'application dans Kubernetes, les choses deviennent encore plus faciles. Ci-dessous, nous ferons ce qui suit:
- Construisons un rôle Ansible pour gérer l'application Hello World dans Kubernetes, ce qui nous aidera à démontrer les capacités du module Ansible k8s.
- Nous publierons ce rĂ´le dans Ansible Galaxy.
Assemblons donc l'opérateur Ansible en utilisant le rôle publié dans Ansible Galaxy. Pourquoi même créer un opérateur en utilisant un rôle d'Ansible Galaxy? Il y a deux raisons:
- Afin de ne pas répéter . Si nous avons déjà programmé le rôle Ansible pour gérer l'application Hello World et l'avons publié dans Ansible Galaxy, il est logique de l'utiliser lors de la création de l'opérateur Ansible.
- En raison de la séparation des responsabilités . Nous voulons que le rôle Hello World Ansible gère l'application du même nom dans Kubernetes et que la logique opérationnelle (opérationnelle) reste à l'intérieur de l'opérateur. Dans notre exemple, la logique opérationnelle est extrêmement simple: elle appelle simplement le rôle djzager.hello_world_k8s chaque fois que vous créez ou modifiez une ressource HelloWorld personnalisée. Cependant, à l'avenir, cette séparation deviendra plus importante, par exemple, nous ajouterons la validation à l'application Hello World via le rôle Ansible, et nous mettrons en œuvre le contrôle de l'état des ressources personnalisées HelloWorld via la logique de l'opérateur.
Bonjour Kubernetes, rencontrez Ansible
De quoi avons-nous besoin
- Ansible - consultez le guide d'installation si vous n'avez pas installé Ansible.
- Client Python pour OpenShift (facultatif). Uniquement nécessaire pour le lancement local. Les instructions d'installation sont ici .
Commençons. Tout d'abord, créez un squelette de rôle en utilisant la galaxie ansible:
# I like clear names on projects. # In meta/main.yml I will make role_name: hello-world-k8s $ ansible-galaxy init ansible-role-hello-world-k8s
Immédiatement après la création d'un nouveau rôle Ansible, nous allons définir toutes les valeurs par défaut pour documenter en même temps ses paramètres de configuration valides. De plus, notre exemple Hello World n'est pas particulièrement compliqué à cet égard. Voici à quoi ressemble notre fichier defaults / main.yml:
--- # NOTE: meta.name(space) comes from CR metadata when run with Ansible Operator # deploy/crds has an example CR for reference name: "{{ meta.name | default('hello-world') }}" namespace: "{{ meta.namespace | default('hello-world') }}" image: docker.io/ansibleplaybookbundle/hello-world:latest # To uninstall from the cluster # state: absent state: present # The size of the hello-world deployment size: 1
Après avoir défini des valeurs par défaut, il est nécessaire de décider ce que le rôle fera. L'application Hello World devra faire ce qui suit:
- Obtenez des informations sur les API disponibles dans le cluster.
- Créez plusieurs modèles et assurez-vous qu'ils sont présents ou absents dans le cluster.
Par conséquent, notre fichier tâches / main.yml ressemble à ceci:
--- - name: "Get information about the cluster" set_fact: api_groups: "{{ lookup('k8s', cluster_info='api_groups') }}" - name: 'Set hello-world objects state={{ state }}' k8s: state: '{{ state }}' definition: "{{ lookup('template', item.name) | from_yaml }}" when: item.api_exists | default(True) loop: - name: deployment.yml.j2 - name: service.yml.j2 - name: route.yml.j2 api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}"
Avant de passer aux modèles, faites attention à cette ligne dans le fichier de tâches:
api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}"
En utilisant set_fact, nous obtenons une liste de toutes les API disponibles dans le cluster afin que nous puissions générer de manière sélective des modèles selon que l'API est présente - dans ce cas, route.openshift.io. Par défaut, dans le cluster Kubernetes d'OpenShift, les routes ne sont pas disponibles et nous n'en avons pas besoin, nous ne travaillons donc avec l'objet Route que lorsqu'il y a route.openshift.io dans le cluster.
Nous pouvons non seulement gérer de manière sélective les objets du cluster en fonction de la disponibilité de certaines API, mais également utiliser les modèles Jinja2 pour utiliser OpenShift DeploymentConfig dans notre modèle de déploiement si le cluster a l'API apps.openshift.io. Voici à quoi ressemble notre fichier templates / deployment.yml.j2:
--- {% if 'apps.openshift.io' in api_groups %} apiVersion: apps.openshift.io/v1 kind: DeploymentConfig {% else %} apiVersion: apps/v1 kind: Deployment {% endif %} metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: replicas: {{ size }} {% if 'apps.openshift.io' in api_groups %} selector: app: {{ name }} service: {{ name }} {% else %} selector: matchLabels: app: {{ name }} service: {{ name }} {% endif %} template: metadata: labels: app: {{ name }} service: {{ name }} spec: containers: - image: {{ image }} name: hello-world ports: - containerPort: 8080 protocol: TCP
Modèles de fichiers / service.yml.j2:
--- apiVersion: v1 kind: Service metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: ports: - name: web port: 8080 protocol: TCP targetPort: 8080 selector: app: {{ name }} service: {{ name }}
Et enfin, le fichier templates / route.yml.j2:
--- apiVersion: route.openshift.io/v1 kind: Route metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: port: targetPort: web to: kind: Service name: {{ name }}
Nous avons omis le fichier meta / main.yml, mais il se trouve
ici .
Par conséquent, nous avons le rôle Ansible de gestion de l'application Hello World dans Kubernetes et nous pouvons utiliser les API disponibles dans le cluster. En d'autres termes, le module k8s et le client dynamique simplifient l'utilisation des objets dans Kubernetes. Nous espérons qu'avec l'exemple de ce rôle, nous avons pu montrer le potentiel d'Ansible en travaillant avec Kubernetes.
Bonjour Galaxy, rencontrez Kubernetes
Ansible Galaxy a une tonne de rôles pour configurer les serveurs et gérer les applications, mais il n'y a pas tellement de rôles pour gérer les applications Kubernetes, nous ferons donc une petite contribution.
Après avoir posté notre rôle sur
GitHub , il ne restait plus que:
- Connectez-vous à Ansible Galaxy pour donner accès à nos référentiels sur GitHub.
- Importez notre rĂ´le.
VoilĂ , maintenant notre rĂ´le hello_world_k8s est accessible au public dans Ansible Galaxy,
ici .
Bonjour opérateur Ansible, Rencontrez Galaxy
Si vous étudiez attentivement notre
projet Hello World sur GitHub , vous remarquerez que nous y avons ajouté plusieurs choses qui sont nécessaires pour créer un opérateur Ansible, à savoir:
- Un fichier Watches qui mappe les ressources personnalisées Kubernetes aux rôles ou playbooks Ansible.
- Dockerfile pour construire notre opérateur.
- Déployer le répertoire avec les objets Kubernetes nécessaires pour exécuter notre opérateur.
Si vous devez en savoir plus sur la création de vos propres instructions Ansible, utilisez le
Guide de l'
utilisateur . Mais puisque nous avons promis de construire un opérateur Ansible en utilisant le rôle publié dans Ansible Galaxy, tout ce dont nous avons
vraiment besoin est un Dockerfile:
FROM quay.io/operator-framework/ansible-operator RUN ansible-galaxy install djzager.hello_world_k8s RUN echo $'--- \n\ - version: v1alpha1\n\ group: examples.djzager.io\n\ kind: HelloWorld\n\ role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml
Maintenant, nous collectons l'opérateur:
$ docker build -t hello-world-operator -f Dockerfile . Sending build context to Docker daemon 157.2 kB Step 1/3 : FROM quay.io/operator-framework/ansible-operator latest: Pulling from operator-framework/ansible-operator Digest: sha256:1156066a05fb1e1dd5d4286085518e5ce15acabfff10a8145eef8da088475db3 Status: Downloaded newer image for quay.io/water-hole/ansible-operator:latest ---> 39cc1d19649d Step 2/3 : RUN ansible-galaxy install djzager.hello_world_k8s ---> Running in 83ba8c21f233 - downloading role 'hello_world_k8s', owned by djzager - downloading role from https://github.com/djzager/ansible-role-hello-world-k8s/archive/master.tar.gz - extracting djzager.hello_world_k8s to /opt/ansible/roles/djzager.hello_world_k8s - djzager.hello_world_k8s (master) was installed successfully Removing intermediate container 83ba8c21f233 ---> 2f303b45576c Step 3/3 : RUN echo $'--- \n- version: v1alpha1\n group: examples.djzager.io\n kind: HelloWorld\n role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml ---> Running in cced495a9cb4 Removing intermediate container cced495a9cb4 ---> 5827bc3c1ca3 Successfully built 5827bc3c1ca3 Successfully tagged hello-world-operator:latest
Il est clair que pour
utiliser cet opérateur, vous avez besoin du contenu du
répertoire de
déploiement de notre projet pour créer un compte de service, un rôle et une liaison de rôle, une définition de ressource personnalisée, ainsi que pour déployer l'opérateur lui-même. Et après avoir déployé l'opérateur, vous devrez créer une ressource personnalisée pour obtenir une instance de l'application Hello World:
apiVersion: examples.djzager.io/v1alpha1 kind: HelloWorld metadata: name: example-helloworld namespace: default spec: size: 3
Étendues d'opérateur: espace de noms et cluster
Un peu plus haut, nous avons déjà suggéré d'explorer notre
répertoire de déploiement et d'y rechercher les objets Kubernetes nécessaires pour lancer l'opérateur. Trois éléments limitent la portée de l'opérateur lors de la gestion des ressources personnalisées avec l'espace de noms dans lequel l'opérateur lui-même est déployé, à savoir:
- La variable d'environnement WATCH_NAMESPACE dans le fichier operator.yaml qui indique à l'opérateur où rechercher les ressources personnalisées
- role.yaml
- liaison_rĂ´le
Cette limitation est certainement utile dans le développement des opérateurs. Mais si nous voulons que notre application soit accessible à tous les utilisateurs du cluster, nous aurons besoin de l'aide d'un administrateur. Je devrais faire ce qui suit:
- Créez ClusterRole au lieu de Role.
- Créez une instruction ServiceAccount dans l'espace de noms où l'instruction sera déployée.
- Créez un ClusterRoleBinding qui associera un ServiceAccount d'un espace de noms particulier à un ClusterRole.
- Développez l'instruction avec une variable d'environnement WATCH_NAMESPACE non définie (par exemple, "").
Si vous effectuez toutes ces opérations, les autres utilisateurs du cluster pourront déployer des instances de notre application Hello World. Si vous êtes intéressé par cette rubrique, nous vous recommandons d'étudier
Operator Lifecycle Manager (qui fait partie de Operator Framework).
Star trek
Nous avons montré comment créer un rôle Ansible pour contrôler une application dans Kubernetes, publier ce rôle dans Ansible Galaxy et l'utiliser dans l'opérateur Ansible. Nous vous souhaitons maintenant:
- Vous utiliserez le module Ansible k8s .
- Commencez à publier vos rôles pour gérer les applications Kubernetes sur Ansible Galaxy .
- Intéressez-vous au SDK Operator et abonnez-vous à notre newsletter Operator Framework .
Notre application Hello World est intentionnellement rendue extrĂŞmement simple, mais il y a des choses qui peuvent aider Ă la rendre encore plus fiable, et en voici quelques-unes:
- Utilisation du SDK opérateur - nous n'avons intentionnellement pas fait cela dans notre exemple pour souligner la facilité avec laquelle il est possible de passer du rôle Ansible à l'opérateur. Mais il est préférable de continuer à utiliser ce rôle avec le SDK (c'est-à -dire, operator-sdk new), de plus, vous en aurez peut-être besoin dans les étapes suivantes.
- Validation - dans notre version actuelle, l'utilisateur peut créer un CR avec la taille: abc, ce qui entraînera inévitablement une erreur au stade du déploiement. Il est donc préférable de détecter les erreurs au stade de la spécification, et non après le début du travail.
- Cycle de vie - dans des exemples plus complexes, il peut s'agir de la même mise à jour de version. Dans des scénarios comme le nôtre, où il n'y a qu'une seule version de l'application Hello World, nous pourrions déterminer si l'image d'un conteneur de travail est obsolète en la comparant aux images disponibles dans le registre de conteneurs correspondant et mettre à jour les instances en cours d'exécution si nécessaire.
- Test - Molecule est très utile lors du développement et du test des rôles Ansible.
- Operator Lifecycle Manager est une boîte à outils pour la gestion des opérateurs. L'intégration avec elle aidera à installer et à mettre à jour notre opérateur.
- Statut - nous pourrions activer la sous-ressource de statut dans notre Hello World CRD et utiliser le module k8s_status, qui fait partie de l'image de l'opérateur Ansible, pour inclure des informations de statut dans la ressource personnalisée.