Aller au contenu
Conteneurs & Orchestration medium

kubectl diff et wait : prévisualiser et synchroniser vos déploiements

16 min de lecture

logo kubernetes

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.

  • Prévisualiser les changements d'un manifest avec kubectl diff avant d'appliquer
  • Lire une sortie diff et comprendre ce qui va être ajouté, modifié ou supprimé
  • Intégrer diff dans 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 diffapplywait

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.

MomentCommandeCe qu'elle fait
Avant apply, vérifier les changementskubectl diff -f manifest.yamlAffiche un diff entre le cluster et le fichier
Après apply, attendre que ce soit prêtkubectl wait --for=condition=Ready ...Bloque jusqu'à l'état attendu (ou timeout)
En CI/CD, valider puis synchroniserdiffapplywaitWorkflow complet et fiable

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.

Fenêtre de terminal
kubectl diff -f <fichier.yaml> [-n namespace]

Supposons que vous modifiez l'image d'un Deployment dans votre fichier api-gateway.yaml :

Fenêtre de terminal
kubectl diff -f api-gateway.yaml
spec:
containers:
- name: api-gateway
image: nginx:1.25
image: nginx:1.27
ports:
- containerPort: 8080

Ce diff vous indique clairement : l'image passera de nginx:1.25 à nginx:1.27. Rien d'autre ne change.

diff fonctionne aussi avec un dossier entier ou un répertoire Kustomize :

Fenêtre de terminal
# Tous les manifests d'un dossier
kubectl diff -f ./k8s/prod/
# Avec Kustomize
kubectl diff -k ./overlays/production/

Par défaut, kubectl diff utilise un diff interne. Vous pouvez le remplacer par un outil plus lisible :

Fenêtre de terminal
# Utiliser colordiff pour une sortie colorée
export KUBECTL_EXTERNAL_DIFF="colordiff -u"
kubectl diff -f api-gateway.yaml
# Utiliser dyff pour un diff structuré YAML
export KUBECTL_EXTERNAL_DIFF="dyff between --omit-header"
kubectl diff -f api-gateway.yaml

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

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.

  1. Prévisualisez les changements

    Fenêtre de terminal
    kubectl diff -f api-gateway.yaml

    Lisez la sortie. Si quelque chose vous surprend, arrêtez-vous là.

  2. Appliquez si le diff est conforme

    Fenêtre de terminal
    kubectl apply -f api-gateway.yaml
  3. 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).

Fenêtre de terminal
kubectl wait --for=condition=<condition> <type>/<nom> [-n namespace] --timeout=<durée>

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 ressourceConditionCe que ça attend
Podcondition=ReadyLe pod a passé ses readiness probes
Deploymentcondition=AvailableLe nombre de réplicas souhaité est prêt
Jobcondition=CompleteLe job s'est terminé avec succès
Jobcondition=FailedLe job a échoué (utile pour détecter les erreurs)
Certificate (Cert-Manager)condition=ReadyLe certificat TLS a été émis
PoddeleteLe pod a été supprimé (n'existe plus)

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.

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é.

Fenêtre de terminal
kubectl wait --for=condition=Available deploy/api-gateway -n prod --timeout=120s
deployment.apps/api-gateway condition met

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.

Fenêtre de terminal
kubectl wait --for=condition=Ready pod/api-server-7d4b8c -n prod --timeout=60s

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.

Fenêtre de terminal
kubectl wait --for=condition=Ready pods -l app=api-gateway -n prod --timeout=120s

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.

Fenêtre de terminal
kubectl wait --for=condition=Complete job/migration-db -n prod --timeout=300s

Utile dans les scripts de drain ou de remplacement :

Fenêtre de terminal
kubectl delete pod api-server-7d4b8c -n prod
kubectl wait --for=delete pod/api-server-7d4b8c -n prod --timeout=60s

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.

Fenêtre de terminal
kubectl wait --for=condition=Ready certificate/api-tls -n prod --timeout=120s

wait retourne un code de sortie exploitable :

Code retourSignification
0La condition est atteinte dans le délai
1Timeout 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= :

Fenêtre de terminal
# 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 3
kubectl wait --for=jsonpath='{.status.availableReplicas}'=3 deploy/api-gateway -n prod --timeout=120s

Combiner 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 bash
set -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 0
fi
kubectl diff -f "$MANIFEST" -n "$NAMESPACE" || true
echo ""
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 1
fi

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.

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 diff avant apply, c'est votre filet de sécurité
  • Intégrez diff comme première étape de votre pipeline CI/CD
  • Utilisez --server-side quand des webhooks de mutation sont en place
  • Définissez KUBECTL_EXTERNAL_DIFF pour une sortie lisible (colordiff, dyff)
  • En CI, exploitez le code retour (0 = rien à faire, 1 = changements)

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=delete après un kubectl delete pour s'assurer que la ressource a disparu
  • Combinez avec set -e dans 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

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ômeCause probableSolution
diff ne montre aucun changementLe manifest est identique à l'état du clusterVérifiez que vous avez modifié et sauvegardé le fichier
diff retourne un code > 1Erreur (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ésChamps ajoutés par les defaults ou webhooksC'est normal, utilisez --server-side pour un diff plus précis
diff échoue avec unauthorizedLe ServiceAccount n'a pas le droit de faire un dry-runAjoutez les verbes create en dry-run dans le RBAC
wait timeout expiré (code 1)La ressource n'atteint pas la condition dans le délaiVérifiez kubectl describe <type>/<nom> pour comprendre pourquoi (events, erreurs)
wait bloque indéfinimentPas de --timeout spécifiéAjoutez --timeout=120s (ou la durée adaptée)
wait échoue : resource not foundLa ressource n'existe pas (encore)Attendez sa création d'abord, ou utilisez kubectl wait après kubectl apply
wait --for=jsonpath ne matche pasType de la valeur incorrect (string vs int)Vérifiez avec kubectl get -o jsonpath='{...}' le format exact
wait avec selector ne retourne rienAucun pod ne matche le labelVérifiez avec kubectl get pods -l <selector> -n <ns>
  • kubectl diff est votre filet de sécurité : il montre ce qui va changer avant apply, pas après.
  • Le code retour de diff est exploitable : 0 = rien à faire, 1 = changements à appliquer, > 1 = erreur.
  • kubectl wait bloque jusqu'à une condition (Ready, Available, Complete, delete), indispensable en CI/CD.
  • Mettez toujours un --timeout sur wait : 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).

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn