Introduction
Kubernetes vous indique ce qui ne va pas, à condition de savoir où regarder. Ce guide associe les messages d'erreur courants à leurs causes racines, montre comment les diagnostiquer rapidement et propose des correctifs sûrs et minimaux. Vous apprendrez un workflow de dépannage reproductible, des commandes pratiques et de petites modifications YAML qui résolvent les problèmes sans conjectures risquées.
Public visé : développeurs, consultants DevOps et équipes techniques de startups qui exécutent des charges de travail sur Kubernetes et ont besoin de correctifs fiables et rapides.
Aperçu du workflow
Utilisez ce flux reproductible pour réduire le temps de résolution et éviter les conjectures :
- Capturer l'erreur et son périmètre
- Notez l'espace de noms, le type de charge de travail (Deployment, StatefulSet, Job) et le message exact.
- Prenez un instantané des événements récents pour ne pas perdre les détails transitoires :
kubectl get events -n <ns> --sort-by=.lastTimestamp | tail -n 50
- Inspecter l'objet
- Décrivez l'objet en échec et vérifiez les Conditions, avertissements et derniers temps de transition :
kubectl describe pod <pod> -n <ns>
kubectl describe deploy <name> -n <ns>
- Lire les journaux
- Consultez les journaux du conteneur courant et précédents. Le journal précédent montre le dernier crash :
kubectl logs <pod> -n <ns> -c <container>
kubectl logs <pod> -n <ns> -c <container> --previous --tail=200
- Valider les ressources et l'ordonnancement
- Recherchez des événements comme
Insufficient cpu/memory, des taints ou des sélecteurs de nœuds insatisfaisables :
kubectl get pod <pod> -n <ns> -o wide
kubectl describe pod <pod> -n <ns> | sed -n '/Events:/,$p'
- Vérifier le chemin réseau
- Confirmez l'existence des Endpoints et testez la connectivité intra-cluster :
kubectl get svc <svc> -n <ns>
kubectl get endpoints <svc> -n <ns>
- Privilégier les rollbacks sûrs
- En cas d'incident urgent, revenez à la dernière version connue fonctionnelle pendant le diagnostic :
kubectl rollout undo deploy/<name> -n <ns>
- Appliquer la plus petite modification
- Modifiez un seul paramètre à la fois et revérifiez les Events et la readiness.
- Confirmer le correctif
- Assurez-vous que les pods Ready restent stables plusieurs minutes et que les Services concernés ont des Endpoints :
kubectl get pods,svc,endpoints -n <ns> -o wide
Plan pilote local
Commencez petit pour obtenir des gains rapides et des résultats prévisibles :
- Périmètre : espace de noms non‑production uniquement (par exemple
ns=ops-pilot). Ciblez 3 à 5 types d'erreurs courants :ImagePullBackOff,CrashLoopBackOff, PVC en attente, Service sans Endpoints, RBAC forbidden. - Configuration : un Deployment exemple avec sondes liveness/readiness. Un Service et un Ingress optionnel (par exemple Nginx) pour tester l'accessibilité. Un PersistentVolumeClaim utilisant votre StorageClass par défaut (Ceph ou autre).
- Cibles et vérifications : suivez le temps de détection et le temps jusqu'à la première requête réussie après correctif. Utilisez
kubectl get eventsetkubectl describepour valider chaque résolution. - Garde-fous : utilisez
rollout undoavant toute modification profonde. Maintenez les patches minimaux et réversibles.
Ce pilote étroit et mesurable est facile à inspecter localement avant d'étendre.
Erreurs courantes et correctifs
Voici les erreurs à fort signal que vous rencontrerez en pratique. Chaque item explique pourquoi elle survient, comment la diagnostiquer et un correctif sûr.
1) CrashLoopBackOff
Pourquoi cela arrive
- Le conteneur démarre puis s'arrête. Causes fréquentes : mauvaise configuration, variables d'environnement manquantes, conteneurs d'initialisation en échec, ou sondes qui tuent le pod.
Diagnostiquer
kubectl describe pod <pod> -n <ns>
kubectl logs <pod> -n <ns> --previous --tail=200
Recherchez le code de sortie, les messages OOMKilled ou les échecs de sondes dans les Events.
Corriger
- Revenir en arrière si c'est une nouvelle version :
kubectl rollout undo deploy/<name> -n <ns>
- Si les sondes sont trop strictes, les assouplir temporairement le temps de corriger l'application :
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
- Vérifier que les variables d'environnement et fichiers de configuration requis existent (chemins de volumes ConfigMap/Secret, permissions de fichiers).
2) ImagePullBackOff / ErrImagePull
Pourquoi cela arrive
- Nom ou tag d'image incorrect, registre privé sans identifiants, ou conflit de
imagePullPolicy.
Diagnostiquer
kubectl describe pod <pod> -n <ns> | sed -n '/Events:/,$p'
Cherchez les messages HTTP 403/401 ou "not found\).
Corriger
- Corriger la référence d'image. Épinglez un tag connu stable :
containers:
- name: api
image: registry.example.com/team/api:v1.2.3
imagePullPolicy: IfNotPresent
- Créer un secret de pull pour le registre et l'attacher au ServiceAccount :
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=<user> \
--docker-password=<pass> \
--docker-email=<[email protected]> \
-n <ns>
kubectl patch serviceaccount default -n <ns> \
-p '{"imagePullSecrets":[{"name":"regcred"}]}'
3) Pod bloqué en Pending (Unschedulable)
Pourquoi cela arrive
- CPU/mémoire insuffisants, taints sur les nœuds, ou règles de sélecteurs/affinité trop strictes.
Diagnostiquer
kubectl describe pod <pod> -n <ns>
kubectl get nodes -o wide
kubectl describe node <node> | sed -n '/Taints:/,/Addresses:/p'
Vérifiez les Events pour Insufficient cpu ou memory. Examinez les labels et taints des nœuds.
Corriger
- Ajuster requests et limits :
kubectl set resources deploy/<name> -n <ns> \
--requests=cpu=100m,memory=128Mi \
--limits=cpu=500m,memory=512Mi
- Supprimer les sélecteurs de nœuds trop restrictifs ou ajouter des tolerations pour les taints requis.
- Étendre le pool de nœuds du cluster si la capacité est réellement épuisée.
4) PersistentVolumeClaim en attente ou MountVolume.SetUp Failed
Pourquoi cela arrive
- Aucun StorageClass par défaut, incompatibilité de mode d'accès (
ReadWriteOncevsReadWriteMany), taille non disponible, ou problèmes de pilote CSI (par exemple configuration Ceph).
Diagnostiquer
kubectl describe pvc <pvc> -n <ns>
kubectl get sc
Regardez les Events pour "no storage class configured" ou "failed to provision volume\)\)\.
Corriger
- Définir ou corriger le StorageClass :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes: ["ReadWriteOnce" ]
storageClassName: fast
resources:
requests:
storage: 10Gi
- Marquer un StorageClass comme défaut si nécessaire :
kubectl patch storageclass fast \
-p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
- Pour les montages bloqués, supprimez le Pod (pas le PVC) et laissez le contrôleur le recréer après l'attachement du volume.
5) Erreurs d'accès au Service (Connection Refused/Timeout)
Pourquoi cela arrive
- Le sélecteur du Service ne correspond pas aux labels des pods,
targetPortincorrect, pods pas Ready, ou NetworkPolicy qui bloque le trafic. Les mauvais routages Ingress/Nginx apparaissent aussi en 404 ou 502.
Diagnostiquer
kubectl get svc <svc> -n <ns> -o yaml | sed -n '1,80p'
kubectl get endpoints <svc> -n <ns>
Les Endpoints doivent lister les IPs et ports des pods. S'ils sont vides, le sélecteur est faux ou aucun pod n'est Ready.
Testez depuis l'intérieur du cluster :
kubectl run tmp-shell -n <ns> --rm -i --tty \
--image=busybox:1.36 --restart=Never -- sh
# dans le shell
wget -qO- http://<svc>.<ns>.svc.cluster.local:<port>/healthz || echo fail
Corriger
- Aligner labels et sélecteurs :
# labels du pod
metadata:
labels:
app: web
# sélecteur du service
spec:
selector:
app: web
- Faire correspondre le port du Service et le containerPort/targetPort. Utilisez un
targetPortnumérique pour éviter les mismatches de nom. - Si une NetworkPolicy bloque le trafic, mettez‑la à jour pour autoriser les namespaces et sélecteurs de pods nécessaires.
6) RBAC (Role‑Based Access Control) : Forbidden (User Does Not Have Access)
Pourquoi cela arrive
- L'utilisateur ou le ServiceAccount n'a pas les permissions pour la ressource, le verbe ou l'espace de noms.
Diagnostiquer
kubectl auth can-i get pods -n <ns> --as <user>
kubectl auth can-i create deployments.apps -n <ns> --as system:serviceaccount:<ns>:<sa>
Corriger
- Lier le Role ou ClusterRole approprié au sujet :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-ops
namespace: myns
rules:
- apiGroups: ["", "apps" ]
resources: ["pods", "deployments" ]
verbs: ["get", "list", "watch", "update", "patch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-ops-binding
namespace: myns
subjects:
- kind: ServiceAccount
name: app-sa
namespace: myns
roleRef:
kind: Role
name: app-ops
apiGroup: rbac.authorization.k8s.io
7) Erreurs Helm Install/Upgrade
Messages courants
- "rendered manifests contain a resource that already exists"
- "UPGRADE FAILED: another operation in progress"
Diagnostiquer
helm list -n <ns>
helm status <release> -n <ns>
helm history <release> -n <ns>
Si une ressource existe déjà d'un release égaré ou d'un apply manuel, identifiez quel release la possède via ses labels/annotations.
Corriger
- Si la dernière upgrade a cassé, faire un rollback :
helm rollback <release> <revision> -n <ns>
- Si une ressource existe en dehors du contrôle Helm, soit l'adopter en alignant soigneusement labels et annotations, soit la supprimer après confirmation qu'elle est sans risque, puis relancer l'install.
- Pour "another operation in progress", attendez que le lock se libère ou nettoyez les hooks échoués avant de réessayer.
8) Pod bloqué en Terminating
Pourquoi cela arrive
- Finalizers sur ressources attachées, hooks
preStopbloqués, ou volumes qui ne se démontent pas.
Diagnostiquer
kubectl describe pod <pod> -n <ns>
kubectl get pod <pod> -n <ns> -o jsonpath='{.metadata.finalizers}'
Corriger (progressif)
- Essayer une suppression normale et attendre un court délai :
kubectl delete pod <pod> -n <ns>
- Si un finalizer sur le pod lui‑même est bloqué et que vous êtes certain que le nettoyage est fait, le retirer :
kubectl patch pod <pod> -n <ns> -p '{"metadata":{"finalizers":[]}}'
- En dernier recours seulement, forcer la suppression :
kubectl delete pod <pod> -n <ns> --grace-period=0 --force
Investiguez et corrigez la cause sous‑jacente (par exemple démontage NFS/CSI lent ou preStop long) pour éviter la récurrence.
9) Node NotReady, problèmes d'ordonnancement et d'éviction
Pourquoi cela arrive
- Kubelet non sain, pression disque, pression mémoire, ou problèmes réseau/CNI (Container Network Interface) : interface réseau pour conteneurs.
Diagnostiquer
kubectl get nodes
kubectl describe node <node> | sed -n '/Conditions:/,/Addresses:/p'
Recherchez les conditions DiskPressure ou NetworkUnavailable.
Corriger
- Libérer de l'espace disque ou augmenter la taille du volume du nœud.
- Cordonner et drainer avant maintenance :
kubectl cordon <node>
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
- Après correction, uncordonner :
kubectl uncordon <node>
10) OOMKilled (Out Of Memory Killed) : tué par manque de mémoire et throttling CPU
Pourquoi cela arrive
- Limite mémoire trop basse (conteneur tué par OOM), ou requests CPU trop bas causant du throttling sous charge.
Diagnostiquer
kubectl describe pod <pod> -n <ns> | sed -n '/Containers:/,/Conditions:/p'
Cherchez Last State: Terminated reason=OOMKilled et la section Resources pour les requests/limits.
Corriger
- Définir des requests et limits réalistes basés sur l'usage observé :
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 1
memory: 512Mi
- Si la readiness flanche pendant le GC, augmenter le timeout et l'initialDelay de la sonde de readiness.
Extraits de diagnostic rapides
- Queue d'events pour un namespace :
kubectl get events -n <ns> --sort-by=.lastTimestamp | tail -n 100
- Lister les pods non‑Ready avec raisons :
kubectl get pods -A --field-selector=status.phase!=Running -o wide
- Afficher les Services sans Endpoints :
kubectl get svc -A | awk 'NR==1 || $4=="<none>"'
Conclusion
Des correctifs rapides et sûrs découlent d'un workflow clair, pas de conjectures. Commencez par un petit pilote local qui exerce quelques erreurs à fort impact. Pour chaque incident, confirmez le message exact, décrivez l'objet, lisez les logs, vérifiez les Events, et ne changez qu'une seule chose à la fois. Faites un rollback vite si nécessaire, et validez avec la readiness et les Endpoints. Une fois que votre équipe résout ces cas courants en toute confiance, étendez la couverture à plus de services et automatisez les vérifications que vous répétez le plus souvent.