Déployer un Pod Kubernetes avec Ansible ?

Déployer un Pod Kubernetes avec Ansible ?

Pour avoir une infrastructure Kubernetes déployée de manière automatisée, Ansible reste une solution sûre et adaptée. La création de ressources via des templates Jinja2, sa gestion de secrets avec Ansible Vault permettant notamment de stocker les fichiers .kubeconfig pour se connecter au cluster Kubernetes sont des fonctionnalités intéressantes dans ce cas.

Prérequis

Les modules Python kubernetes, pyyaml et jsonpatch sont requis.
Pour les installer :

pip install kubernetes pyyaml jsonpatch

La collection Ansible-Galaxy kubernetes.core est également requise. Pour l'installer :

ansible-galaxy collection install kubernetes.core

Le rôle Ansible pour Kubernetes

Voici l'arborescence du rôle Ansible avec le playbook k8s.yml :

k8s.yml
  ├── 
    roles
    ├── 
        k8s
        │   ├── defaults
        │   │   └── main.yml
        │   ├── tasks
        │   │   └── main.yml
        │   └── templates
        │       └── pod.yml.j2

Un rôle plutôt court car il s'agit uniquement du déploiement d'une seule ressource Kubernetes : un Pod à conteneur unique. Rien de plus.
Il est évidemment possible de customiser ce rôle afin d'y ajouter des éléments comme par exemple un imagePullSecrets si vous avez une registry Docker privée et bien d'autres...

Les variables

Nous allons utiliser le fichier defaults/main.yml afin de définir les variables par défaut pour notre configuration.

---
pod:
  name: NOM_DU_POD
  image: CHEMIN_DE_L'IMAGE_DOCKER
  namespace: NAMESPACE_KUBERNETES

kubeconfig: CHEMIN_VERS_KUBECONFIG

Il est possible de chiffrer le contenu du fichier .kubeconfig avec Ansible Vault. Il vous faudra ajouter l'option --ask-vault-pass afin d'entrer la clé de déchiffrement au lancement du Playbook Ansible.  

Le template Jinja2

Afin de créer notre Pod en fonction des variables que nous avons spécifié plus haut, rien de mieux qu'un template Jinja2 avec le fichier pod.yml.j2

apiVersion: v1
kind: Pod
metadata:
  name: {{ pod.name }}
  namespace: {{ pod.namespace }}
spec:
  containers:
  - name: {{ pod.name }}-container
    image: {{ pod.image }}

Un Pod tout ce qu'il y a de plus basique, n'hésitez pas à le compléter et y ajouter tout ce dont vous avez besoin.

La task

Pour finir, une task Ansible avec le fichier tasks/main.yml qui va venir créer toutes les ressources Kubernetes que nous venons de définir précédemment.

- name: Create pod from template
  kubernetes.core.k8s:
    template: pod.yml.j2
    apply: true
    kubeconfig: "{{ kubeconfig }}"
    wait: True
  delegate_to: localhost

Cette task vient effectuer l'équivalent de la commande kubectl suivante :

kubectl apply -f pod.yml

Il est nécessaire d'ajouter delegate_to: localhost afin que le node Ansible n'aille pas essayer de se connecter à un cluster Kubernetes sur l'hôte distant.

Nous verrons dans de prochains articles comment créer d'autres ressources Kubernetes avec de l'infra-as-code 😉