
Kubernetes offre plusieurs outils de diagnostic intégrés. Vous utiliserez principalement kubectl logs pour les erreurs applicatives, kubectl describe et kubectl get events pour les problèmes d’orchestration, et kubectl exec ou kubectl debug pour l’investigation interactive. Ce guide vous montre comment combiner ces outils efficacement.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Diagnostiquer avec
kubectl get,kubectl describeetkubectl get events - Analyser les logs avec
kubectl logs - Exécuter des commandes avec
kubectl exec - Utiliser les conteneurs éphémères (
kubectl debug) - Investiguer les problèmes réseau et de service
- Résoudre les erreurs courantes (CrashLoopBackOff, ImagePullBackOff, OOMKilled, Pending)
Philosophie du debug Kubernetes
Section intitulée « Philosophie du debug Kubernetes »Le debugging suit une progression logique :
- Observer — Quel est l’état actuel du Pod, des événements ?
- Comprendre — Pourquoi cet état ? Logs, conditions, exit codes
- Investiguer — Plonger dans le conteneur si nécessaire
- Corriger — Appliquer la solution et vérifier
Tableau de décision rapide
Section intitulée « Tableau de décision rapide »| Symptôme | Première commande | Deuxième commande |
|---|---|---|
Pod en CrashLoopBackOff | kubectl logs --previous | kubectl describe pod |
Pod en Pending | kubectl describe pod | kubectl get events |
Pod Running mais application KO | kubectl logs | kubectl port-forward / debug réseau |
| Image minimale sans shell | kubectl debug --image=busybox | ps, ss, nslookup, curl |
| Suspicion OOM | kubectl describe pod | kubectl top pod |
| Problème de Service | kubectl get endpoints | kubectl port-forward pod |
Commandes essentielles
Section intitulée « Commandes essentielles »kubectl get — Vue globale
Section intitulée « kubectl get — Vue globale »Première commande pour voir l’état de vos ressources :
# État des Pods dans un namespacekubectl get pods -n mon-namespace
# État de TOUS les Pods du clusterkubectl get pods -A
# Plus de détails (node, IP)kubectl get pods -o wide
# Rafraîchissement continukubectl get pods -wExemple de sortie :
NAME READY STATUS RESTARTS AGEapp-healthy 1/1 Running 0 2happ-crashloop 0/1 CrashLoopBackOff 5 (30s ago) 3mapp-pending 0/1 Pending 0 5mkubectl get events — Vue chronologique
Section intitulée « kubectl get events — Vue chronologique »Commande sous-estimée mais extrêmement utile. Les événements donnent une vue chronologique de ce qui s’est passé :
# Événements du namespace courant, triés par datekubectl get events --sort-by=.lastTimestamp
# Événements de tous les namespaceskubectl get events -A --sort-by=.lastTimestamp
# Événements d'un namespace spécifiquekubectl get events -n mon-namespace --sort-by=.lastTimestampExemple de sortie :
LAST SEEN TYPE REASON OBJECT MESSAGE2m Warning FailedScheduling pod/app-pending 0/3 nodes are available: 3 Insufficient memory3m Normal Pulling pod/app-new Pulling image "nginx:1.25"5m Warning BackOff pod/app-crashloop Back-off restarting failed containerkubectl describe — Analyse détaillée
Section intitulée « kubectl describe — Analyse détaillée »Pour comprendre pourquoi un Pod est dans un état donné :
kubectl describe pod mon-podSections clés à examiner :
| Section | Information |
|---|---|
| Status | État actuel du Pod |
| Conditions | Ready, Initialized, ContainersReady, PodScheduled |
| Containers | État de chaque conteneur, codes de sortie, raison |
| Events | Historique chronologique des actions sur ce Pod |
kubectl logs — Logs applicatifs
Section intitulée « kubectl logs — Logs applicatifs »kubectl logs lit les logs via le kubelet sur le nœud, à partir des fichiers de logs du conteneur. C’est pourquoi votre application doit écrire vers stdout et stderr.
# Logs d'un Pod (conteneur unique)kubectl logs mon-pod
# Logs d'un conteneur spécifique (Pod multi-conteneurs)kubectl logs mon-pod -c mon-conteneur
# Dernières 100 ligneskubectl logs mon-pod --tail=100
# Logs en temps réelkubectl logs mon-pod -f
# Logs de l'instance précédente du conteneur (après crash)kubectl logs mon-pod --previouskubectl exec — Accès interactif
Section intitulée « kubectl exec — Accès interactif »Pour exécuter des commandes dans un conteneur en cours d’exécution :
# Commande uniquekubectl exec mon-pod -- ls -la /app
# Shell interactifkubectl exec -it mon-pod -- /bin/sh
# Avec conteneur spécifique (Pod multi-conteneurs)kubectl exec -it mon-pod -c sidecar -- /bin/bashkubectl debug — Conteneurs éphémères
Section intitulée « kubectl debug — Conteneurs éphémères »Les conteneurs éphémères sont stables depuis Kubernetes v1.25. Ils permettent d’injecter un conteneur de debug temporaire dans un Pod existant :
# Ajouter un conteneur éphémère basiquekubectl debug mon-pod -it --image=busybox:1.36 --target=app
# Avec des outils réseau completskubectl debug mon-pod -it --image=nicolaka/netshoot --target=appExemple pratique dans le conteneur de debug :
# Voir les processus du conteneur cibleps aux
# Variables d'environnement du processus principalcat /proc/1/environ | tr '\0' '\n'
# Ports en écoutess -tlnp
# Test de connectivité réseaucurl -v http://mon-service:8080/healthkubectl cp — Copier des fichiers
Section intitulée « kubectl cp — Copier des fichiers »# Pod → Localkubectl cp mon-pod:/app/logs/error.log ./error.log
# Local → Podkubectl cp ./config.yaml mon-pod:/app/config.yaml
# Avec conteneur spécifiquekubectl cp mon-pod:/app/dump.txt ./dump.txt -c appkubectl top — Métriques instantanées
Section intitulée « kubectl top — Métriques instantanées »Voir la consommation CPU/mémoire (nécessite metrics-server installé) :
# Pods du namespace courantkubectl top pods
# Tous les Podskubectl top pods -A
# Nœudskubectl top nodes
# Tri par mémoirekubectl top pods --sort-by=memory
# Un Pod spécifique avec ses conteneurskubectl top pod mon-pod --containerskubectl port-forward — Accès direct
Section intitulée « kubectl port-forward — Accès direct »Accédez à un Pod ou Service sans exposition externe :
# Vers un Podkubectl port-forward mon-pod 8080:80
# Vers un Servicekubectl port-forward svc/mon-service 8080:80
# En arrière-plankubectl port-forward mon-pod 8080:80 &Utile pour tester si le Pod répond indépendamment du Service.
Erreurs courantes et solutions
Section intitulée « Erreurs courantes et solutions »CrashLoopBackOff
Section intitulée « CrashLoopBackOff »Symptôme : Le conteneur démarre, crash, redémarre en boucle.
-
Vérifiez les logs du crash précédent
Fenêtre de terminal kubectl logs mon-pod --previous -
Examinez le code de sortie et la raison
Fenêtre de terminal kubectl describe pod mon-pod | grep -A10 "Last State" -
Interprétez le code de sortie
Code Signification 0 Sortie normale (mais Pod censé tourner → vérifiez la commande) 1 Erreur applicative générique 137 Processus tué par SIGKILL (souvent OOM — confirmez avec describe)143 SIGTERM reçu (arrêt propre demandé) -
Appliquez la solution
- Code 1 : Corrigez le bug applicatif (voir logs)
- Code 137 + OOMKilled : Augmentez
resources.limits.memory - Sortie immédiate (code 0) : Vérifiez la commande/entrypoint
ImagePullBackOff
Section intitulée « ImagePullBackOff »Symptôme : Kubernetes ne peut pas télécharger l’image.
kubectl describe pod mon-pod | grep -A10 Eventskubectl get events --field-selector involvedObject.name=mon-pod| Cause | Solution |
|---|---|
| Image inexistante | Vérifiez le nom et le tag exact |
| Registry privé | Créez un imagePullSecret et référencez-le |
| Quota Docker Hub | Authentifiez-vous ou utilisez un registry privé |
| Erreur réseau | Vérifiez la connectivité du nœud vers le registry |
Symptôme : Le Pod reste en Pending indéfiniment.
kubectl describe pod mon-pod | grep -A20 Eventskubectl get events -A --sort-by=.lastTimestamp | grep -i scheduling| Cause | Solution |
|---|---|
Insufficient cpu/memory | Réduisez les requests ou ajoutez des nœuds |
No nodes match nodeSelector | Vérifiez les labels des nœuds |
Taints not tolerated | Ajoutez les tolerations nécessaires |
PVC pending | Vérifiez le PVC et le StorageClass |
OOMKilled
Section intitulée « OOMKilled »Symptôme : Conteneur tué pour surconsommation mémoire.
# Vérifier l'état du conteneurkubectl describe pod mon-pod | grep -A5 "Last State"
# Chercher OOMKilled explicitementkubectl describe pod mon-pod | grep -i oom
# Voir la consommation actuellekubectl top pod mon-pod --containersSolutions :
- Augmentez
resources.limits.memory - Analysez les fuites mémoire de l’application
- Ajoutez du monitoring pour détecter la tendance avant le crash
Pod Running mais application inaccessible
Section intitulée « Pod Running mais application inaccessible »C’est un cas très fréquent : le Pod est Running, mais l’application ne répond pas.
Étape 1 : Vérifiez que le Pod répond directement
Section intitulée « Étape 1 : Vérifiez que le Pod répond directement »# Accès direct au Pod, contournant le Servicekubectl port-forward mon-pod 8080:80# Dans un autre terminalcurl http://localhost:8080/healthSi le Pod répond : le problème vient du Service ou du réseau. Si le Pod ne répond pas : le problème est applicatif.
Étape 2 : Vérifiez le Service et les Endpoints
Section intitulée « Étape 2 : Vérifiez le Service et les Endpoints »# Voir le Servicekubectl get svc mon-service -o wide
# Vérifier que le Service a des endpointskubectl get endpoints mon-service
# Ou avec EndpointSlices (Kubernetes moderne)kubectl get endpointslices -l kubernetes.io/service-name=mon-serviceEndpoints vides ? Le selector du Service ne matche aucun Pod. Vérifiez les labels :
# Labels du Service (selector)kubectl get svc mon-service -o jsonpath='{.spec.selector}'
# Labels des Podskubectl get pods --show-labelsÉtape 3 : Testez la connectivité depuis un autre Pod
Section intitulée « Étape 3 : Testez la connectivité depuis un autre Pod »# Lancer un Pod de debug avec des outils réseaukubectl run debug-net --rm -it --image=nicolaka/netshoot -- /bin/bash
# Dans le Pod de debugnslookup mon-servicecurl -v http://mon-service:80/healthnc -zv mon-service 80Debug avec images minimales
Section intitulée « Debug avec images minimales »Quand kubectl exec échoue faute de shell (distroless, scratch), voici le workflow :
-
Lancez un conteneur éphémère avec une image de debug
Fenêtre de terminal kubectl debug mon-pod -it --image=nicolaka/netshoot --target=app -
Explorez le conteneur cible
Fenêtre de terminal # Processusps aux# Variables d'environnementcat /proc/1/environ | tr '\0' '\n'# Fichiers ouvertsls -la /proc/1/fd/ -
Testez le réseau
Fenêtre de terminal # Résolution DNSnslookup kubernetes.defaultnslookup mon-service.mon-namespace.svc.cluster.local# Connectivité TCPnc -zv mon-service 80# Test HTTPcurl -v http://mon-service:80/health# Ports en écoute dans le conteneur cibless -tlnp# Routes réseauip route -
Vérifiez les volumes montés
Fenêtre de terminal mount | grep -v "cgroup\|proc\|sys"cat /etc/resolv.conf
Workflow de debug complet
Section intitulée « Workflow de debug complet »-
Vue globale
Fenêtre de terminal kubectl get pods -A | grep -v Runningkubectl get events -A --sort-by=.lastTimestamp | head -20 -
Cibler le Pod problématique
Fenêtre de terminal kubectl describe pod mon-pod -
Logs applicatifs
Fenêtre de terminal kubectl logs mon-pod --tail=100# Si crash récentkubectl logs mon-pod --previous -
Investigation interactive
Fenêtre de terminal # Si shell disponiblekubectl exec -it mon-pod -- /bin/sh# Sinonkubectl debug mon-pod -it --image=nicolaka/netshoot --target=app -
Vérification réseau/service
Fenêtre de terminal kubectl port-forward mon-pod 8080:80kubectl get endpoints mon-service -
Métriques
Fenêtre de terminal kubectl top pod mon-pod --containers
Bonnes pratiques
Section intitulée « Bonnes pratiques »Pour vos applications
Section intitulée « Pour vos applications »- Loguez vers stdout/stderr — Kubernetes capture automatiquement via le kubelet
- Implémentez des health endpoints —
/health,/readypour les probes - Définissez des ressources — Évite les OOMKilled silencieux et les Pending
- Utilisez des labels cohérents — Facilite le filtrage (
kubectl get pods -l app=api) - Gérez SIGTERM proprement — Arrêt gracieux pour les rolling updates
Pour le debug
Section intitulée « Pour le debug »- Commencez par
get events— Vue chronologique de ce qui s’est passé - Utilisez
-A/--all-namespaces— Quand vous ne savez pas où est le problème - Gardez une image de debug —
nicolaka/netshootoubusyboxpour les cas difficiles - Centralisez les logs — Loki, Elasticsearch, CloudWatch pour l’historique
Réflexes CKAD
Section intitulée « Réflexes CKAD »-
Vue globale rapide
Fenêtre de terminal kubectl get pods -Akubectl get events -A --sort-by=.lastTimestamp -
Diagnostic d’un Pod
Fenêtre de terminal kubectl describe pod <pod>kubectl logs <pod> --previous -
Investigation interactive
Fenêtre de terminal kubectl exec -it <pod> -- /bin/sh -
Test de connectivité
Fenêtre de terminal kubectl port-forward <pod> 8080:80 -
Debug avancé (images minimales)
Fenêtre de terminal kubectl debug <pod> -it --image=busybox --target=<container> -
Vérifier les endpoints d’un Service
Fenêtre de terminal kubectl get endpoints <service>
À retenir
Section intitulée « À retenir »| Situation | Commande |
|---|---|
| Vue globale tous namespaces | kubectl get pods -A |
| Événements chronologiques | kubectl get events --sort-by=.lastTimestamp |
| Détails d’un Pod | kubectl describe pod |
| Logs applicatifs | kubectl logs [--previous] |
| Shell interactif | kubectl exec -it -- /bin/sh |
| Images minimales | kubectl debug --image=busybox --target=app |
| Test direct Pod | kubectl port-forward pod 8080:80 |
| Vérifier Service | kubectl get endpoints |
| Métriques instantanées | kubectl top pods |
| Copier des fichiers | kubectl cp (nécessite tar dans le conteneur) |
Le debugging Kubernetes suit toujours le même pattern : observer l’état global, lire les événements, analyser les logs, vérifier le réseau/service, investiguer interactivement si nécessaire.