GitOps : Git comme état désiré (ArgoCD) & Flux : la réconciliation continue
Comprendre le paradigme GitOps où un dépôt Git devient la source unique de l'état désiré, et découvrir comment ArgoCD et Flux réconcilient en continu le cluster avec cet état — avec du YAML et kubectl.
GitOps : Git comme état désiré (ArgoCD)
L’idée en une phrase
Le GitOps élève un dépôt Git au rang de source unique de l’état désiré d’un cluster : un contrôleur embarqué compare en permanence les manifestes versionnés dans Git avec les ressources réelles du cluster, puis réconcilie tout écart — la même boucle observe → diff → agit que celle d’un controller Kubernetes, appliquée cette fois à l’ensemble de l’infrastructure déclarative.
Analogie : Considérons un architecte qui dépose les plans définitifs d’un bâtiment dans un coffre-fort notarié. Chaque matin, un maître d’œuvre compare l’avancement réel du chantier avec les plans du coffre. Si une cloison manque ou a été déplacée, il la reconstruit conformément au plan — sans attendre d’instruction supplémentaire. Le coffre-fort est le dépôt Git (immuable, auditable), le chantier est le cluster, et le maître d’œuvre est le contrôleur GitOps.
Points clés
- Le principe fondateur du GitOps repose sur quatre piliers formulés par l’OpenGitOps working group : l’infrastructure est déclarative, l’état désiré est versionné et immuable dans Git, les changements sont appliqués automatiquement par un agent, et l’agent réconcilie en continu l’état réel avec l’état désiré. Aucune modification manuelle via
kubectl applyn’est censée contourner ce flux. - ArgoCD implémente ce paradigme sous forme d’un contrôleur déployé dans le cluster. Il surveille un ou plusieurs dépôts Git (via polling ou webhook) et compare le contenu du dépôt (l’état désiré) avec les ressources effectivement présentes dans le cluster (l’état réel). L’écart est affiché dans une interface web et peut être réconcilié automatiquement ou après approbation manuelle.
- ArgoCD modélise chaque déploiement sous la forme d’une CR Application. Cette CR déclare le dépôt Git source, le chemin des manifestes, le cluster cible et la politique de synchronisation. Le contrôleur d’ArgoCD réconcilie cette CR exactement comme n’importe quel Operator réconcilie sa CR — la boucle est la même, le domaine change.
- Le statut d’une Application ArgoCD reflète l’écart entre Git et le cluster : Synced (état réel = état désiré), OutOfSync (écart détecté), Degraded (ressources en échec). Ce status est la manifestation directe du diff calculé par la boucle de réconciliation.
- La politique auto-sync avec self-heal active la réconciliation automatique : toute dérive du cluster (suppression manuelle d’un pod, modification d’un ConfigMap via
kubectl edit) est corrigée sans intervention humaine. Sans self-heal, ArgoCD se contente de signaler l’écart.
Exemple concret
Une équipe gère un microservice payment-api déployé dans un namespace production. Le Deployment, le Service et le ConfigMap sont versionnés dans un dépôt Git infra-k8s, dans le répertoire apps/payment-api/. ArgoCD surveille ce répertoire. À t₀, un opérateur modifie le ConfigMap directement dans le cluster via kubectl edit pour changer un flag de feature. ArgoCD détecte l’écart lors de son prochain cycle de réconciliation (toutes les 3 minutes par défaut). Avec self-heal activé, ArgoCD réapplique le ConfigMap tel qu’il existe dans Git — la modification manuelle est annulée. L’opérateur constate la correction et comprend que toute modification durable doit passer par un commit dans le dépôt Git. Le dépôt Git reste la source de vérité.
Comparaison — déploiement CI/CD classique vs GitOps
| Critère | CI/CD push (pipeline applique) | GitOps pull (agent réconcilie) |
|---|---|---|
| Qui applique les manifestes | Le pipeline CI/CD (externe au cluster) | Un contrôleur dans le cluster |
| Source de vérité | Le pipeline au moment de l’exécution | Le dépôt Git en permanence |
| Détection de dérive | Aucune — l’état peut diverger entre deux pipelines | Continue — l’agent compare à chaque cycle |
| Accès cluster requis | Le pipeline a besoin de credentials cluster | Seul l’agent interne a accès — surface d’attaque réduite |
| Rollback | Relancer un ancien pipeline ou écrire un script | git revert — l’agent réconcilie automatiquement |
Code YAML — déclaration d’une Application ArgoCD
# application.yaml — l'Application est une CR qui décrit l'état désiré d'un déploiement
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: payment-api
namespace: argocd # ArgoCD surveille ses CR dans ce namespace
spec:
project: default
source:
repoURL: https://github.com/acme/infra-k8s.git
targetRevision: main # la branche Git = la version de l'état désiré
path: apps/payment-api # répertoire contenant les manifestes YAML
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # supprimer les ressources absentes de Git
selfHeal: true # corriger toute dérive détectée dans le cluster
syncOptions:
- CreateNamespace=true
Code bash — observer la réconciliation ArgoCD
# Vérifier le statut de synchronisation de l'Application
kubectl get application payment-api -n argocd \
-o jsonpath='{.status.sync.status}'
# Synced
# Provoquer une dérive : modifier un ConfigMap manuellement
kubectl edit configmap payment-config -n production
# (modifier une clé et sauvegarder)
# Après le prochain cycle de réconciliation (~3 min) :
kubectl get application payment-api -n argocd \
-o jsonpath='{.status.sync.status}'
# Synced ← ArgoCD a réconcilié : la modification manuelle est annulée
# Consulter l'historique de synchronisation
kubectl get application payment-api -n argocd \
-o jsonpath='{.status.history[*].revision}'
# abc1234 def5678 ← chaque sync est liée à un commit Git
Piège courant : « GitOps remplace la CI/CD » est un raccourci trompeur. GitOps remplace la partie livraison (CD) — le déploiement des manifestes dans le cluster. La partie intégration (CI) — build de l’image, exécution des tests, publication dans un registre — reste nécessaire et pilotée par un pipeline classique. Le pipeline CI pousse une nouvelle image taguée dans le registre, met à jour la référence d’image dans le dépôt Git, et le contrôleur GitOps réconcilie le cluster avec ce nouvel état désiré.
Flux : la réconciliation continue
L’idée en une phrase
Flux implémente le GitOps comme un ensemble de contrôleurs spécialisés déployés dans le cluster — chacun réconciliant un aspect précis (sources Git, dépôts Helm, manifestes Kustomize) — incarnant le principe Kubernetes de composition de boucles de réconciliation indépendantes plutôt qu’un contrôleur monolithique.
Analogie : Considérons une chaîne logistique où chaque entrepôt régional dispose de son propre gestionnaire de stock. Le gestionnaire de Bordeaux surveille les niveaux de son entrepôt et passe des commandes au fournisseur pour maintenir le stock cible. Celui de Lyon fait de même, indépendamment. Un coordinateur central publie le catalogue et les niveaux cibles, mais chaque gestionnaire réconcilie localement. Flux fonctionne ainsi : chaque contrôleur (source, kustomize, helm) réconcilie sa partie de l’état désiré de manière autonome, sans coordination centralisée.
Points clés
- Flux se décompose en contrôleurs indépendants, chacun pilotant ses propres CRDs. Le source-controller réconcilie les sources (dépôts Git, buckets, OCI) : il clone le dépôt à l’intervalle configuré et expose une archive des manifestes. Le kustomize-controller réconcilie les objets Kustomization : il applique les manifestes issus du source-controller au cluster. Le helm-controller réconcilie les HelmRelease en installant ou mettant à jour les charts Helm.
- Ce découpage en contrôleurs autonomes reflète l’architecture même de Kubernetes : plutôt qu’un seul processus responsable de tout, chaque contrôleur possède sa propre boucle observe → diff → agit, son propre intervalle de réconciliation et ses propres conditions de statut. Une panne du helm-controller n’affecte pas la réconciliation des manifestes Kustomize.
- La CR GitRepository définit la source : URL du dépôt, branche, intervalle de polling et éventuellement un Secret contenant les credentials. Le source-controller détecte les nouveaux commits et met à jour un artifact (archive tar) que les autres contrôleurs consomment.
- La CR Kustomization (à ne pas confondre avec le fichier
kustomization.yamlde Kustomize) pointe vers un GitRepository et un chemin. Le kustomize-controller réconcilie les manifestes de ce chemin dans le cluster, avec health checks intégrés : il attend que les ressources appliquées soient prêtes avant de marquer la réconciliation comme réussie. - Flux supporte les notifications bidirectionnelles : un webhook GitHub déclenche une réconciliation immédiate (au lieu d’attendre le prochain intervalle), et un Alert Flux envoie les résultats de réconciliation vers Slack, Teams ou un endpoint HTTP. L’observabilité de la boucle est ainsi intégrée dès la conception.
Exemple concret
Un cluster de staging utilise Flux pour gérer trois microservices. Le dépôt Git platform-config contient un répertoire par service. Un GitRepository est configuré avec un intervalle de 1 minute. À t₀, un développeur pousse un commit qui modifie le nombre de replicas du service cart-api de 2 à 4. Le source-controller détecte le nouveau commit dans les 60 secondes, clone le dépôt et produit un nouvel artifact. Le kustomize-controller observe que l’artifact a changé, applique les manifestes mis à jour et lance un health check. Le Deployment cart-api passe de 2 à 4 replicas. Le kustomize-controller marque la Kustomization comme Ready: True. Un Alert Flux envoie une notification Slack : « Kustomization cart-api réconciliée avec succès — commit abc1234 ».
Comparaison — ArgoCD vs Flux
| Critère | ArgoCD | Flux |
|---|---|---|
| Architecture | Contrôleur monolithique + serveur API + UI web | Ensemble de micro-contrôleurs (source, kustomize, helm) |
| Interface | UI web riche + CLI argocd | CLI flux + portail Weave GitOps (optionnel) |
| Modèle de réconciliation | Une CR Application = un déploiement complet | Composition de CRs (GitRepository + Kustomization \| HelmRelease) |
| Multi-tenancy | Projects + RBAC applicatif | Namespaces natifs + ServiceAccounts Kubernetes |
| Déclenchement | Polling + webhooks | Polling + Receiver (webhook natif) |
Code YAML — configuration Flux (GitRepository + Kustomization)
# git-repository.yaml — le source-controller surveille ce dépôt
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: platform-config
namespace: flux-system
spec:
interval: 1m # fréquence de réconciliation de la source
url: https://github.com/acme/platform-config.git
ref:
branch: main
secretRef:
name: git-credentials # Secret contenant le token d'accès
---
# kustomization.yaml — le kustomize-controller applique ces manifestes
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: cart-api
namespace: flux-system
spec:
interval: 5m # fréquence de réconciliation des manifestes
sourceRef:
kind: GitRepository
name: platform-config
path: ./apps/cart-api # chemin des manifestes dans le dépôt
prune: true # supprimer les ressources absentes de Git
targetNamespace: staging
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: cart-api
namespace: staging
timeout: 3m # durée maximale du health check
Code bash — observer la réconciliation Flux
# Installer Flux dans le cluster (bootstrap)
flux bootstrap github \
--owner=acme \
--repository=platform-config \
--branch=main \
--path=clusters/staging \
--personal
# ✔ all components are healthy
# Vérifier l'état du GitRepository
flux get sources git
# NAME REVISION SUSPENDED READY MESSAGE
# platform-config main@abc1234 False True stored artifact for revision 'main@abc1234'
# Vérifier l'état de la Kustomization
flux get kustomizations
# NAME REVISION SUSPENDED READY MESSAGE
# cart-api main@abc1234 False True Applied revision: main@abc1234
# Forcer une réconciliation immédiate (sans attendre l'intervalle)
flux reconcile kustomization cart-api --with-source
# ✔ source reconciliation completed
# ✔ kustomization reconciliation completed
# Observer les événements de réconciliation
flux events --for Kustomization/cart-api
# Kustomization/cart-api info Reconciliation finished, next run in 5m
Piège courant : « Flux et ArgoCD sont interchangeables — le choix est purement esthétique » est une simplification. L’architecture diffère fondamentalement : ArgoCD centralise la logique dans un seul contrôleur avec un serveur API dédié et une interface web intégrée, tandis que Flux distribue la réconciliation entre plusieurs micro-contrôleurs indépendants pilotés uniquement par des CRDs Kubernetes. Ce choix a des conséquences sur le multi-tenancy (Flux repose sur les namespaces natifs), la résilience (une panne d’un contrôleur Flux n’affecte pas les autres) et l’opérabilité (ArgoCD offre une visibilité immédiate via son UI, Flux exige un outil complémentaire). Le bon choix dépend de l’équipe et de l’environnement.