L'Application en détail
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 :
| Type | Détecté par | Rendu |
|---|---|---|
| Répertoire de manifestes | aucun fichier particulier | les fichiers YAML et JSON du répertoire (option directory.recurse pour les sous-répertoires) |
| Helm | un Chart.yaml | helm template, avec valueFiles, values, parameters, releaseName |
| Kustomize | un kustomization.yaml | kustomize build, avec surcharges d'images, préfixes, correctifs |
| Greffon | configuré explicitement | un 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églage | Par défaut | Ce qu'il fait |
|---|---|---|
automated (présent, ou enabled: true) | absent | synchronise automatiquement quand la source change : nouveau commit, nouveaux paramètres |
selfHeal | false | synchronise aussi quand le cluster s'écarte de la source, sans nouveau commit |
prune | false | supprime les ressources retirées de la source ; sans lui, elles restent, signalées comme à élaguer |
allowEmpty | false | autorise 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: 8000Le 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.yamlreleaseName 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=trueLe 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
- Ajouter dans le chart l'annotation
argocd.argoproj.io/sync-options: Prune=falsesur le PVC, synchroniser, et vérifier qu'elle est présente dans le cluster. - Vérifier la politique de rétention du volume existant : la
reclaimPolicyd'une classe de stockage ne s'applique qu'aux volumes créés ensuite ; pour un volume déjà provisionné, passerpersistentVolumeReclaimPolicy: Retainsur le PV lui-même (kubectl patch pv). - Vérifier qu'aucune ressource n'est actuellement marquée « à élaguer » (
argocd app resourcesou le statutrequiresPruning), sans quoi l'activation la supprimerait. - 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-managerL'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.
automatedsynchronise quand la source change, une fois par révision et paramètres ;selfHealcorrige aussi les écarts du cluster ;prunesupprime ce qui a quitté la source ;allowEmptyprotège contre un rendu vide.- Les changements de politique prennent effet au cycle suivant ; les messages
Skipping auto-syncdu contrôleur expliquent chaque décision. ignoreDifferencesignore un champ dans la comparaison ;RespectIgnoreDifferences=truel'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.iorend la suppression en cascade ; sans lui, les ressources restent.
Pour aller plus loin
- Argo CD, Automated Sync Policy : toutes les conditions de la synchronisation automatique.
- Argo CD, Diffing Customization : pointeurs JSON, expressions JQ, gestionnaires de champs.
- Leçon suivante : Structurer les dépôts et promouvoir.
Sources
- Argo CD, Automated Sync Policy
- Argo CD, Sync Options
- Argo CD, Diffing Customization (ignoreDifferences)
- Argo CD, Helm (sources Helm, valueFiles, releaseName)
- Argo CD, Resource Tracking
- Argo CD, App Deletion (finalizer)
- Argo CD, guide de mise à niveau 2.14 vers 3.0 (suivi par annotation)
- Argo CD, application-controller : code de la synchronisation automatique (messages « Skipping auto-sync »)
- Kubernetes, Finalizers