E-NO
Kubernetes 7 min de lecture

Erreurs de déploiement Kubernetes : causes, diagnostic et corrections sûres

calendar_today Publié : 2026-11-05
update Dernière mise à jour : 2026-11-05
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Erreurs de déploiement Kubernetes : causes, diagnostic et corrections sûres ».

Introduction

Les erreurs de déploiement Kubernetes peuvent bloquer les mises en production, épuiser les ingénieurs d'astreinte et éroder la confiance dans la plateforme. La bonne nouvelle, c'est que la plupart des échecs suivent un petit nombre de schémas : images de conteneurs mal configurées, ressources manquantes, sondes défaillantes et déploiements trop rapides. La mauvaise nouvelle, c'est que sans approche systématique, vous pouvez perdre des heures à deviner une indentation YAML ou à chercher des journaux qui ne montrent pas le vrai problème.

Cet article vous fournit un flux de travail de diagnostic reproductible, pas une collection de commandes à copier-coller. Vous apprendrez à inventorier l'environnement de manière sûre, à inspecter un déploiement sans le modifier, à interpréter les messages d'erreur les plus courants et à récupérer avec un rayon d'impact minimal. Chaque recommandation inclut une commande concrète, la sortie attendue et un plan de secours. Le public cible comprend les développeurs qui possèdent leurs services, les consultants DevOps qui doivent réparer des clusters qu'ils n'ont pas construits et les équipes de démarrage où une personne porte plusieurs casquettes.

La sécurité opérationnelle est le principe sous-jacent : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.

Inventaire de la version et de l'environnement

Avant de toucher à un déploiement cassé, vous devez savoir à quoi vous avez affaire. Le comportement de Kubernetes change selon les versions ; un correctif qui fonctionne sur la 1.28 peut ne pas s'appliquer à la 1.30. Commencez par des observations en lecture seule.

Exemples de commandes d'inventaire :

kubectl version --short
# Client Version: v1.30.2
# Server Version: v1.30.0
kubectl get deployment -n production
# NAME        READY   UP-TO-DATE   AVAILABLE   AGE
# web-app     0/3     3            0           15m
kubectl get pods -n production -l app=web-app -o wide
# NAME                      READY   STATUS             RESTARTS   AGE   IP       NODE
# web-app-6d4b7c9f5-abcde   0/1     ImagePullBackOff   0          5m    <none>   node-pool-1
# web-app-6d4b7c9f5-fghij   0/1     ImagePullBackOff   0          5m    <none>   node-pool-2
# web-app-6d4b7c9f5-klmno   0/1     ImagePullBackOff   0          5m    <none>   node-pool-3

Remarquez le statut ImagePullBackOff. Cela indique que le pod n'a pas pu extraire l'image du conteneur, mais pas pourquoi. Pour le savoir, décrivez le pod :

kubectl describe pod -n production web-app-6d4b7c9f5-abcde
# Events:
#   Type     Reason     Age   From               Message
#   ----     ------     ----  ----               -------
#   Normal   Scheduled  5m    default-scheduler  Successfully assigned production/web-app-6d4b7c9f5-abcde to node-pool-1
#   Warning  Failed     5m    kubelet            Failed to pull image "myregistry.example.com/web-app:v1.25": rpc error: code = NotFound desc = failed to pull and unpack image: not found
#   Warning  Failed     4m    kubelet            Failed to pull image "myregistry.example.com/web-app:v1.25": rpc error: code = NotFound desc = failed to pull and unpack image: not found
#   Normal   Pulling    3m    kubelet            Pulling image "myregistry.example.com/web-app:v1.25"

L'événement indique not found. Cela signifie généralement que l'étiquette d'image n'existe pas dans le registre ou que le nom de l'image est mal orthographié. Avant de modifier quoi que ce soit, vérifiez la spécification du déploiement :

kubectl get deployment -n production web-app -o yaml | grep -A5 image
#       image: myregistry.example.com/web-app:v1.25
#       imagePullPolicy: Always

Comparez avec les étiquettes réellement présentes dans votre registre. Si l'étiquette correcte est v1.25.0, vous avez trouvé la cause racine. La correction est un changement d'une ligne, mais ne l'appliquez pas encore. Documentez l'état actuel, puis effectuez le changement.

Parallèle pratique : pour un déploiement avec de nombreux pods, utilisez kubectl get pods -n production -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[0].state}{"\n"}{end}' pour obtenir une vue compacte de l'état actuel de chaque pod.

