
Vous êtes sur le point de lancer kubectl apply, mais que va-t-il réellement changer dans le cluster ? Et une fois appliqué, comment savoir que le déploiement est effectivement prêt avant de passer à l'étape suivante ? kubectl diff vous montre exactement les modifications avant de les appliquer. kubectl wait bloque jusqu'à ce qu'une ressource atteigne l'état attendu. Ensemble, ces deux commandes transforment un déploiement manuel en un workflow fiable et automatisable.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Prévisualiser les changements d'un manifest avec
kubectl diffavant d'appliquer - Lire une sortie diff et comprendre ce qui va être ajouté, modifié ou supprimé
- Intégrer
diffdans un pipeline CI/CD pour bloquer les changements non attendus - Attendre qu'un pod, deployment, job ou certificat soit prêt avec
kubectl wait - Écrire des scripts de déploiement robustes combinant
diff→apply→wait
Quand utiliser chaque commande
Section intitulée « Quand utiliser chaque commande »Les deux commandes n'interviennent pas au même moment et ne se remplacent
pas. diff sert avant l'application, pour décider ; wait sert après,
pour synchroniser la suite du script. Le tableau résume les trois situations où
l'une, l'autre ou les deux se justifient.
| Moment | Commande | Ce qu'elle fait |
|---|---|---|
Avant apply, vérifier les changements | kubectl diff -f manifest.yaml | Affiche un diff entre le cluster et le fichier |
Après apply, attendre que ce soit prêt | kubectl wait --for=condition=Ready ... | Bloque jusqu'à l'état attendu (ou timeout) |
| En CI/CD, valider puis synchroniser | diff → apply → wait | Workflow complet et fiable |
kubectl diff : que va changer mon apply ?
Section intitulée « kubectl diff : que va changer mon apply ? »kubectl diff compare le contenu d'un manifest (fichier YAML) avec l'état actuel de la ressource dans le cluster. La sortie est un diff standard (comme git diff) : les lignes - seront supprimées/remplacées, les lignes + seront ajoutées.
L'option -f accepte un fichier, un dossier ou l'entrée standard. Sans -n, la
commande travaille dans le namespace du contexte kubectl courant.
kubectl diff -f <fichier.yaml> [-n namespace]Premier exemple
Section intitulée « Premier exemple »Supposons que vous modifiez l'image d'un Deployment dans votre fichier api-gateway.yaml :
kubectl diff -f api-gateway.yamlspec: containers: - name: api-gateway image: nginx:1.25 image: nginx:1.27 ports: - containerPort: 8080Ce diff vous indique clairement : l'image passera de nginx:1.25 à nginx:1.27. Rien d'autre ne change.
Comparer un dossier de manifests
Section intitulée « Comparer un dossier de manifests »diff fonctionne aussi avec un dossier entier ou un répertoire Kustomize :
# Tous les manifests d'un dossierkubectl diff -f ./k8s/prod/
# Avec Kustomizekubectl diff -k ./overlays/production/Personnaliser le programme de diff
Section intitulée « Personnaliser le programme de diff »Par défaut, kubectl diff utilise un diff interne. Vous pouvez le remplacer par un outil plus lisible :
# Utiliser colordiff pour une sortie coloréeexport KUBECTL_EXTERNAL_DIFF="colordiff -u"kubectl diff -f api-gateway.yaml
# Utiliser dyff pour un diff structuré YAMLexport KUBECTL_EXTERNAL_DIFF="dyff between --omit-header"kubectl diff -f api-gateway.yamlIntégrer diff dans un pipeline CI/CD
Section intitulée « Intégrer diff dans un pipeline CI/CD »kubectl diff est un excellent garde-fou dans un pipeline de déploiement :
diff: stage: validate script: - kubectl diff -f ./k8s/prod/ || true # Le || true empêche l'échec du job (exit code 1 = changements)
deploy: stage: deploy script: - kubectl apply -f ./k8s/prod/ - kubectl wait --for=condition=Available deploy/api-gateway -n prod --timeout=300s when: manual # Validation humaine après review du diff- name: Preview changes run: | kubectl diff -f ./k8s/prod/ || true
- name: Deploy if: github.ref == 'refs/heads/main' run: | kubectl apply -f ./k8s/prod/ kubectl wait --for=condition=Available deploy/api-gateway -n prod --timeout=300sWorkflow complet : diff → apply → verify
Section intitulée « Workflow complet : diff → apply → verify »Ces trois étapes constituent le geste de base d'un déploiement manuel
maîtrisé. La troisième n'est pas décorative : un apply réussi signifie
uniquement que l'API a accepté le manifest, pas que les pods tournent.
-
Prévisualisez les changements
Fenêtre de terminal kubectl diff -f api-gateway.yamlLisez la sortie. Si quelque chose vous surprend, arrêtez-vous là.
-
Appliquez si le diff est conforme
Fenêtre de terminal kubectl apply -f api-gateway.yaml -
Vérifiez que l'apply a bien fonctionné
Fenêtre de terminal kubectl rollout status deploy/api-gateway -n prod
kubectl wait : attendre qu'une ressource soit prête
Section intitulée « kubectl wait : attendre qu'une ressource soit prête »kubectl wait bloque l'exécution jusqu'à ce qu'une ressource atteigne une condition donnée, ou jusqu'à expiration du timeout. C'est l'outil de synchronisation de kubectl.
Le nom de la ressource peut être remplacé par un selector -l, et --timeout
attend une durée avec son unité (60s, 5m).
kubectl wait --for=condition=<condition> <type>/<nom> [-n namespace] --timeout=<durée>Conditions les plus utilisées
Section intitulée « Conditions les plus utilisées »Chaque type de ressource publie ses propres conditions dans son
status. Le tableau reprend celles que l'on croise le plus souvent ; pour une
ressource précise, kubectl get <type>/<nom> -o yaml affiche les conditions
réellement présentes et leur valeur du moment.
| Type de ressource | Condition | Ce que ça attend |
|---|---|---|
| Pod | condition=Ready | Le pod a passé ses readiness probes |
| Deployment | condition=Available | Le nombre de réplicas souhaité est prêt |
| Job | condition=Complete | Le job s'est terminé avec succès |
| Job | condition=Failed | Le job a échoué (utile pour détecter les erreurs) |
| Certificate (Cert-Manager) | condition=Ready | Le certificat TLS a été émis |
| Pod | delete | Le pod a été supprimé (n'existe plus) |
Recettes essentielles
Section intitulée « Recettes essentielles »Les six commandes qui suivent couvrent la quasi-totalité des besoins réels. Elles ne diffèrent que par la ressource visée et la condition attendue, la structure de la commande restant identique.
Attendre qu'un Deployment soit prêt
Section intitulée « Attendre qu'un Deployment soit prêt »Available indique que le nombre de réplicas demandé est disponible, et non
que la mise à jour est terminée. Pour suivre le déroulé d'un rollout,
kubectl rollout status reste plus adapté.
kubectl wait --for=condition=Available deploy/api-gateway -n prod --timeout=120sdeployment.apps/api-gateway condition metAttendre qu'un pod soit Ready
Section intitulée « Attendre qu'un pod soit Ready »La condition Ready dépend de la readiness probe déclarée sur le
conteneur. Sans probe, le pod est considéré prêt dès que son processus démarre,
ce qui rend l'attente peu significative.
kubectl wait --for=condition=Ready pod/api-server-7d4b8c -n prod --timeout=60sAttendre tous les pods d'un label
Section intitulée « Attendre tous les pods d'un label »Avec un selector, wait attend que tous les pods correspondants
remplissent la condition. Attention au cas limite : si aucun pod ne porte le
label, la commande n'attend rien et rend la main immédiatement en succès.
kubectl wait --for=condition=Ready pods -l app=api-gateway -n prod --timeout=120sAttendre la fin d'un Job
Section intitulée « Attendre la fin d'un Job »Complete n'est atteint que si le job réussit. En cas d'échecs successifs,
la commande ira jusqu'au bout du timeout : surveillez aussi condition=Failed
si vous voulez sortir dès la première erreur.
kubectl wait --for=condition=Complete job/migration-db -n prod --timeout=300sAttendre la suppression d'un pod
Section intitulée « Attendre la suppression d'un pod »Utile dans les scripts de drain ou de remplacement :
kubectl delete pod api-server-7d4b8c -n prodkubectl wait --for=delete pod/api-server-7d4b8c -n prod --timeout=60sAttendre un certificat TLS (Cert-Manager)
Section intitulée « Attendre un certificat TLS (Cert-Manager) »Utile avant de basculer du trafic vers un Ingress. L'émission d'un certificat prend souvent plusieurs dizaines de secondes, le temps que la validation ACME auprès de l'autorité aboutisse.
kubectl wait --for=condition=Ready certificate/api-tls -n prod --timeout=120sTimeout et code de sortie
Section intitulée « Timeout et code de sortie »wait retourne un code de sortie exploitable :
| Code retour | Signification |
|---|---|
| 0 | La condition est atteinte dans le délai |
| 1 | Timeout expiré, la condition n'a pas été atteinte |
Attendre avec jsonpath (conditions personnalisées)
Section intitulée « Attendre avec jsonpath (conditions personnalisées) »Pour des conditions non standard, utilisez --for=jsonpath= :
# Attendre que le champ .status.phase soit "Running"kubectl wait --for=jsonpath='{.status.phase}'=Running pod/mon-pod -n prod --timeout=60s
# Attendre que le nombre de réplicas disponibles soit 3kubectl wait --for=jsonpath='{.status.availableReplicas}'=3 deploy/api-gateway -n prod --timeout=120sCombiner diff et wait dans un script de déploiement
Section intitulée « Combiner diff et wait dans un script de déploiement »Voici un script complet qui illustre le workflow sécurisé :
#!/usr/bin/env bashset -euo pipefail
NAMESPACE="prod"MANIFEST="./k8s/prod/"DEPLOY="api-gateway"TIMEOUT="300s"
echo "=== 1. Prévisualisation des changements ==="if kubectl diff -f "$MANIFEST" -n "$NAMESPACE" > /dev/null 2>&1; then echo "Aucun changement détecté, rien à faire." exit 0fi
kubectl diff -f "$MANIFEST" -n "$NAMESPACE" || trueecho ""
echo "=== 2. Application des changements ==="kubectl apply -f "$MANIFEST" -n "$NAMESPACE"
echo "=== 3. Attente que le déploiement soit prêt ==="if kubectl wait --for=condition=Available "deploy/$DEPLOY" \ -n "$NAMESPACE" --timeout="$TIMEOUT"; then echo "✅ Déploiement réussi."else echo "❌ Timeout : le déploiement n'est pas prêt." kubectl rollout status "deploy/$DEPLOY" -n "$NAMESPACE" exit 1fiBonnes pratiques
Section intitulée « Bonnes pratiques »Les recommandations qui suivent tiennent en deux réflexes : regarder ce qui va changer avant de l'appliquer, et ne jamais laisser une commande d'attente sans limite de temps. Le reste n'est que du réglage.
kubectl diff
Section intitulée « kubectl diff »Ces cinq points portent sur la fiabilité de la prévisualisation, en particulier sur les cas où le diff calculé côté client s'écarte de ce que le serveur appliquera réellement.
- Toujours exécuter
diffavantapply, c'est votre filet de sécurité - Intégrez
diffcomme première étape de votre pipeline CI/CD - Utilisez
--server-sidequand des webhooks de mutation sont en place - Définissez
KUBECTL_EXTERNAL_DIFFpour une sortie lisible (colordiff, dyff) - En CI, exploitez le code retour (0 = rien à faire, 1 = changements)
kubectl wait
Section intitulée « kubectl wait »Ces cinq points visent la robustesse en script : sortir proprement au bout d'un délai fixé, et cibler la bonne ressource même lorsque son nom n'est pas connu à l'avance.
- Toujours mettre un
--timeout, jamais d'attente infinie dans un script - Préférez les selectors (
-l app=...) aux noms de pods pour les déploiements multi-réplicas - Utilisez
--for=deleteaprès unkubectl deletepour s'assurer que la ressource a disparu - Combinez avec
set -edans vos scripts pour arrêter le pipeline en cas de timeout - Pour des conditions exotiques, utilisez
--for=jsonpath=avec vérification préalable du format
Dépannage
Section intitulée « Dépannage »Le tableau couvre les erreurs des deux commandes. Côté diff, la surprise
la plus fréquente est un écart portant sur des champs que vous n'avez jamais
écrits, ajoutés par les valeurs par défaut ou par un webhook. Côté wait, c'est
une ressource qui n'existe pas encore au moment où la commande démarre.
| Symptôme | Cause probable | Solution |
|---|---|---|
diff ne montre aucun changement | Le manifest est identique à l'état du cluster | Vérifiez que vous avez modifié et sauvegardé le fichier |
diff retourne un code > 1 | Erreur (manifest invalide, ressource inexistante…) | Vérifiez la syntaxe YAML et que la ressource existe avec kubectl get |
| Diff montre des champs que vous n'avez pas modifiés | Champs ajoutés par les defaults ou webhooks | C'est normal, utilisez --server-side pour un diff plus précis |
diff échoue avec unauthorized | Le ServiceAccount n'a pas le droit de faire un dry-run | Ajoutez les verbes create en dry-run dans le RBAC |
wait timeout expiré (code 1) | La ressource n'atteint pas la condition dans le délai | Vérifiez kubectl describe <type>/<nom> pour comprendre pourquoi (events, erreurs) |
wait bloque indéfiniment | Pas de --timeout spécifié | Ajoutez --timeout=120s (ou la durée adaptée) |
wait échoue : resource not found | La ressource n'existe pas (encore) | Attendez sa création d'abord, ou utilisez kubectl wait après kubectl apply |
wait --for=jsonpath ne matche pas | Type de la valeur incorrect (string vs int) | Vérifiez avec kubectl get -o jsonpath='{...}' le format exact |
wait avec selector ne retourne rien | Aucun pod ne matche le label | Vérifiez avec kubectl get pods -l <selector> -n <ns> |
À retenir
Section intitulée « À retenir »kubectl diffest votre filet de sécurité : il montre ce qui va changer avantapply, pas après.- Le code retour de
diffest exploitable : 0 = rien à faire, 1 = changements à appliquer, > 1 = erreur. kubectl waitbloque jusqu'à une condition (Ready, Available, Complete, delete), indispensable en CI/CD.- Mettez toujours un
--timeoutsurwait: sans limite, la commande bloque le runner jusqu'à ce que la CI finisse par tuer le job elle-même, sans message utile. - Utilisez
--for=jsonpath=pour des conditions personnalisées sur n'importe quel champ du status. - Le workflow de base en prod : diff → apply → wait, simple, fiable, scriptable.
- Personnalisez l'affichage du diff avec
KUBECTL_EXTERNAL_DIFF(colordiff, dyff).