Lab 12.2 : GitOps avec Argo CD¶
| Durée | 90 à 120 min |
| Niveau | Semi-guidé |
| Prérequis | Lab 12.1 réalisé (image publique dans ghcr.io), Lab 11.2 réalisé (Kustomize), cours du chapitre 12 lu, cluster Ready, accès Internet depuis les VMs |
| Acquis visés | AA7 |
Objectifs
- Installer Argo CD sur le cluster et accéder à son interface
- Créer un dépôt de configuration au format Kustomize
- Déclarer une
ApplicationArgo CD qui déploie l'application depuis Git - Déployer une nouvelle version en modifiant Git, sans
kubectl apply - Observer la correction automatique d'une dérive (
selfHeal) et son absence en mode manuel - Revenir à une version précédente avec
git revert
Contexte et schéma¶
Vous séparez désormais le code (dépôt webapp, Lab 12.1) de la configuration de déploiement (dépôt webapp-config). Argo CD, installé dans le cluster, lit le second et aligne le cluster dessus.
flowchart LR
subgraph GH["GitHub"]
A["webapp<br/>(code + CI)"] -- "publie" --> R[("ghcr.io<br/>webapp:commit")]
C["webapp-config<br/>(base + overlay prod)"]
end
subgraph K["Cluster k3s"]
AG["Argo CD"] -- "lit" --> C
AG -- "applique" --> NS["namespace tp-prod<br/>Deployment webapp"]
end
R -. "pull de l'image" .-> NS
Ressources limitées
Argo CD lance plusieurs composants et occupe une part sensible de la mémoire de vos VMs. Avant de commencer, supprimez les namespaces des autres TP (tp-k8s, tp-dev, monitoring, etc.) et surveillez k top nodes. Au-delà de 85 % de mémoire sur un nœud, arrêtez et reprenez plus tard.
Étapes¶
Étape 1 : Préparer le cluster¶
Supprimez les namespaces de TP inutiles (k delete namespace NOM). Notez la mémoire utilisée par chaque nœud : c'est votre point de départ.
Étape 2 : Installer Argo CD¶
Cherchez le numéro de la dernière version stable de la page Releases du projet Argo CD (github.com/argoproj/argo-cd/releases, depuis votre poste Windows) et fixez-le :
ARGOVER=<version, par exemple v2.x.y>
k create namespace argocd
k apply -n argocd --server-side -f https://raw.githubusercontent.com/argoproj/argo-cd/$ARGOVER/manifests/install.yaml
k get pods -n argocd -w
(Ctrl+C pour arrêter la surveillance.) Attendez que tous les Pods soient Running et prêts, ce qui peut prendre plusieurs minutes. Vérifiez la mémoire :
Pourquoi --server-side ?
Certaines définitions d'objets d'Argo CD sont trop volumineuses pour un apply classique. L'option --server-side demande à l'API server de fusionner les modifications.
- Tous les Pods du namespace
argocdsont prêts - Les nœuds restent sous 85 % de mémoire
Étape 3 : Accéder à l'interface¶
Récupérez le mot de passe initial de l'utilisateur admin, puis exposez l'interface :
k -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
k port-forward -n argocd svc/argocd-server 8443:443 --address 0.0.0.0
Laissez cette commande tourner dans un terminal. Depuis le navigateur du poste Windows, ouvrez https://IP-DU-SERVEUR:8443 (acceptez l'avertissement : le certificat est auto-signé), puis connectez-vous avec admin.
- L'interface Argo CD s'affiche
- Vous êtes connectés (liste d'applications vide)
Étape 4 : Créer le dépôt de configuration¶
Créez un dépôt GitHub public webapp-config. Il doit contenir cette arborescence :
webapp-config/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
└── prod/
└── kustomization.yaml
base/deployment.yaml (remplacez VOTRE-COMPTE) :
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 1
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: ghcr.io/VOTRE-COMPTE/webapp
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
resources:
requests:
cpu: 20m
memory: 16Mi
limits:
cpu: 100m
memory: 64Mi
À écrire vous-mêmes :
base/service.yaml: un Servicewebappde typeClusterIP, port 80, sélecteurapp: webapp;base/kustomization.yaml: la liste des deux ressources ;overlays/prod/kustomization.yaml: référence../../base, namespacetp-prod, 2 réplicas (patch) et tag de l'image (transformationimages,name=ghcr.io/VOTRE-COMPTE/webapp,newTag= un tag de 7 caractères de votre registre).
Indices
- Reprenez la structure de l'overlay
proddu Lab 11.2. - Le patch de réplicas est un fichier
replicas.yamlà côté de l'overlay, qui désigne le Deploymentwebapp. - L'image sans tag dans la base est valable : c'est l'overlay qui fixe
newTag.
Vérifiez le rendu avant de pousser :
Cherchez replicas: 2, namespace: tp-prod et l'image complète avec son tag. Puis publiez le dépôt (git add, git commit, git push), comme au Lab 12.1.
- Le rendu de l'overlay contient 2 réplicas, le namespace
tp-prodet l'image avec son tag - Le dépôt
webapp-configest publié sur GitHub
Étape 5 : Déclarer l'application¶
Créez application.yaml sur le serveur (ce fichier n'est pas dans le dépôt de configuration) :
cat <<'EOF2' > application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: webapp
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/VOTRE-COMPTE/webapp-config.git
targetRevision: main
path: overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: tp-prod
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
EOF2
k apply -f application.yaml
k get applications -n argocd
Dans l'interface, ouvrez l'application webapp : suivez la synchronisation. Vérifiez ensuite le cluster :
L'état attendu est Synced et Healthy.
- L'application est
SyncedetHealthy - Deux Pods
webapptournent danstp-prod - Vous avez trouvé, dans l'interface, la représentation graphique Deployment → ReplicaSet → Pods
Étape 6 : Déployer une nouvelle version par Git¶
- Dans le dépôt
webapp(Lab 12.1), changez le titre deindex.html(« version 2 »), puisgit commitetgit push. La CI publie une nouvelle image : relevez son tag (7 caractères). - Dans le dépôt
webapp-config, modifieznewTagdansoverlays/prod/kustomization.yaml, puisgit commitetgit push. - Sans toucher au cluster, observez Argo CD :
Argo CD interroge Git à intervalle régulier (environ toutes les trois minutes). Pour ne pas attendre, cliquez sur Refresh dans l'interface. La nouvelle version est déployée par un rolling update.
Vérifiez que l'image du Deployment est la nouvelle :
- La CI a publié un nouveau tag
- Après la modification de Git, le Deployment utilise la nouvelle image sans
kubectl apply
Étape 7 : La dérive est corrigée (selfHeal)¶
Modifiez le cluster à la main :
Observez : Argo CD détecte l'écart et ramène le Deployment à 2 réplicas, valeur de Git. Notez le délai.
- Le nombre de réplicas revient à 2 sans intervention
Étape 8 : Passer en synchronisation manuelle¶
Retirez la synchronisation automatique de l'application :
k patch application webapp -n argocd --type merge -p '{"spec":{"syncPolicy":null}}'
k scale deployment webapp -n tp-prod --replicas=5
k get applications -n argocd
Cette fois, l'application passe à OutOfSync et le cluster reste à 5 réplicas. Dans l'interface, la ressource est signalée en écart. Cliquez sur Sync : le cluster est ramené à l'état de Git.
Rétablissez ensuite la synchronisation automatique avec k apply -f application.yaml.
- L'application est
OutOfSync, et le cluster n'est pas corrigé automatiquement - Un clic sur Sync rétablit l'état voulu
- La synchronisation automatique est rétablie
Étape 9 : Revenir en arrière avec Git¶
Dans le dépôt webapp-config, annulez la dernière modification de tag :
Après un Refresh, observez : le Deployment revient à l'image précédente. L'historique de Git est le journal de vos déploiements.
- Le Deployment utilise de nouveau l'image précédente
-
git logmontre la mise à jour puis son annulation
Questions de réflexion¶
Qu'est-ce qui, dans cette démarche, remplace kubectl apply ?
Un git push dans le dépôt de configuration. L'agent Argo CD lit Git et applique les différences ; plus personne n'a besoin d'identifiants d'administration du cluster pour déployer.
Quelle différence de comportement entre l'étape 7 et l'étape 8 ?
Avec selfHeal, Argo CD corrige seul la dérive. Sans synchronisation automatique, il se contente de signaler l'écart (OutOfSync) et attend une action humaine (Sync).
Pourquoi n'avez-vous pas versionné application.yaml dans webapp-config ?
L'objet Application décrit comment Argo CD lit le dépôt : il est géré à part, côté cluster. Versionner dans le même dépôt est possible (modèle « app of apps »), mais demande une amorce manuelle et dépasse ce lab.
Que se passe-t-il si quelqu'un pousse dans webapp-config une image qui n'existe pas ?
Argo CD applique le changement, les nouveaux Pods restent en ImagePullBackOff, l'état Health passe à Progressing puis Degraded, tandis que les anciens Pods continuent de servir pendant le rolling update. Le retour arrière se fait par git revert.
Quelle étape de cette chaîne reste manuelle, et comment l'automatiser ?
La mise à jour du tag dans webapp-config après la publication de l'image. La CI peut la faire elle-même (commit automatique dans le dépôt de configuration, avec un jeton limité à ce dépôt), ou un outil dédié peut surveiller le registre.
Dépannage¶
| Symptôme | Pistes |
|---|---|
k apply du install.yaml : Too long |
Option --server-side oubliée |
Pods d'Argo CD Pending ou redémarrages |
Mémoire insuffisante : supprimer d'autres namespaces, k top nodes, k describe pod |
| Interface inaccessible depuis Windows | port-forward arrêté, --address 0.0.0.0 oublié, pare-feu ufw de la VM, https:// oublié dans l'URL |
Connexion refusée avec admin |
Mot de passe mal recopié ; relire le Secret argocd-initial-admin-secret |
Application en Unknown ou ComparisonError |
URL du dépôt incorrecte, dépôt privé, path absent du dépôt : k describe application webapp -n argocd |
Erreur kustomize build dans Argo CD |
Rendu invalide : tester kubectl kustomize overlays/prod localement avant de pousser |
OutOfSync permanent juste après le déploiement |
Champ modifié par un autre acteur (ou, ici, replicas) ; relire la différence dans l'interface |
Pods ImagePullBackOff |
Paquet ghcr.io privé, tag erroné, accès Internet : k describe pod -n tp-prod |
| Argo CD ne voit pas le push | Attendre ~3 minutes ou cliquer sur Refresh ; vérifier la branche (targetRevision) |
selfHeal ne corrige pas |
Application sans syncPolicy.automated (étape 8 non annulée) |
Nettoyage¶
k delete application webapp -n argocd
k delete namespace tp-prod
k delete -n argocd --server-side -f https://raw.githubusercontent.com/argoproj/argo-cd/$ARGOVER/manifests/install.yaml 2>/dev/null
k delete namespace argocd
k get crd | grep argoproj
Si des définitions argoproj.io subsistent, supprimez-les :
Arrêtez le port-forward (Ctrl+C). Conservez les dépôts webapp et webapp-config : ils serviront de base au projet fil rouge.