Aller au contenu
L'Application en détail

L'Application en détail

200 Pratiquer ⏱ 1 h 15 argocdkuberneteshelmgitops

À la fin, vous saurez

  • Déclarer une Application à partir d'un chart Helm et de fichiers de valeurs par environnement
  • Régler la synchronisation automatique, l'auto-réparation et l'élagage en connaissant leur comportement réel
  • Ignorer un champ piloté par un autre contrôleur sans casser la synchronisation
  • Expliquer comment Argo CD suit ses ressources
  • Supprimer une application en conservant ou en supprimant ses ressources

Prérequis

Testé avec argocd 3.5.3 helm 3.16.3 (poste), 4 (dans Argo CD 3.5) kubernetes 1.36.4 , vérifié le 2 octobre 2026

Pourquoi

À la leçon précédente, l'application était synchronisée à la main. C'est le bon point de départ, et ce n'est pas du GitOps complet : rien ne se passe entre deux commandes. Les deux derniers principes, tirer automatiquement et réconcilier en continu, demandent la synchronisation automatique, et c'est elle qui fait la différence avec un pipeline.

Elle s'accompagne de décisions qui ne sont pas anodines. Faut-il corriger tout écart, au risque d'annuler un geste d'urgence ? Faut-il supprimer ce qui disparaît de Git, au risque d'effacer un volume de données ? Que faire d'un champ qu'un autre contrôleur modifie légitimement, comme le nombre de répliques piloté par un autoscaler ? Chez Lyneko, l'élagage automatique est désactivé sur les applications qui ont des volumes persistants, pour une raison précise donnée plus bas ; c'est un choix, pas un oubli.

Cette leçon passe Signalements à un chart Helm, comme les applications de Lyneko, puis règle la synchronisation automatique pièce par pièce, en observant à chaque fois ce que fait réellement Argo CD. Plusieurs comportements y sont moins évidents que la documentation ne le laisse croire.

Les concepts

Les sources

Une Application tire ses manifestes d'une source, et le repo-server en détecte le type :

TypeDétecté parRendu
Répertoire de manifestesaucun fichier particulierles fichiers YAML et JSON du répertoire (option directory.recurse pour les sous-répertoires)
Helmun Chart.yamlhelm template, avec valueFiles, values, parameters, releaseName
Kustomizeun kustomization.yamlkustomize build, avec surcharges d'images, préfixes, correctifs
Greffonconfiguré explicitementun outil de rendu personnalisé (Config Management Plugin)

La source peut être un dépôt Git, un dépôt de charts Helm, ou, depuis Argo CD 3.1, un artefact OCI (repoURL: oci://...), y compris un chart Helm publié dans un registre. Une Application peut même combiner plusieurs sources (un chart d'un registre et des fichiers de valeurs d'un dépôt Git, par exemple).

Un point à retenir pour Helm : Argo CD rend le chart avec helm template et applique le résultat lui-même. Il n'y a pas de release Helm dans le cluster, helm list ne montre rien, et les hooks Helm sont traduits en hooks Argo CD (leçon 5). Argo CD 3.5 embarque Helm 4.

Des réglages distincts

La politique de synchronisation automatique, spec.syncPolicy.automated, regroupe plusieurs réglages qu'il faut comprendre séparément :

RéglagePar défautCe qu'il fait
automated (présent, ou enabled: true)absentsynchronise automatiquement quand la source change : nouveau commit, nouveaux paramètres
selfHealfalsesynchronise aussi quand le cluster s'écarte de la source, sans nouveau commit
prunefalsesupprime les ressources retirées de la source ; sans lui, elles restent, signalées comme à élaguer
allowEmptyfalseautorise une synchronisation qui supprimerait toutes les ressources (garde-fou contre un dépôt vidé par erreur)

Sans selfHeal, un kubectl scale fait à la main reste en place, et l'application est simplement OutOfSync. Sans prune, retirer un fichier de Git ne supprime rien. Ces valeurs par défaut sont prudentes, et chacune se décide en connaissance de cause.

Le suivi des ressources

Pour savoir quelles ressources du cluster lui appartiennent, Argo CD pose sur chacune une annotation de suivi, argocd.argoproj.io/tracking-id, de la forme <application>:<groupe>/<type>:<namespace>/<nom>. C'est le comportement par défaut depuis Argo CD 3.0. Les versions 2.x utilisaient par défaut l'étiquette app.kubernetes.io/instance, au risque de collisions avec les outils qui posent cette même étiquette (les charts Helm la posent couramment). Le suivi par annotation identifie précisément chaque ressource, et permet à Argo CD de reconnaître une ressource copiée par un autre outil, qui porterait l'annotation mais pas sa propre identité.

En pratique

Passer à un chart Helm

Le dépôt de déploiement reçoit un chart minimal, dans chart/ :

# chart/Chart.yaml
apiVersion: v2
name: signalements
description: Signalements, l'application de démonstration des cours Lyneko
type: application
version: 0.1.0
appVersion: "1.1.0"
# chart/values.yaml
# Valeurs par défaut ; chaque environnement les surcharge dans son fichier.
image:
  repository: registre.lyneko.example/signalements
  tag: "1.1.0"
replicas: 1
environnement: inconnu
ressources:
  requests: {cpu: 50m, memory: 96Mi}
  limits: {memory: 192Mi}
# chart/values-recette.yaml
image:
  tag: "1.1.0"   # écrit par la CI
replicas: 2
environnement: recette
# chart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}
  labels:
    app: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels:
      app: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ .Release.Name }}
    spec:
      securityContext:
        runAsNonRoot: true
      containers:
        - name: signalements
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: 8000
          env:
            - name: ENVIRONNEMENT
              value: {{ .Values.environnement | quote }}
          readinessProbe:
            httpGet:
              path: /sante
              port: 8000
          resources:
            {{- toYaml .Values.ressources | nindent 12 }}
# chart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}
spec:
  selector:
    app: {{ .Release.Name }}
  ports:
    - port: 80
      targetPort: 8000

Le fichier values-recette.yaml porte la ligne que le pipeline de construction mettra à jour, exactement comme dans les applications de Lyneko et dans le cours GitHub Actions. On vérifie le rendu localement :

$ helm lint chart -f chart/values-recette.yaml
...
1 chart(s) linted, 0 chart(s) failed
$ helm template signalements chart -f chart/values-recette.yaml | grep -E "replicas|image:|value:"
  replicas: 2
          image: "registre.lyneko.example/signalements:1.1.0"
              value: "recette"

On supprime l'ancien répertoire signalements/, on pousse, et on change la source de l'Application :

  source:
    repoURL: http://forgejo.forge.svc.cluster.local:3000/plateforme/signalements-deploiement.git
    targetRevision: main
    path: chart
    helm:
      releaseName: signalements
      valueFiles:
        - values-recette.yaml

releaseName fixe le nom de release utilisé par les modèles ({{ .Release.Name }}) ; sans lui, ce serait le nom de l'application, signalements-recette, et tous les objets changeraient de nom. valueFiles est relatif au chemin du chart.

$ kubectl apply -f applications/signalements-recette.yaml
$ argocd app get signalements-recette --refresh
...
  Path:             chart
  Helm Values:      values-recette.yaml
...
Sync Status:        Synced to main (8f55d52)
Health Status:      Healthy

GROUP  KIND        NAMESPACE             NAME          STATUS  HEALTH   HOOK  MESSAGE
       Service     signalements-recette  signalements  Synced  Healthy        service/signalements unchanged
apps   Deployment  signalements-recette  signalements  Synced  Healthy        deployment.apps/signalements unchanged
$ argocd app diff signalements-recette
$ echo $?
0

Le passage d'un répertoire de manifestes à un chart Helm est invisible pour le cluster : le chart rend exactement les mêmes objets, Argo CD n'a rien à changer, aucun pod ne redémarre. C'est la façon sûre de faire évoluer la structure d'un dépôt : vérifier d'abord que le diff est vide. Et, comme annoncé, aucune release Helm n'existe :

$ kubectl -n signalements-recette get secrets -l owner=helm
No resources found in signalements-recette namespace.

La synchronisation automatique, et sa première surprise

Activons la synchronisation automatique seule, puis modifions le cluster à la main :

Note

Dans les blocs de cette leçon, les lignes qui commencent par # résument ce qu'a affiché une petite boucle de relevé (des kubectl get et argocd app get à intervalles réguliers), omise pour la lisibilité.

$ argocd app set signalements-recette --sync-policy automated
$ kubectl -n signalements-recette scale deployment signalements --replicas=4
$ sleep 20
# après 20 s : Synced, répliques 2

Le changement manuel a été annulé, alors que selfHeal n'est pas activé. L'explication est dans le journal du contrôleur et dans l'état de l'application :

$ argocd app get signalements-recette -o json | jq -r '"dernière opération : \(.status.operationState.operation.initiatedBy) révision \(.status.operationState.syncResult.revision[0:7])"'
dernière opération : {"automated":true} révision 8f55d52

La synchronisation automatique est faite une fois par combinaison de révision et de paramètres de la source. Or, depuis le passage au chart, la révision 8f55d52 et la nouvelle source n'avaient jamais été synchronisées : l'application était Synced sans qu'aucune opération ait eu lieu. L'activation de la synchronisation automatique a donc déclenché une synchronisation de cette combinaison, qui s'est produite juste après le kubectl scale, et l'a annulé au passage.

Recommençons maintenant que cette combinaison a été synchronisée :

$ argocd app set signalements-recette --self-heal=false
$ kubectl -n signalements-recette scale deployment signalements --replicas=4
$ sleep 30
# après 30 s : OutOfSync, répliques 4

Cette fois, la synchronisation automatique ne fait rien : la source n'a pas changé. L'application est OutOfSync, l'écart est visible dans l'interface et dans les métriques, mais il est laissé en place.

L'auto-réparation

$ argocd app set signalements-recette --self-heal
# répliques revenues à 2 après 2 s
$ kubectl -n signalements-recette scale deployment signalements --replicas=6
# second écart corrigé après 2 s
$ kubectl -n argocd get events --field-selector involvedObject.name=signalements-recette --sort-by=.lastTimestamp \
    -o custom-columns=RAISON:.reason,MESSAGE:.message | tail -4
ResourceUpdated      Updated health status: Healthy -> Progressing
OperationCompleted   Partial sync operation to 8f55d527d8b19071c9aa7456b650d9703d1e87a7 succeeded
ResourceUpdated      Updated sync status: OutOfSync -> Synced
ResourceUpdated      Updated health status: Progressing -> Healthy

Avec selfHeal, l'écart est corrigé en deux secondes. L'événement précise qu'il s'agit d'une synchronisation partielle : seules les ressources hors de synchronisation sont réappliquées. Si les écarts se répètent (un autre contrôleur qui se bat avec Argo CD), les corrections successives sont espacées par un délai qui croît de façon exponentielle (2 secondes, puis trois fois plus à chaque fois, jusqu'à 5 minutes), pour ne pas transformer la dispute en boucle effrénée.

L'élagage, et sa seconde surprise

Ajoutons une ConfigMap au chart, puis retirons-la :

# chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-annonce
data:
  message: "Maintenance prévue samedi"
$ git add chart && git commit -qm "Annonce de maintenance" && git push -q origin main
$ kubectl -n signalements-recette get configmap signalements-annonce -o name
configmap/signalements-annonce
$ git rm -q chart/templates/configmap.yaml && git commit -qm "Fin de l'annonce" && git push -q origin main
$ argocd app get signalements-recette --refresh | grep -E "^Sync Status|ConfigMap"
Sync Status:        OutOfSync from main (4a09531)
       ConfigMap   signalements-recette  signalements-annonce  OutOfSync                 configmap/signalements-annonce created
$ kubectl -n signalements-recette get configmap signalements-annonce -o name
configmap/signalements-annonce

Sans prune, la ConfigMap reste. L'application est OutOfSync, et la ressource est marquée comme devant être élaguée (requiresPruning: true dans le statut). Le journal du contrôleur dit pourquoi aucune synchronisation automatique n'a eu lieu :

$ kubectl -n argocd logs statefulset/argocd-application-controller --since=10m | grep signalements-recette | ...
2026-10-02T07:23:18Z Initiated automated sync to '4c3e68678b0ef341bf3de4382b7c987d2a3f9ce7'
...
2026-10-02T07:23:21Z Skipping auto-sync: need to prune extra resources only but automated prune is disabled

Activons maintenant l'élagage :

$ argocd app set signalements-recette --auto-prune
$ sleep 60
Sync Status:        OutOfSync from main (4a09531)

Une minute plus tard, rien n'a changé : modifier la politique ne relance pas l'évaluation. Elle a lieu au prochain cycle de réconciliation, au plus tard trois minutes, ou immédiatement après un rafraîchissement :

$ argocd app get signalements-recette --refresh > /dev/null
# ConfigMap élaguée 2 s après le rafraîchissement
$ kubectl -n argocd logs statefulset/argocd-application-controller --since=2m | grep signalements-recette | ...
2026-10-02T07:24:58Z Adding resource result, status: 'Pruned', phase: 'Succeeded', message: 'pruned'

C'est la limite de l'agent de la leçon 1 qui est levée : grâce à l'annotation de suivi, Argo CD retrouve une ressource qui n'existe plus dans la source et la supprime.

Ignorer un champ piloté ailleurs

Certains champs ne sont pas à Git. Le nombre de répliques d'un Deployment piloté par un autoscaler horizontal en est l'exemple classique : l'autoscaler le modifie en permanence, et l'auto-réparation le remettrait à la valeur de Git à chaque fois. On déclare le champ ignoré :

spec:
  # Le nombre de répliques est piloté par un autoscaler, pas par Git.
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - RespectIgnoreDifferences=true

Le laboratoire n'a pas de serveur de métriques ; on simule l'autoscaler par un kubectl scale :

$ kubectl -n signalements-recette scale deployment signalements --replicas=5
$ sleep 20
# après 20 s : Synced, répliques 5

L'application reste Synced : la différence sur /spec/replicas est ignorée. Le vrai test est celui d'un commit qui modifie autre chose : la synchronisation qu'il déclenche conserve-t-elle la valeur de l'autoscaler ?

$ sed -i 's/tag: "1.1.0"   # écrit par la CI/tag: "1.0.0"   # écrit par la CI/' chart/values-recette.yaml
$ git commit -qam "Recette : retour en 1.0.0 pour essai" && git push -q origin main
$ argocd app wait signalements-recette --sync --health --timeout 120
$ kubectl -n signalements-recette get deploy signalements -o jsonpath='répliques {.spec.replicas}, image {.spec.template.spec.containers[0].image}{"\n"}'
répliques 5, image registre.lyneko.example/signalements:1.0.0

Oui. Et sans l'option RespectIgnoreDifferences=true, avec un nouveau commit :

$ kubectl -n argocd patch application signalements-recette --type json -p '[{"op":"remove","path":"/spec/syncPolicy/syncOptions/1"}]'
$ sed -i 's/tag: "1.0.0"   # écrit par la CI/tag: "1.1.0"   # écrit par la CI/' chart/values-recette.yaml
$ git commit -qam "Recette : 1.1.0" && git push -q origin main
$ argocd app wait signalements-recette --sync --health --timeout 120
# répliques 2, image registre.lyneko.example/signalements:1.1.0

Sans l'option, ignoreDifferences ne concerne que la comparaison : la synchronisation applique le manifeste complet, et remet les répliques à la valeur de Git, en coupant l'herbe sous le pied de l'autoscaler. Avec un vrai autoscaler, le nombre de pods aurait chuté à chaque déploiement. RespectIgnoreDifferences=true étend l'ignorance à la synchronisation. (Une autre solution, souvent préférable : ne pas mettre replicas du tout dans le Deployment quand un autoscaler le gère.)

