Aller au contenu
Exploiter Argo CD

Exploiter Argo CD

300 Concevoir ⏱ 1 h 15 argocdkubernetesgitopshelmprometheus

À la fin, vous saurez

  • Faire passer une application déployée par Helm sous la gestion d'Argo CD, sans redémarrage ni suppression
  • Configurer des notifications sur les échecs de synchronisation et les dégradations
  • Choisir les métriques et alertes qui révèlent un Argo CD en mauvaise santé
  • Planifier les mises à jour d'Argo CD et sa reprise après sinistre
  • Choisir comment les nouvelles versions d'images arrivent dans Git

Prérequis

Testé avec argocd 3.5.3 argocd-image-updater 1.3.0 flux 2.9.6 , vérifié le 2 octobre 2026

Pourquoi

Installer Argo CD prend une heure. L'exploiter, c'est pour des années : il faut y faire entrer les applications qui existaient avant lui, savoir qu'une synchronisation a échoué la nuit sans regarder l'interface, le mettre à jour quatre fois par an, survivre à la perte de son cluster, et décider comment les nouvelles images arrivent dans Git. Cette dernière leçon rassemble ce qui sépare une démonstration d'une plateforme, avec deux incidents réels vécus chez Lyneko lors de la mise en place d'Argo CD, et ce qu'ils ont appris.

Les concepts

Exploiter Argo CD, c'est surveiller deux choses distinctes :

  • Les applications vues par Argo CD : sont-elles synchronisées, saines, et les synchronisations réussissent-elles ? C'est le rôle des notifications et des métriques argocd_app_*.
  • Argo CD lui-même : ses composants répondent-ils, joignent-ils Git et les clusters, ont-ils assez de mémoire ? C'est le rôle des métriques des composants et de la supervision Kubernetes habituelle.

Une panne d'Argo CD n'arrête pas les applications : elles continuent de tourner telles qu'elles sont. Mais plus rien ne se déploie, plus rien ne se répare, et une dérive passe inaperçue. C'est une panne silencieuse, d'où l'importance de la surveiller explicitement.

En pratique

Adopter une release Helm existante

Avant Argo CD, les applications de Lyneko étaient déployées par helm upgrade --install depuis la CI. Les faire passer sous Argo CD, c'est retirer à Helm la propriété de ressources qui tournent, sans les supprimer.

L'incident. La première adoption a suivi une idée qui semblait sûre : poser l'annotation helm.sh/resource-policy: keep sur toutes les ressources vivantes avec kubectl annotate, puis lancer helm uninstall, qui est censé conserver les ressources ainsi annotées. Helm n'a conservé qu'une ressource, un volume persistant dont l'annotation figurait dans le chart. Tout le reste (Deployments, StatefulSet, Services, Ingress, certificat, ExternalSecrets) a été supprimé, et l'application, utilisée par un client, est tombée jusqu'à ce qu'une synchronisation d'Argo CD la recrée, une à deux minutes plus tard. Aucune donnée perdue : les volumes avaient l'annotation dans le chart, une classe de stockage en Retain, et le StatefulSet une politique de rétention de ses PVC à Retain.

L'explication. helm uninstall évalue helm.sh/resource-policy sur le manifeste enregistré dans le secret de release de Helm, pas sur les objets du cluster. Une annotation posée à la main sur un objet vivant n'existe pas pour lui. Pour qu'elle compte, il faut l'ajouter dans le chart et faire un helm upgrade, afin qu'elle entre dans le manifeste enregistré.

La méthode sûre, validée ensuite sur plusieurs applications, sans aucun redémarrage :

  1. Épingler dans Git la version réellement déployée. Si la CI passait --set image.tag=<sha>, le values.yaml de Git dit autre chose (souvent latest), et Argo CD rendrait la mauvaise version.
  2. Créer l'Application sans syncPolicy : Argo CD compare, mais n'agit pas.
  3. Vérifier que la différence est vide (argocd app diff, ou helm template comparé à l'existant par kubectl diff). La seule différence acceptable est l'annotation de suivi d'Argo CD.
  4. Synchroniser. Argo CD ajoute son annotation argocd.argoproj.io/tracking-id ; le gabarit des pods ne change pas, donc aucun pod ne redémarre.
  5. Retirer Helm en supprimant seulement sa comptabilité, les secrets de release : kubectl delete secret -n <namespace> -l owner=helm,name=<release>. Les ressources ne sont pas touchées.
  6. Retirer le déploiement de la CI. Sinon, CI et Argo CD se battent ; chez Lyneko, le premier helm upgrade de la CI après l'adoption a d'ailleurs échoué, faute de secret de release (secrets "sh.helm.release.v1.<release>.v11" not found). La CI se contente désormais d'écrire la nouvelle version dans Git, et n'a plus besoin d'identifiant du cluster.

Les annotations meta.helm.sh/release-name et meta.helm.sh/release-namespace, et l'étiquette app.kubernetes.io/managed-by: Helm, restent sur les objets après l'adoption : elles sont inoffensives, mais un helm install du même nom pourrait de nouveau revendiquer ces ressources.

L'ordre est voulu : Argo CD synchronise avant que Helm ne lâche, et Helm reste une solution de repli tant qu'Argo CD n'a pas prouvé qu'il gère les ressources.

Caution

Pendant une adoption, laissez prune désactivé. Une ressource du chart oubliée dans Git (un volume persistant, par exemple) serait sinon supprimée à la première synchronisation automatique. Chez Lyneko, prune reste désactivé sur les applications qui ont des PVC ; pour l'activer, posez d'abord argocd.argoproj.io/sync-options: Prune=false sur les PVC.

Être prévenu

Le contrôleur de notifications fait partie d'Argo CD depuis la version 2.3. Il réagit à des déclencheurs (conditions sur l'état d'une Application), met en forme un modèle, et l'envoie à un service (courriel, Slack, Teams, Google Chat, Mattermost, webhook générique...). Le catalogue officiel fournit les déclencheurs courants, à installer une fois :

kubectl apply -n argocd --server-side --force-conflicts \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.5.3/notifications_catalog/install.yaml
DéclencheurQuand
on-sync-failedune synchronisation a échoué
on-health-degradedl'application est devenue Degraded
on-sync-status-unknownl'état de synchronisation est Unknown (erreur de rendu, cluster injoignable)
on-deployedsynchronisée et saine, une fois par commit
on-sync-succeeded, on-sync-running, on-created, on-deletedles autres étapes

Pour un espace Google Chat, l'URL du webhook entrant est un secret : elle va dans argocd-notifications-secret (produit par External Secrets, leçon 8), et la configuration la référence :

# argocd-notifications-cm (extrait)
data:
  service.googlechat: |
    webhooks:
      plateforme: $googlechat-plateforme

L'abonnement se pose par annotation, sur une Application ou, mieux, sur un AppProject pour couvrir toutes ses applications :

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: signalements
  annotations:
    notifications.argoproj.io/subscribe.on-sync-failed.googlechat: plateforme
    notifications.argoproj.io/subscribe.on-health-degraded.googlechat: plateforme
    notifications.argoproj.io/subscribe.on-sync-status-unknown.googlechat: plateforme

Ne vous abonnez pas à on-sync-succeeded sur toutes les applications : avec l'auto-réparation, le canal se remplit de messages que plus personne ne lit, et l'échec important s'y noie. Notifiez les échecs ; on-deployed peut servir, dans un canal séparé, à tracer les mises en production.

Surveiller

Chaque composant expose des métriques Prometheus. Les plus utiles :

MétriqueCe qu'elle dit
argocd_app_infoune série par application, avec sync_status et health_status en étiquettes
argocd_app_sync_totalles synchronisations, par résultat (phase)
argocd_app_reconcilela durée des réconciliations : un contrôleur qui s'essouffle
argocd_cluster_connection_statusla connexion à chaque cluster cible
argocd_git_request_total, argocd_git_request_duration_secondsles accès à Git du repo-server
argocd_repo_pending_request_totaldes rendus en attente : un repo-server saturé

Quelques alertes, en PromQL :

# Extrait des règles d'un PrometheusRule (sous spec.groups[].rules).
# Une application désynchronisée depuis plus de 30 minutes : l'auto-synchronisation n'y arrive pas,
# ou quelqu'un a désactivé l'automatisme et oublié.
- alert: ArgoCDApplicationDesynchronisee
  expr: argocd_app_info{sync_status="OutOfSync"} == 1
  for: 30m
# Une application dégradée.
- alert: ArgoCDApplicationDegradee
  expr: argocd_app_info{health_status="Degraded"} == 1
  for: 10m
# Un cluster cible injoignable.
- alert: ArgoCDClusterInjoignable
  expr: argocd_cluster_connection_status == 0
  for: 5m

Et une alerte sur l'absence de métriques (absent(argocd_app_info)) : si le contrôleur ne tourne plus, les autres alertes se taisent, faute de données.

Dimensionner : le second incident

L'incident. Le cluster Kapsule de Lyneko n'avait qu'un nœud, avec un disque racine de 20 Go (environ 17 Gio utilisables). Le cache d'images y avait atteint près de 10 Gio, dont 2 Gio pour une seule image d'analyse de documents, et le disque était plein à 90 %. L'installation d'Argo CD, avec ses images, a fait passer l'espace libre sous le seuil d'éviction du kubelet (10 % disponibles) : le nœud est passé en DiskPressure, et le kubelet a évincé des pods, dont le contrôleur d'entrée qui servait plusieurs applications. Elles sont devenues injoignables jusqu'à ce que le ramasse-miettes d'images libère de la place ; aucune intervention manuelle n'a été nécessaire. Le délai de 300 secondes de l'installation Helm d'Argo CD a d'ailleurs expiré pendant que le nœud se débattait.

Les leçons :

  • Sur un cluster à un seul nœud, chaque image jamais tirée s'accumule sur ce nœud. Dimensionner en processeur et mémoire ne suffit pas : déclarez aussi ephemeral-storage dans les ressources, et surveillez le disque des nœuds.
  • La correction a été un disque racine de 50 Go. Sur Kapsule, changer la taille du disque racine remplace le pool : le nœud est détruit et recréé, tout redémarre. À planifier, pas à improviser.
  • Argo CD n'est pas petit : contrôleur, repo-server, serveur, Redis, contrôleur d'ApplicationSet, notifications. Donnez-leur des requests réalistes et des limites de mémoire, en particulier au repo-server, qui rend les charts et peut consommer beaucoup pendant les pics.

Mettre à jour

Le projet publie une version mineure tous les trois mois, et seules les trois dernières mineures reçoivent des correctifs, y compris de sécurité. Une installation qui ne bouge pas pendant neuf mois n'est plus corrigée. La routine :

  1. lire les notes de mise à jour de chaque mineure traversée ; par exemple, la 3.5 embarque Helm 4.2 (avec des effets sur les dépôts OCI en HTTP) et remplace la vérification des signatures GnuPG par Source Integrity ;
  2. mettre à jour par Git (la version du chart Helm ou des manifestes dans le dépôt de la plateforme), d'abord sur une instance de recette si vous en avez une ;
  3. appliquer l'ensemble des manifestes, côté serveur (--server-side --force-conflicts), pas seulement l'image ;
  4. vérifier que les applications restent Synced et qu'aucune ne passe en erreur de comparaison après la mise à jour (un changement de version de Helm ou de Kustomize peut modifier un rendu).

Les correctifs (troisième chiffre) ne cassent rien par principe : appliquez-les vite, surtout quand ils corrigent une vulnérabilité.

Qui installe Argo CD ? Chez Lyneko, Argo CD est installé par Terraform (une ressource Helm dans le dépôt d'infrastructure), à côté du cluster. Une autre école fait gérer Argo CD par lui-même, à travers une Application qui pointe vers son propre chart : élégant, mais une mauvaise configuration peut l'empêcher de se réparer. Dans les deux cas, la version d'Argo CD est dans Git.

Sauvegarder

Avec GitOps, l'essentiel de l'état est dans Git : reconstruire un cluster, c'est réinstaller Argo CD et appliquer l'application racine. Ce qui n'est pas dans Git doit être sauvegardé ou reproductible :

  • les secrets (identifiants de dépôts et de clusters, secret OIDC) : dans le gestionnaire de secrets, ce qui est une raison de plus pour ESO ;
  • tout ce qui a été créé par l'interface ou la CLI au lieu de Git (Applications, projets, dépôts) : argocd admin export -n argocd > sauvegarde.yaml en fait un export complet, à réimporter avec argocd admin import ;
  • les clés de Sealed Secrets, si vous l'utilisez (leçon 8).

Le vrai test d'une reprise après sinistre est de la jouer : recréer Argo CD dans un cluster vide, et mesurer le temps jusqu'à ce que tout soit Synced.

Faire arriver les nouvelles images dans Git

Argo CD déploie ce que dit Git. Reste à mettre la nouvelle version de l'image dans Git, à chaque construction. Deux approches :

  • La CI écrit dans Git. Après avoir construit et poussé l'image, la CI modifie la version dans le dépôt de déploiement et commite (ou ouvre une demande de fusion pour la production, comme à la leçon 4). C'est l'approche de Lyneko : simple, tracée, sans composant de plus. Son piège : le remplacement par sed d'une ligne tag: peut toucher la mauvaise clé si le fichier en contient plusieurs ; préférez un outil qui comprend le YAML (yq).
  • Argo CD Image Updater surveille le registre et met à jour lui-même les applications, en écrivant dans Git ou en surchargeant les paramètres par l'API d'Argo CD. Il fonctionne avec les applications Helm, Kustomize et à greffon de rendu (Config Management Plugin), et se configure, depuis sa version 1, par une ressource ImageUpdater. Il est encore hébergé dans argoproj-labs, et son README indique ne pas le recommander « pour les charges de travail critiques en production ». La surcharge par l'API, qui ne passe pas par Git, contredit d'ailleurs le principe d'un état voulu versionné : si vous l'utilisez, choisissez l'écriture dans Git.

Et Flux ?

Flux est l'autre grand outil GitOps de la CNCF. Les principes sont les mêmes, la conception diffère :

Argo CDFlux
UnitéApplication, ApplicationSetKustomization, HelmRelease, sources séparées
Helmrendu par Argo CD (helm template), pas de release Helmvraie release Helm, gérée par le contrôleur Helm
Interfaceinterface web riche, RBAC et SSO intégréspas d'interface intégrée ; RBAC de Kubernetes
Multi-clustersun hub qui pilote les clusters ciblesen général, une instance par cluster
Mise à jour d'imagesImage Updater (projet labs)contrôleurs d'automatisation d'images intégrés

Flux plaît aux équipes qui veulent un outil réduit à ses contrôleurs, sans interface, gouverné uniquement par le RBAC de Kubernetes. Argo CD plaît à celles qui veulent une interface partagée avec les équipes de développement et un modèle multi-clusters centralisé. Les concepts de ce cours (réconciliation, état voulu dans Git, promotion par demande de fusion, secrets résolus dans le cluster) s'appliquent aux deux.

Sous le capot

Le contrôleur ne surveille pas Git en continu : il compare chaque application à Git toutes les 120 secondes par défaut (timeout.reconciliation), plus un délai aléatoire d'au plus 60 secondes (timeout.reconciliation.jitter) qui étale la charge sur le repo-server. D'où les « environ trois minutes » observés tout au long de ce cours. Un webhook de la forge vers argocd-server (/api/webhook) déclenche un rafraîchissement immédiat des applications concernées : c'est le réglage qui rend les déploiements quasi instantanés. Protégez-le par un secret partagé : plusieurs vulnérabilités de 2024 et 2025 permettaient de faire tomber argocd-server par une requête de webhook malformée, sans authentification.

Pièges courants

helm.sh/resource-policy: keep posé à la main, puis helm uninstall. Les ressources sont supprimées. Supprimez les secrets de release de Helm à la place.

latest dans Git pendant une adoption. Argo CD déploierait une autre version que celle qui tourne. Épinglez d'abord.

La CI déploie encore après l'adoption. Deux maîtres pour les mêmes ressources. Retirez le déploiement de la CI.

Un canal de notifications que personne ne lit. Trop de messages. Ne notifiez que ce qui demande une action.

Une mise à jour qui saute plusieurs mineures sans lire les notes. Lisez les notes de chaque version traversée.

DiskPressure après l'installation d'un composant. Le disque du nœud était déjà presque plein. Surveillez le disque, déclarez ephemeral-storage.

Sécurité

Mettez à jour. C'est la mesure de sécurité la plus efficace : la leçon 9 a montré des vulnérabilités critiques corrigées uniquement dans les mineures supportées.

Les sauvegardes contiennent des secrets. Un argocd admin export contient les Secrets d'Argo CD : identifiants de dépôts et de clusters. Chiffrez-le et stockez-le comme un secret.

Les notifications sortent du cluster. Elles envoient des noms d'applications, des messages d'erreur, parfois des extraits de manifestes, vers un service externe. Choisissez des modèles sobres, et des services de confiance.

Le webhook d'Argo CD est un point d'entrée sans authentification utilisateur : secret partagé obligatoire, et si possible accessible uniquement depuis votre forge. Les avis de sécurité de 2025 sur les webhooks (CVE-2025-59531, CVE-2025-59537, CVE-2025-59538) recommandent de définir un secret aléatoire pour chaque fournisseur, y compris ceux que vous n'utilisez pas (Gogs, Bitbucket Server, Azure DevOps) : sans secret, le point d'entrée d'un fournisseur accepte n'importe quelle requête.

En production

Chez Lyneko, le bilan de la mise en place tient en quelques règles, toutes issues des incidents de cette leçon :

  • adoption des applications Helm par la méthode sûre (épingler, comparer, synchroniser, supprimer les secrets de release, retirer le déploiement de la CI), sans aucun redémarrage sur les applications suivantes ;
  • prune désactivé tant que les PVC ne sont pas protégés par Prune=false ;
  • un disque de nœud dimensionné pour le cache d'images, et le disque surveillé ;
  • la CI qui écrit la version dans Git et n'a plus d'identifiant du cluster : un secret de moins dans la CI, ce qui est peut-être le plus grand gain de sécurité de tout le passage à GitOps.

Exercices

1. Un collègue propose d'adopter une release Helm en lançant helm uninstall --keep-history. Qu'en pensez-vous ?

Solution

--keep-history conserve l'historique des releases, pas les ressources : helm uninstall supprime toujours les ressources, sauf celles dont le manifeste enregistré porte helm.sh/resource-policy: keep. Pour retirer la propriété de Helm sans toucher aux ressources, on supprime les secrets de release (owner=helm,name=<release>), après qu'Argo CD a synchronisé l'application.

2. Écrivez l'abonnement qui envoie les échecs de synchronisation de toutes les applications de production dans l'espace Google Chat astreinte, et rien d'autre.

Solution

Sur l'AppProject de production (ou dans subscriptions d'argocd-notifications-cm avec un sélecteur d'étiquettes) :

metadata:
  annotations:
    notifications.argoproj.io/subscribe.on-sync-failed.googlechat: astreinte

avec astreinte déclaré dans service.googlechat.webhooks, l'URL venant de argocd-notifications-secret.

3. Votre installation est en 3.2 en octobre 2026. Est-elle encore supportée ? Que faites-vous ?

Solution

Avec une mineure tous les trois mois et la 3.5 publiée, les versions supportées sont les trois dernières mineures : 3.5, 3.4 et 3.3. La 3.2 ne reçoit plus de correctifs, même de sécurité. Il faut monter en lisant les notes de 3.2 vers 3.3, 3.3 vers 3.4 et 3.4 vers 3.5, idéalement une mineure à la fois en vérifiant les applications entre chaque étape.

4. Pourquoi absent(argocd_app_info) est-elle une alerte indispensable ?

Solution

Les autres alertes reposent sur les séries de argocd_app_info. Si le contrôleur ne tourne plus, ou n'est plus collecté, ces séries disparaissent, et les alertes « désynchronisée » ou « dégradée » ne peuvent plus se déclencher : le silence ressemblerait à un état sain. L'alerte sur l'absence détecte justement cette panne silencieuse.

5. Faut-il préférer Image Updater ou l'écriture par la CI pour Signalements ?

Solution

L'écriture par la CI : la CI sait déjà quelle image elle vient de construire et de tester, le commit relie la version à la construction, la promotion en production reste une demande de fusion relue, et il n'y a pas de composant supplémentaire. Image Updater a du sens quand les images viennent de l'extérieur (une image tierce à suivre) ; il reste un projet labs que ses mainteneurs ne recommandent pas pour les charges critiques.

Récapitulatif

  • Adopter une release Helm : épingler la version, Application sans automatisme, différence vide, synchroniser, supprimer les secrets de release, retirer le déploiement de la CI. Jamais helm.sh/resource-policy posé à la main sur l'existant.
  • Notifier les échecs (on-sync-failed, on-health-degraded, on-sync-status-unknown), de préférence par projet, pas les succès.
  • Surveiller argocd_app_info, la connexion aux clusters, le repo-server, et l'absence même des métriques.
  • Dimensionner aussi le disque : un nœud plein évince des pods qui n'ont rien à voir avec Argo CD.
  • Mettre à jour au rythme du projet : une mineure par trimestre, trois mineures supportées.
  • Sauvegarder ce que Git ne contient pas, et jouer la reprise.
  • Les nouvelles images arrivent dans Git par la CI ; Image Updater reste un projet labs.

Pour aller plus loin

Voir ma constellation →

Sources