
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 debug d'un Pod suit toujours la même progression, et la sauter coûte du temps plutôt que d'en gagner. La raison est que chaque phase produit l'information dont la suivante a besoin : sans avoir lu l'état et les événements, vous ne savez pas quel conteneur inspecter ni quels logs demander. Les quatre étapes ci-dessous structurent tout le reste du guide.
- 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 »Ce tableau se lit par la colonne de gauche, celle du symptôme observé, et
donne les deux commandes à lancer dans cet ordre. L'ordre n'est pas
interchangeable : sur un CrashLoopBackOff, kubectl logs --previous vient
avant describe parce que le conteneur courant n'a peut-être pas encore
produit de logs, alors que l'instance précédente en a laissé. Si les deux
commandes ne suffisent pas, la section correspondante plus bas détaille le
diagnostic.
| 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:1.36 | 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:v0.9 --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 »La syntaxe reprend celle de scp : la source vient en premier, la destination
ensuite, et le pod se désigne par pod:/chemin. Une limite à connaître avant de
l'utiliser en incident, détaillée juste après : la commande s'appuie sur tar
présent dans le conteneur distant, ce qui la rend inopérante sur les images
minimales. Évitez également de récupérer un fichier volumineux d'un pod en
production, la copie transite par le serveur d'API.
# 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 en temps réel nécessite metrics-server installé dans le cluster. C'est un prérequis courant à l'examen CKAD.
Vérifier que metrics-server est présent :
kubectl get pods -n kube-system | grep metrics-serverkubectl top nodes # Si metrics-server est absent : "error: Metrics API not available"Installer metrics-server si absent (environnements de test) :
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.9.0/components.yaml# Attendre la disponibilité (30-60 secondes)kubectl rollout status deployment/metrics-server -n kube-systemCommandes utiles :
# Pods du namespace courantkubectl top pods
# Tous les Pods (tous les namespaces)kubectl top pods -A
# Nœudskubectl top nodes
# Trier par mémoire décroissantekubectl top pods --sort-by=memory
# Trier par CPU décroissantekubectl top pods --sort-by=cpu
# Un Pod avec détail par conteneurkubectl top pod mon-pod --containersExemple de sortie et interprétation :
NAME CPU(cores) MEMORY(bytes)api 234m 128Miworker 12m 64Midb 890m 512MiLa colonne CPU est en millicores (1000m = 1 vCPU). Un Pod qui consomme 890m CPU alors que sa requests est à 500m mais sa limit à 1000m fonctionne mais approche la limite, risque de throttling. Pour la mémoire, si la consommation dépasse la limit, le Pod est tué en OOMKilled.
Corréler avec requests/limits :
# Comparer consommation réelle vs limits définieskubectl get pod mon-pod -o=jsonpath='{.spec.containers[*].resources}' | jqkubectl 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. Le Pod est
correctement programmé sur un nœud, mais le kubelet échoue à récupérer
l'image auprès du registry et réessaie avec un délai croissant. La cause exacte
figure toujours dans le message de l'événement, il faut donc le lire en entier :
un manifest unknown désigne un tag inexistant, un unauthorized un problème
d'identifiants, un toomanyrequests un quota atteint.
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. Contrairement aux deux cas
précédents, aucun conteneur n'a démarré : le Pod n'a pas encore de nœud, c'est
l'ordonnanceur qui refuse de le placer. Le message de l'événement
FailedScheduling indique combien de nœuds ont été évalués et pourquoi chacun
a été écarté, sous la forme 0/3 nodes are available: .... Cette phrase
contient à elle seule la réponse dans la grande majorité des cas.
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. C'est le noyau du
nœud, et non Kubernetes, qui met fin au processus dès que le conteneur dépasse
sa limits.memory. L'arrêt est immédiat et sans avertissement, l'application
n'a aucune chance de se fermer proprement. Deux conséquences pour le
diagnostic : les logs s'arrêtent net au milieu d'une opération, et le seul
endroit qui nomme la cause est le champ Last State de describe, pas les
journaux applicatifs.
# 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 »Cette étape sert à couper le problème en deux. kubectl port-forward établit un
tunnel direct vers le pod, en contournant totalement le Service, le
kube-proxy et les éventuelles NetworkPolicies. Le verdict est donc net :
si le pod répond ici, l'application va bien et le problème est dans la chaîne
réseau ; s'il ne répond pas, inutile d'inspecter le Service.
# 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 »Les deux premières étapes ont testé depuis votre poste, ce qui ne reproduit pas
les conditions réelles : à l'intérieur du cluster, la résolution DNS passe par
CoreDNS et le trafic peut être filtré par des NetworkPolicies. Lancer un pod
jetable dans le même namespace place le test dans les mêmes conditions que
l'application appelante. Commencez toujours par nslookup : un nom de service
qui ne résout pas explique à lui seul l'échec des tests suivants.
# Lancer un Pod de debug avec des outils réseaukubectl run debug-net --rm -it --image=nicolaka/netshoot:v0.9 -- /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:v0.9 --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 »Cette séquence reprend dans l'ordre les commandes des sections précédentes. Elle part du plus large pour resserrer progressivement, et chaque étape sert à décider si la suivante est utile. Dans la pratique, une panne sur trois se résout dès l'étape 2, à la lecture des Events : ne sautez pas directement à l'investigation interactive, elle coûte du temps et ne dit rien sur les problèmes d'orchestration.
-
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:v0.9 --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 »Ces cinq règles ne concernent pas le debug lui-même mais ce qui le rend
possible. Une application qui écrit ses journaux dans un fichier interne au
conteneur est invisible pour kubectl logs, et une application sans requests
déclarées empêche l'ordonnanceur de raisonner. Les deux premières lignes sont
celles qui changent le plus la vie en incident.
- 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 »Ces quatre réflexes portent sur votre méthode plutôt que sur les commandes. Le plus rentable est le premier : les Events répondent souvent en une ligne à une question que les logs applicatifs ne peuvent pas trancher, parce qu'ils décrivent ce que Kubernetes a tenté, pas ce que l'application a fait. Retenez aussi que les Events ont une durée de vie limitée, une heure par défaut : au-delà, seule une centralisation des journaux conserve la trace.
- 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 épinglée,
nicolaka/netshoot:v0.9oubusybox:1.36pour les cas difficiles - Centralisez les logs, Loki, Elasticsearch, CloudWatch pour l'historique
Réflexes CKAD
Section intitulée « Réflexes CKAD »L'examen CKAD est chronométré, ce qui change la méthode : vous n'avez pas le temps d'explorer, il faut une séquence déjà mémorisée. Les six réflexes ci-dessous sont volontairement réduits à leur forme la plus courte, sans options superflues. Entraînez-vous à les taper sans réfléchir ; le temps gagné là se reporte sur les questions de configuration, qui rapportent davantage de points.
-
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:1.36 --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:1.36 --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.
Testez vos connaissances
Section intitulée « Testez vos connaissances »Ce questionnaire porte sur les situations traitées dans le guide : lecture d'un
état de pod, choix de la commande adaptée à un symptôme, interprétation d'un
code de sortie. Les questions sur --previous et sur la distinction entre
describe et get events sont celles qui révèlent le mieux les points à
relire.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Troubleshooting cluster : Le diagnostic quand la panne vient du cluster et non de l'application.
- Méthode de diagnostic d'un incident : Une démarche en quatre niveaux pour ne plus chercher au hasard.
- Diagnostiquer un CrashLoopBackOff : Le cas le plus fréquent en production, traité de bout en bout.