Supprimer une application

Que deviennent les ressources quand on supprime l'Application ? Cela dépend d'un finalizer. Deux applications d'essai, identiques sauf sur ce point :

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: essai-avec
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  # ... même source que signalements-recette, destination essai-avec
$ kubectl apply -f applications/essai-sans.yaml -f applications/essai-avec.yaml
Warning: metadata.finalizers: "resources-finalizer.argocd.argoproj.io": prefer a domain-qualified finalizer name including a path (/) to avoid accidental conflicts with other finalizer writers
$ kubectl -n argocd delete application essai-sans
application.argoproj.io "essai-sans" deleted from argocd namespace
$ kubectl -n essai-sans get deploy,svc
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/signalements   1/1     1            1           20s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/signalements   ClusterIP   10.96.154.214   <none>        80/TCP    20s
$ kubectl -n argocd delete application essai-avec
application.argoproj.io "essai-avec" deleted from argocd namespace
$ kubectl -n essai-avec get deploy,svc
No resources found in essai-avec namespace.

Avec kubectl delete et sans finalizer, la suppression est sans cascade : l'Application disparaît, ses ressources restent, désormais orphelines. Avec resources-finalizer.argocd.argoproj.io, Kubernetes attend qu'Argo CD ait supprimé toutes les ressources avant de supprimer l'Application. L'avertissement de Kubernetes 1.36 porte seulement sur la forme du nom ; Argo CD propose aussi la variante resources-finalizer.argocd.argoproj.io/background, qui supprime en arrière-plan.