Question rapide 1 sur 2

Selon le passage de référence, lequel des éléments suivants est cité comme un facteur pouvant empêcher un Deployment de terminer le déploiement de son ReplicaSet le plus récent ?

Le passage cite un quota insuffisant (ainsi que les échecs des readiness probes, les erreurs de pull d'image, les autorisations insuffisantes, les plages de limites et une mauvaise configuration de l'exécution de l'application) comme facteur pouvant bloquer un Deployment.

Chemin de configuration sûr

Une fois que vous avez identifié une cause racine probable, vous avez besoin d'un moyen sûr d'appliquer et de vérifier la correction. La règle d'or : effectuez le plus petit changement possible et vérifiez chaque étape. Ne regroupez pas plusieurs corrections dans un seul kubectl apply, car si quelque chose d'autre casse, vous ne saurez pas quel changement en est la cause.

Utilisation de kubectl edit ou kubectl apply

kubectl edit ouvre un objet vivant dans votre éditeur. C'est rapide mais dangereux car vous pouvez accidentellement modifier plusieurs champs. Une approche plus sûre consiste à exporter le YAML existant, à effectuer une modification contrôlée et à diffuser avant d'appliquer.

kubectl get deployment -n production web-app -o yaml > web-app-current.yaml
# Modifiez web-app-current.yaml pour changer l'étiquette de l'image
kubectl diff -f web-app-current.yaml
# -  image: myregistry.example.com/web-app:v1.25
# +  image: myregistry.example.com/web-app:v1.25.0

La sortie de kubectl diff montre exactement ce qui va changer. Si cela semble correct, appliquez :

kubectl apply -f web-app-current.yaml
# deployment.apps/web-app configured

Ensuite, surveillez le déploiement :

kubectl rollout status deployment/web-app -n production
# Waiting for deployment "web-app" rollout to finish: 0 of 3 updated replicas are available...
# deployment "web-app" successfully rolled out

Si le déploiement ne réussit pas, ne l'ignorez pas. Enquêtez sur les nouveaux pods. kubectl rollout status restera bloqué ou expirera ; vous pouvez utiliser --timeout=1m pour éviter un blocage indéfini.

Déploiement progressif avec maxSurge et maxUnavailable

Par défaut, Kubernetes peut remplacer tous les pods à la fois selon votre stratégie. Pour limiter le rayon d'impact, configurez une stratégie RollingUpdate avec maxSurge: 1 et maxUnavailable: 0. Cela garantit qu'au plus un pod supplémentaire est créé et qu'aucun ancien pod n'est terminé avant que les nouveaux ne soient prêts.

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

C'est particulièrement utile lors de l'annulation d'un mauvais changement. Vous pouvez mettre en pause le déploiement si vous soupçonnez un problème :

kubectl rollout pause deployment/web-app -n production
# deployment.apps/web-app paused

Pendant la pause, inspectez les nouveaux pods, exécutez des tests de fumée, puis reprenez :

kubectl rollout resume deployment/web-app -n production
# deployment.apps/web-app resumed

Protection des secrets et de la configuration

Ne codez jamais de secrets en dur dans la spécification du déploiement. Utilisez des variables d'environnement provenant d'un Secret ou d'une ConfigMap. Par exemple :

env:
  - name: DATABASE_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: password

Avant d'appliquer tout changement, assurez-vous de ne pas exposer de secrets dans les journaux ou les manifestes. Utilisez kubectl get secret db-secret -o yaml pour vérifier que le secret existe, mais n'imprimez pas ses valeurs dans la documentation.

Vérification et diagnostics

Après avoir appliqué une correction, de nombreux ingénieurs supposent que le problème est résolu si le pod est en cours d'exécution. C'est insuffisant. Vous devez vérifier que l'application est saine et sert le trafic correctement.

Sondes de disponibilité et de vivacité

Un pod peut être Running mais ne pas être prêt à recevoir du trafic. Kubernetes utilise des sondes de disponibilité (readiness probes) pour déterminer quand ajouter un pod aux points de terminaison d'un service. Si votre déploiement n'a pas de sonde de disponibilité, le pod est considéré comme prêt dès que son conteneur démarre, ce qui peut être trop tôt.

Exemple de sonde de disponibilité HTTP :

readinessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 3

Vérifiez l'état de la sonde avec kubectl describe pod :

kubectl describe pod web-app-6d4b7c9f5-new123 -n production
# Events:
#   Type     Reason     Age   From               Message
#   ----     ------     ----  ----               -------
#   Warning  Unhealthy  5s    kubelet            Readiness probe failed: HTTP probe failed with statuscode: 503

Un code 503 signifie que l'application n'est pas prête, même si le conteneur fonctionne. Enquêtez sur les journaux de l'application.

Vérification des journaux des pods

Utilisez kubectl logs pour inspecter la sortie actuelle du conteneur :

kubectl logs web-app-6d4b7c9f5-new123 -n production --tail=50

Si le conteneur est en boucle de crash, utilisez --previous pour obtenir les journaux du dernier conteneur terminé :

kubectl logs web-app-6d4b7c9f5-new123 -n production --previous

Cherchez des traces de pile, des erreurs de connexion ou des problèmes de configuration. Par exemple, une erreur courante est Exception in thread "main" java.net.UnknownHostException: db-service. Cela indique que l'application ne peut pas résoudre le nom du service de base de données, généralement parce que le service n'existe pas ou que l'application utilise le mauvais espace de noms.

Vérification de bout en bout avec Service et transfert de port

Ne vérifiez pas seulement les pods ; vérifiez qu'un service peut acheminer vers eux. Listez les points de terminaison du service :

kubectl get endpoints web-app -n production
# NAME        ENDPOINTS                                         AGE
# web-app     10.244.1.5:8080,10.244.2.6:8080,10.244.3.7:8080   20m

Si ENDPOINTS est vide, le sélecteur du service ne correspond pas aux étiquettes des pods. Vérifiez le sélecteur du service et les étiquettes des pods :

kubectl get svc web-app -n production -o jsonpath='{.spec.selector}'
# {"app":"web-app"}

kubectl get pods -n production -l app=web-app --show-labels
# NAME                      READY   STATUS    RESTARTS   AGE   LABELS
# web-app-6d4b7c9f5-new123   1/1     Running   0          2m    app=web-app,pod-template-hash=6d4b7c9f5

Elles correspondent, mais les points de terminaison peuvent être vides si les pods ne sont pas prêts. Assurez-vous que les sondes de disponibilité passent.

Pour un test manuel rapide, utilisez le transfert de port pour accéder directement à un pod :

kubectl port-forward pod/web-app-6d4b7c9f5-new123 8080:8080 -n production
# Forwarding from 127.0.0.1:8080 -> 8080

Ensuite, interrogez le point de terminaison de santé :

curl http://localhost:8080/healthz
# OK

Modes de défaillance et récupération

Les déploiements échouent de manière prévisible. Connaître ces schémas vous permet de récupérer plus rapidement.

ImagePullBackOff

Cause : L'image n'existe pas, le registre est inaccessible, les informations d'identification sont incorrectes ou la politique de tirage d'image est mauvaise. Le pod affiche ImagePullBackOff ou ErrImagePull.

Diagnostic :

kubectl describe pod <pod-name> -n <namespace>

Cherchez des événements comme Failed to pull image ... not found ou unauthorized: authentication required.

Correction :

  • Vérifiez le nom et l'étiquette de l'image.
  • Vérifiez la connectivité au registre depuis le nœud.
  • Assurez-vous que le secret de tirage d'image est présent et correctement référencé.
  • Pour les images publiques, testez avec docker pull ou crictl pull sur le nœud.

Récupération : Corrigez la spécification de l'image et appliquez. Kubernetes réessaiera automatiquement après la période de recul.

CrashLoopBackOff

Cause : Le conteneur démarre puis se termine avec un code non nul. Les raisons incluent une mauvaise configuration de l'application, des dépendances manquantes ou des sondes défaillantes.

Diagnostic :

kubectl describe pod <pod-name> -n <namespace>
# Last State:     Terminated
#   Reason:       Error
#   Exit Code:    1

Vérifiez les journaux :

kubectl logs <pod-name> -n <namespace> --previous

Correction :

  • Examinez le démarrage de l'application. Nécessite-t-elle une base de données qui n'est pas prête ?
  • Vérifiez les variables d'environnement et les ConfigMaps montées.
  • Ajustez les délais de la sonde de vivacité si l'application démarre lentement.

Récupération : Après correction, supprimez le pod pour forcer un nouveau (ne supprimez pas le déploiement) :

kubectl delete pod <pod-name> -n <namespace>

Pods en attente (non planifiables)

Cause : Ressources insuffisantes (CPU, mémoire, GPU), sélecteurs de nœuds ou règles d'affinité impossibles à satisfaire, ou inadéquation entre les teintures et les tolérances.

Diagnostic :

kubectl describe pod <pod-name> -n <namespace>
# Events:
#   Warning  FailedScheduling  2m   default-scheduler  0/3 nodes are available: 3 Insufficient memory.

Correction :

  • Réduisez les demandes de ressources ou augmentez la capacité du cluster.
  • Ajustez les sélecteurs de nœuds ou l'affinité.
  • Ajoutez les tolérances nécessaires.

Récupération : Mettez à jour la spécification du déploiement et appliquez. Les nouveaux pods devraient être planifiés.

Déploiement bloqué (ProgressDeadlineExceeded)

Cause : Le déploiement ne peut pas atteindre l'état souhaité dans le délai de progression (10 minutes par défaut). Souvent dû à des sondes de disponibilité défaillantes ou à des ressources insuffisantes.

Diagnostic :

kubectl rollout status deployment/<name> -n <namespace>
# error: deployment "web-app" exceeded its progress deadline

Inspectez le nouveau ReplicaSet :

kubectl describe rs <new-replica-set> -n <namespace>

Correction :

  • Corrigez le problème sous-jacent avec les nouveaux pods.
  • Si vous devez mettre en pause le déploiement, utilisez kubectl rollout pause.

Récupération : Si la nouvelle version est défectueuse, revenez à la révision précédente :

kubectl rollout undo deployment/web-app -n production
# deployment.apps/web-app rolled back

Ou revenez à une révision spécifique :

kubectl rollout undo deployment/web-app -n production --to-revision=2

Question rapide 2 sur 2

Quel champ de la spécification Deployment indique le nombre de secondes que le contrôleur Deployment attend avant d'indiquer que la progression du Deployment est bloquée ?

Le passage indique que .spec.progressDeadlineSeconds désigne le nombre de secondes que le contrôleur Deployment attend avant d'indiquer (dans le statut du Deployment) que la progression est bloquée.

Liste de contrôle des opérations

Utilisez cette liste avant et après tout changement de déploiement. Chaque élément nomme un responsable et la fréquence de révision.

  • [Responsable : ingénieur DevOps ; révision : après chaque changement] Capturez l'état actuel du déploiement : kubectl get deployment <name> -n <namespace> -o yaml > backup-$(date +%Y%m%d).yaml. Cela fournit une sauvegarde à un instant donné.
  • [Responsable : développeur d'application ; révision : avant chaque version] Vérifiez que l'image du conteneur existe et peut être tirée. Testez avec docker pull ou un appel à l'API du registre.
  • [Responsable : ingénieur DevOps ; révision : hebdomadaire] Vérifiez que le déploiement a des sondes de disponibilité et de vivacité valides. Utilisez kubectl get deployment <name> -n <namespace> -o jsonpath='{.spec.template.spec.containers[*].readinessProbe}' pour confirmer.
  • [Responsable : équipe plateforme ; révision : mensuelle] Passez en revue les demandes et limites de ressources par rapport à l'utilisation réelle. Utilisez kubectl top pods -n <namespace> et comparez avec resources.requests dans la spécification.
  • [Responsable : ingénieur DevOps ; révision : à chaque déploiement] Exécutez kubectl rollout status deployment/<name> --timeout=5m après l'application. En cas d'échec, enquêtez immédiatement plutôt que d'attendre.
  • [Responsable : responsable sécurité ; révision : trimestrielle] Auditez les registres d'images et les secrets de tirage. Assurez-vous qu'aucun secret n'est stocké en clair dans les manifestes de déploiement.
  • [Responsable : ingénieur DevOps ; révision : trimestrielle] Testez la procédure de retour en arrière : kubectl rollout undo deployment/<name> --to-revision=<previous> dans un environnement de préproduction.
  • [Responsable : développeur d'application ; révision : à chaque changement de code] Vérifiez les journaux de l'application pour les erreurs de démarrage en utilisant kubectl logs <pod> --previous après un crash.

Pièges courants et comment les éviter

Même les ingénieurs expérimentés commettent ces erreurs. Les reconnaître permet de gagner du temps et d'éviter les pannes.

1. Ne pas utiliser correctement les espaces de noms

Piège : Vous modifiez ou revenez en arrière sur un déploiement dans le mauvais espace de noms. C'est courant dans les clusters avec plusieurs environnements.

Évitement : Spécifiez toujours -n <namespace> dans chaque commande. Définissez votre contexte actuel avec kubectl config set-context --current --namespace=<namespace> si vous travaillez principalement dans un seul espace de noms.

Récupération : Si vous avez modifié un déploiement dans le mauvais espace de noms, annulez immédiatement le changement. Si vous avez une sauvegarde, restaurez-la. Sinon, vérifiez l'historique des déploiements et revenez à la révision précédente.

2. Ignorer les budgets de perturbation des pods

Piège : Vous réduisez ou supprimez des pods pendant la maintenance sans tenir compte d'un budget de perturbation des pods (PDB). Cela peut entraîner des temps d'arrêt imprévus ou une violation des SLO.

Évitement : Avant toute perturbation volontaire, vérifiez les PDB : kubectl get pdb -n <namespace>. Respectez les paramètres minAvailable ou maxUnavailable.

Récupération : Si vous avez violé un PDB, redimensionnez le déploiement pour respecter le budget et assurez-vous de ne pas planifier d'autres perturbations jusqu'à la récupération.

3. Écraser les correctifs manuels avec kubectl apply

Piège : Vous modifiez manuellement un champ avec kubectl edit ou kubectl patch, puis votre pipeline CI/CD applique un ancien manifeste qui écrase votre changement.

Évitement : Stockez le manifeste canonique dans le contrôle de version et effectuez les modifications là-bas. Utilisez kubectl apply --server-side ou kubectl replace avec prudence, en comprenant les implications. Assurez-vous que le CI/CD utilise le bon manifeste.

Récupération : Si un changement a été écrasé, réappliquez le correctif. Mieux, corrigez le manifeste source et redéployez.

4. Mal configurer les paramètres de mise à jour progressive

Piège : Définir maxUnavailable: 3 sur un déploiement à 3 répliques entraîne la terminaison de tous les pods avant que les nouveaux ne démarrent, provoquant un temps d'arrêt.

Évitement : Utilisez maxUnavailable: 0 et maxSurge: 1 pour des mises à jour progressives sans interruption. Cela garantit que les anciens pods restent jusqu'à ce que les nouveaux soient prêts.

Récupération : Si vous avez déjà provoqué un temps d'arrêt, le déploiement finira par se terminer si les nouveaux pods sont sains ; sinon, revenez à la version précédente.

5. Oublier de mettre à jour les sondes de santé avec les changements d'application

Piège : Vous modifiez le chemin ou le port du point de terminaison de santé de l'application mais oubliez de mettre à jour la sonde de disponibilité. Les pods ne deviennent jamais prêts.

Évitement : Traitez les configurations de sonde comme faisant partie de la définition de l'application. Testez les sondes en préproduction avant la production. Utilisez des variables d'environnement ou des chemins cohérents.

Récupération : Mettez à jour le chemin/port de la sonde dans la spécification du déploiement et appliquez. Les nouveaux pods passeront les sondes.

6. Négliger la mutabilité des étiquettes d'image

Piège : Utiliser l'étiquette latest ou une étiquette mutable comme v1 peut entraîner des changements d'image inattendus. Lorsqu'une nouvelle image est poussée avec la même étiquette, une mise à jour progressive peut tirer des versions différentes pour différents pods.

Évitement : Utilisez des étiquettes immuables comme v1.25.0 ou un SHA de commit. Activez l'immutabilité des étiquettes dans votre registre si disponible.

Récupération : Si des versions incohérentes sont en cours d'exécution, définissez l'image sur une étiquette immuable spécifique et déclenchez une mise à jour progressive.

Conclusion

Les erreurs de déploiement Kubernetes sont inévitables, mais elles ne doivent pas être stressantes. Une approche systématique – inventaire, diagnostic, changement minimal, vérification et récupération – transforme un incident chaotique en opération de routine. Les commandes et les schémas de cet article vous donnent les outils pour gérer les modes de défaillance les plus courants en toute sécurité.

Commencez par appliquer une nouvelle pratique : peut-être ajouter une sonde de disponibilité là où elle manque, ou utiliser kubectl diff avant d'appliquer des changements. Documentez votre état actuel, exécutez la vérification documentée et comparez le résultat avec la sortie attendue. Examinez les dépendances telles que les ReplicaSets, les pods et les autoscalers horizontaux de pods lorsqu'ils affectent le comportement de votre déploiement.

Un flux de travail fiable rend les échecs visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de la récupération avant qu'un incident ne force la décision. Votre cluster sera plus stable et votre équipe dormira mieux.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO