Aller au contenu
Tech & IA

Cloud & DevOps

GitOps expliqué : ArgoCD, l’état voulu dans Git, la dérive corrigée

Dans une approche GitOps, Git décrit l’état voulu et un contrôleur dans le cluster le fait respecter en continu. À l’échelle d’un petit cluster k3s, voici ce que cela change : déploiements, retour arrière et dérive.

6 min de lecture

Des câbles réseau bleus, verts et jaunes branchés sur un commutateur

Il y a deux façons de déployer une application sur Kubernetes. La première : quelqu’un, ou un script de CI, exécute des commandes kubectl apply ou helm upgrade vers le cluster. La seconde : on écrit dans un dépôt Git ce que le cluster doit contenir, et un programme à l’intérieur du cluster se charge de le faire correspondre. La seconde s’appelle GitOps, et elle règle plusieurs problèmes que la première cache sous le tapis.

Le principe en une phrase

Git est la source de vérité de l’état voulu ; un contrôleur compare sans cesse cet état à l’état réel du cluster et corrige l’écart. Le déploiement n’est plus une action qu’on lance, c’est un état qu’on déclare.

La communauté a formalisé quatre principes, regroupés sous le nom d’OpenGitOps :

  • Déclaratif : le système est décrit par ce qu’il doit être, pas par une suite de commandes.
  • Versionné et immuable : l’état voulu est stocké de façon à garder l’historique complet, ce que Git fait très bien.
  • Récupéré automatiquement : un agent tire les changements depuis la source, plutôt qu’un outil externe les pousse.
  • Réconcilié en continu : l’agent compare en permanence et corrige les divergences.

Pull plutôt que push

Dans un déploiement classique « en poussée », la CI possède des identifiants capables de modifier le cluster. Quiconque compromet la CI compromet le cluster, et ces identifiants vivent en dehors de lui. En GitOps, c’est l’inverse : le contrôleur, installé dans le cluster, a accès en lecture au dépôt, et c’est lui qui applique les changements. Le cluster n’a besoin d’aucune porte d’entrée ouverte pour les déploiements, et la CI n’a plus besoin d’aucun accès à lui.

ArgoCD, la pièce centrale

ArgoCD est l’un des contrôleurs GitOps les plus répandus pour Kubernetes. Il est lui-même composé de quelques services : un serveur d’API et d’interface web, un contrôleur d’applications qui compare et synchronise, un service qui lit le dépôt et génère les manifestes (le repo server), et un cache. L’unité de travail s’appelle une Application, qui décrit quatre choses :

  • la source : l’adresse du dépôt, le chemin du dossier et la révision à suivre (une branche, un tag) ;
  • le type de contenu : des manifestes bruts, un chart Helm ou une configuration Kustomize ;
  • la destination : le cluster et le namespace cibles ;
  • la politique de synchronisation : manuelle, ou automatique avec des options.

Chaque application a deux états à surveiller. Le premier est la synchronisation : Synced si l’état réel correspond à Git, OutOfSync sinon. Le second est la santé : Healthy si les ressources fonctionnent, Degraded ou Progressing sinon. Une application peut être parfaitement synchronisée et en panne, parce que Git décrit une configuration cassée. Les deux sont indépendants.

La dérive, et comment elle disparaît

La dérive est l’écart entre ce que Git décrit et ce qui tourne vraiment. Elle a une origine banale : à trois heures du matin, quelqu’un modifie un déploiement à la main avec kubectl edit pour résoudre un incident, et oublie de reporter le changement. Quelques semaines plus tard, plus personne ne sait pourquoi la production ne ressemble pas au dépôt.

Avec la synchronisation automatique, deux options traitent le problème :

  • selfHeal: true : si l’état réel s’écarte de Git, par exemple après une modification manuelle, le contrôleur le remet conforme ;
  • prune: true : une ressource retirée de Git est supprimée du cluster, au lieu de rester orpheline.

Cela change la façon de travailler. Corriger un incident passe par un commit, qui reste dans l’historique avec son auteur et sa date. Les modifications manuelles ne tiennent plus, et c’est voulu. Ce n’est pas toujours confortable le jour où l’on veut tester quelque chose en urgence, mais c’est ce qui garantit que le dépôt dit la vérité.

Si ce n’est pas dans Git, ce n’est pas la production. Si c’est dans Git, c’est ce qui doit tourner.

À l’échelle d’un petit cluster k3s

GitOps n’est pas réservé aux grandes plateformes. Sur un cluster k3s d’un seul nœud, qui héberge un site et quelques services, le schéma tient en peu de pièces :

  1. Un dépôt de configuration contient un dossier par application : un chart Helm ou des manifestes Kustomize, avec les valeurs de l’environnement.
  2. ArgoCD est installé dans son propre namespace.
  3. Une Application par service pointe vers son dossier, avec une synchronisation automatique.
  4. Pour livrer une nouvelle version, on change le tag de l’image dans le dépôt, par une pull request.

ArgoCD n’est pas gratuit en ressources : plusieurs processus tournent en permanence, et sur une petite machine cela se voit. C’est le prix de la réconciliation continue, à mettre en face de ce qu’on économise en incidents liés à un état que personne ne connaît.

Livrer une nouvelle version

Le flux habituel sépare deux dépôts, ou deux dossiers : le code de l’application, et la configuration du déploiement. La CI du code construit l’image, la publie, puis modifie le tag dans le dépôt de configuration, soit en ouvrant une pull request, soit par un outil dédié. ArgoCD voit le changement et déploie.

Deux habitudes aident beaucoup. D’abord, utiliser des tags immuables, ou mieux, le digest de l’image, pour que ce qui est déployé soit exactement ce qui a été testé. Ensuite, ne jamais utiliser le tag latest : il rend l’état voulu ambigu, ce qui est exactement ce qu’on veut éviter.

Le retour arrière, presque gratuit

Annuler un déploiement revient à annuler un commit : git revert, un merge, et le contrôleur ramène le cluster à l’état précédent. Pas de procédure spéciale à retrouver dans un wiki, pas de commande à reconstituer de mémoire sous pression. L’historique de Git est aussi l’historique des déploiements.

Les secrets, le point délicat

On ne peut pas simplement commiter un mot de passe en clair dans un dépôt de configuration. Trois approches répandues : chiffrer les secrets dans le dépôt (Sealed Secrets, SOPS), les référencer depuis un coffre externe (External Secrets Operator), ou les créer hors du flux GitOps pour ce qui est vraiment sensible. Aucune n’est gratuite, mais toutes valent mieux qu’un secret en clair dans l’historique.

Les pièges qu’on rencontre

  • Des différences permanentes sur des champs que d’autres contrôleurs modifient (un nombre de réplicas géré par un autoscaler, par exemple). On les déclare comme à ignorer dans la configuration de l’application.
  • L’ordre de création : certaines ressources doivent exister avant d’autres (une définition de ressource personnalisée avant son usage). ArgoCD propose des vagues de synchronisation pour cela.
  • Le `prune` activé trop tôt, sur un dossier mal réorganisé, qui supprime plus que prévu.
  • Un dépôt devenu fourre-tout, sans structure, où l’on ne retrouve plus ce qui appartient à quoi.

Pour commencer, une application, un dépôt, une synchronisation manuelle pendant quelques jours pour regarder les différences, puis le mode automatique. On apprend plus vite en voyant l’écart se produire qu’en lisant la documentation.

Commentaires (0)

Aucun commentaire pour le moment.