Le comportement sans cascade est précieux pour migrer une application (la retirer d'Argo CD sans couper le service) ; le comportement en cascade, pour nettoyer un environnement temporaire. Attention, la CLI ne se comporte pas comme kubectl : argocd app delete supprime en cascade par défaut (le serveur pose lui-même le finalizer), après une simple confirmation ; --cascade=false conserve les ressources. L'interface propose les deux modes à chaque suppression.

Sous le capot

La synchronisation automatique est décidée par le contrôleur à chaque réconciliation, dans une fonction qui enchaîne des conditions, et dont les messages de journal (Skipping auto-sync: ...) disent laquelle a arrêté le processus : application déjà synchronisée, opération déjà en cours, synchronisation déjà tentée pour cette révision et ces paramètres, seulement des ressources à élaguer avec l'élagage désactivé, ou ressources à supprimer toutes (refusé sans allowEmpty). Pour l'auto-réparation, une condition supplémentaire s'ajoute : le délai exponentiel depuis la dernière correction. Lire ces messages est le moyen le plus direct de comprendre pourquoi une application ne se synchronise pas.

La comparaison se fait sur des objets normalisés : Argo CD retire les champs que Kubernetes gère lui-même (status depuis la 3.0, metadata.generation, managedFields), applique les valeurs par défaut connues, puis les règles ignoreDifferences (par pointeur JSON, par expression JQ, ou par gestionnaire de champ avec managedFieldsManagers, qui ignore tout ce qu'un contrôleur donné a écrit). Par défaut, le diff est calculé côté client, en trois voies comme kubectl apply. Le diff côté serveur (server-side diff), stable depuis la 3.1 mais pas activé par défaut, demande à l'API un dry run de l'application, ce qui tient compte des webhooks d'admission et des valeurs par défaut réelles ; il s'active par une annotation sur l'Application ou globalement.

Pièges courants

L'auto-synchronisation annule un geste manuel alors que selfHeal est désactivé. Une synchronisation automatique de la révision courante n'avait pas encore eu lieu. Vérifiez la dernière opération (status.operationState).

L'élagage activé ne supprime rien. La politique a changé, pas la révision : attendez le cycle suivant ou rafraîchissez.

ignoreDifferences n'empêche pas la synchronisation de remettre le champ. Il manque RespectIgnoreDifferences=true.

Un nouveau commit fait disparaître tous les objets. Le répertoire de la source existe toujours mais ne contient plus de manifestes (ou le chart ne rend plus rien), et le rendu est vide. (Un chemin qui n'existe plus est différent : c'est une ComparisonError, et rien n'est supprimé, leçon 4.) Sans allowEmpty, la synchronisation automatique refuse de tout supprimer : c'est le garde-fou. Ne l'activez pas sans raison.

Les objets changent de nom après le passage à Helm. releaseName n'est pas fixé : Helm utilise le nom de l'Application. Vérifiez que le diff est vide avant de synchroniser.

helm list ne montre pas l'application. C'est normal : Argo CD rend le chart sans créer de release. Les commandes helm upgrade ou helm rollback faites à côté entrent en conflit avec Argo CD et seront annulées.

Deux applications se disputent une ressource. Elles rendent un même objet (un namespace commun, une ressource globale). Chaque synchronisation réécrit l'annotation de suivi. FailOnSharedResource=true fait échouer la synchronisation au lieu de se battre.

Sécurité

L'auto-réparation est une protection. Un changement manuel non autorisé (ou malveillant) dans le cluster est annulé en quelques secondes, et laisse une trace dans les événements. Sans elle, il dure jusqu'au prochain commit.

L'élagage peut détruire des données. Retirer de Git le modèle d'un PersistentVolumeClaim, par erreur ou lors d'un refactoring, supprime le volume avec prune: true, et ses données selon la politique de rétention. Chez Lyneko, l'élagage automatique est désactivé sur les applications à volumes persistants ; pour l'activer, on pose d'abord l'annotation argocd.argoproj.io/sync-options: Prune=false sur les PVC, qui les exclut de l'élagage, et l'on garde les volumes en Retain (classe de stockage pour les nouveaux volumes, persistentVolumeReclaimPolicy sur les volumes existants).

ignoreDifferences est une porte ouverte. Un champ ignoré n'est plus surveillé : un changement malveillant sur ce champ passe inaperçu. Ignorez le moins possible, et de préférence par gestionnaire de champ plutôt que par chemin.

La suppression en cascade est irréversible. Une Application supprimée avec son finalizer emporte tout. Réservez le finalizer aux environnements jetables, ou protégez les applications de production par les projets et le RBAC (leçon 9).

En production

Les réglages de Lyneko. Synchronisation automatique et auto-réparation activées, élagage désactivé tant que les volumes ne sont pas protégés par annotation, applications créées sans politique de synchronisation lors de l'adoption, puis passées en automatique une fois le diff vérifié (leçon 10).

Les webhooks. En production, un webhook de la forge vers /api/webhook d'Argo CD déclenche le rafraîchissement dès la poussée, au lieu d'attendre jusqu'à trois minutes. La documentation cite GitHub, GitLab, Bitbucket, Bitbucket Server, Azure DevOps et Gogs ; pour une autre forge, vérifiez qu'elle sait envoyer l'un de ces formats, et protégez le point d'entrée par le secret partagé correspondant.

Les autoscalers. Pour un Deployment piloté par un autoscaler, le plus simple est de ne pas écrire replicas dans le manifeste ; sinon, ignoreDifferences (par pointeur ou par gestionnaire de champ) et RespectIgnoreDifferences=true.

Les réessais. syncPolicy.retry relance une synchronisation qui échoue (une ressource dont la définition n'est pas encore installée, un webhook d'admission indisponible), avec un délai croissant. Utile, mais une synchronisation qui échoue en boucle doit déclencher une alerte (leçon 10), pas seulement des réessais.

Exercices

1. Pour chacune de ces combinaisons, dites ce qui se passe après un kubectl delete service signalements : (a) synchronisation manuelle ; (b) automated seul, après une première synchronisation automatique de la révision courante ; (c) automated et selfHeal.

Solution

(a) L'application passe OutOfSync, le service reste supprimé jusqu'à une synchronisation manuelle. (b) Pareil : la source n'a pas changé, la synchronisation automatique ne fait rien. (c) Le service est recréé en quelques secondes par une synchronisation partielle.

2. Votre équipe veut activer prune: true sur une application qui contient un PersistentVolumeClaim de base de données. Rédigez les étapes, dans l'ordre.

Solution
  1. Ajouter dans le chart l'annotation argocd.argoproj.io/sync-options: Prune=false sur le PVC, synchroniser, et vérifier qu'elle est présente dans le cluster.
  2. Vérifier la politique de rétention du volume existant : la reclaimPolicy d'une classe de stockage ne s'applique qu'aux volumes créés ensuite ; pour un volume déjà provisionné, passer persistentVolumeReclaimPolicy: Retain sur le PV lui-même (kubectl patch pv).
  3. Vérifier qu'aucune ressource n'est actuellement marquée « à élaguer » (argocd app resources ou le statut requiresPruning), sans quoi l'activation la supprimerait.
  4. Activer prune: true.

3. Remplacez le pointeur JSON de ignoreDifferences par une règle qui ignore tout ce qu'écrit l'autoscaler. Quel est l'avantage ?

Solution
  ignoreDifferences:
    - group: apps
      kind: Deployment
      managedFieldsManagers:
        - kube-controller-manager

L'autoscaler horizontal fait partie du gestionnaire de contrôleurs de Kubernetes, et ses écritures sont enregistrées sous le gestionnaire de champs kube-controller-manager (c'est l'exemple que donne la documentation d'Argo CD). Seuls les champs dont ce gestionnaire est propriétaire, selon metadata.managedFields, sont ignorés. Un kubectl scale fait à la main, dont le gestionnaire est kubectl, reste détecté et corrigé ; le pointeur /spec/replicas ignorait le champ quelle que soit l'origine du changement. Vérifiez avec kubectl get deploy -o yaml --show-managed-fields quel gestionnaire écrit réellement le champ dans votre cluster.

4. Vous devez retirer une application de la gestion d'Argo CD pour la confier à une autre instance, sans interruption. Quelle suppression choisissez-vous, et que reste-t-il à faire ?

Solution

Une suppression sans cascade (retirer d'abord le finalizer s'il est présent, ou choisir le mode non cascade dans argocd app delete). Les ressources restent en place. La nouvelle instance doit ensuite les adopter : Application sans politique de synchronisation, diff vérifié, première synchronisation qui réécrit l'annotation de suivi à son nom.

5. Pourquoi l'activation de la synchronisation automatique a-t-elle annulé le kubectl scale dans cette leçon, alors que selfHeal était désactivé ? Comment l'auriez-vous évité ?

Solution

Parce que la combinaison de la révision 8f55d52 et de la nouvelle source Helm n'avait jamais été synchronisée : l'activation a déclenché une synchronisation automatique de cette combinaison, qui a réappliqué le Deployment. Pour l'éviter : synchroniser une fois à la main après tout changement de source, avant d'activer la synchronisation automatique, ou ne pas faire de geste manuel dans la fenêtre qui suit l'activation.

Récapitulatif

  • Une Application rend une source répertoire, Helm, Kustomize, greffon, éventuellement OCI ; avec Helm, Argo CD rend le chart sans créer de release.
  • automated synchronise quand la source change, une fois par révision et paramètres ; selfHeal corrige aussi les écarts du cluster ; prune supprime ce qui a quitté la source ; allowEmpty protège contre un rendu vide.
  • Les changements de politique prennent effet au cycle suivant ; les messages Skipping auto-sync du contrôleur expliquent chaque décision.
  • ignoreDifferences ignore un champ dans la comparaison ; RespectIgnoreDifferences=true l'ignore aussi à la synchronisation.
  • Argo CD suit ses ressources par l'annotation argocd.argoproj.io/tracking-id (défaut depuis la 3.0).
  • Le finalizer resources-finalizer.argocd.argoproj.io rend la suppression en cascade ; sans lui, les ressources restent.

Pour aller plus loin

Voir ma constellation →

Sources