Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Méthode de diagnostic d'un incident Kubernetes

16 min de lecture

logo kubernetes

Face à un incident Kubernetes, commencez toujours par le même réflexe : qualifier le niveau du problème — cluster, nœud, pod ou réseau — puis descendez méthodiquement. Ce guide vous donne une approche systématique en 4 niveaux avec les commandes kubectl adaptées à chaque situation. Vous pourrez localiser la cause d’un incident en quelques minutes au lieu de chercher au hasard.

  • Appliquer une méthode de triage en 4 niveaux : cluster → nœud → pod → réseau
  • Maîtriser les 4 commandes de diagnostic essentielles : get, describe, logs, events
  • Utiliser kubectl debug avec les conteneurs éphémères pour inspecter un pod en cours d’exécution
  • Diagnostiquer les problèmes de Service : DNS, EndpointSlices, kube-proxy

Sous pression, le réflexe naturel est de chercher directement dans les logs du pod suspect. C’est souvent une perte de temps : si le problème vient du nœud (disque plein, kubelet en panne) ou du réseau (Service mal configuré, DNS cassé), les logs du pod ne montreront rien d’utile.

Une méthode structurée permet de :

  • Éliminer rapidement les niveaux qui fonctionnent
  • Localiser la couche responsable avant de creuser
  • Communiquer clairement l’état du diagnostic à l’équipe
  • Reproduire la même démarche à chaque incident
NiveauQuestion à se poserCommandes principales
1. ClusterLe cluster est-il accessible et sain ?kubectl cluster-info, kubectl get nodes
2. NœudUn nœud est-il en difficulté ?kubectl describe node, kubectl top nodes
3. PodPourquoi ce pod ne fonctionne pas ?kubectl describe pod, kubectl logs, kubectl debug
4. RéseauLe trafic arrive-t-il au bon endroit ?kubectl get svc, kubectl get endpointslices, DNS check

La règle : commencer par le haut et descendre. Si le niveau 1 est sain, passer au 2. Si le 2 est sain, passer au 3, etc.

Avant toute chose, vérifiez que vous pouvez communiquer avec l’API server et que les nœuds sont opérationnels.

Fenêtre de terminal
kubectl cluster-info

Résultat attendu :

Kubernetes control plane is running at https://192.168.122.50:6443
CoreDNS is running at https://192.168.122.50:6443/api/v1/namespaces/kube-system/services/coredns:dns/proxy

Si cette commande échoue, le problème est en amont de Kubernetes : réseau, kubeconfig, VPN, certificat expiré. Vérifiez votre fichier ~/.kube/config et la connectivité réseau vers l’API server.

Fenêtre de terminal
kubectl get nodes
StatusSignificationAction
Tous ReadyLe cluster reste globalement accessible, mais cela ne suffit pas à exclure un problème control plane, kube-system ou réseau. Continuer le triage selon le symptômeVérifier kube-system et /readyz
Un nœud NotReadyProblème sur ce nœud → passer au niveau 2Inspecter le nœud
Un nœud SchedulingDisabledMaintenance en cours (cordon)Normal si planifié
Aucune réponseAPI server injoignableVérifier le plan de contrôle
Fenêtre de terminal
kubectl get pods -n kube-system -o wide

Vérifiez que etcd, kube-apiserver, kube-controller-manager et kube-scheduler sont en état Running avec RESTARTS à 0 (ou très faible).

Pour un diagnostic plus fin :

Fenêtre de terminal
kubectl get --raw='/readyz?verbose' | grep -E '\[(\+|\-)\]'

Chaque ligne [+] confirme un sous-système fonctionnel. Une ligne [-] signale un composant en échec.

Si un nœud est NotReady ou SchedulingDisabled de manière inattendue, inspectez-le en détail.

Fenêtre de terminal
kubectl describe node <nom-du-noeud>

La section Conditions révèle la cause. Voici les signaux d’alerte :

ConditionValeur anormaleCause probable
ReadyFalse ou UnknownKubelet arrêté, réseau coupé, nœud surchargé
MemoryPressureTrueMémoire insuffisante, pods trop gourmands
DiskPressureTrueDisque plein (nodefs, imagefs ou inodes)
PIDPressureTrueTrop de processus sur le nœud
NetworkUnavailableTruePlugin CNI non fonctionnel
Fenêtre de terminal
kubectl top nodes

Si un nœud affiche CPU ou mémoire proches de 100 %, les pods peuvent être en train d’être évincés ou incapables de démarrer.

Fenêtre de terminal
kubectl events --for node/<nom-du-noeud> --types=Warning

Les événements Warning sur un nœud peuvent révéler des problèmes de disque, de kubelet ou de réseau que les conditions ne montrent pas encore.

C’est le niveau le plus fréquent. Le triage commence par identifier l’état du pod, puis on choisit la bonne commande selon le symptôme.

Fenêtre de terminal
kubectl get pods -n <namespace> -o wide
Status observéSignificationProchaine action
PendingLe pod n’est pas encore planifié ou pas encore prêt à démarrerkubectl describe pod → voir Events (scheduling)
ContainerCreatingLe conteneur est en cours de créationAttendre, puis kubectl describe pod si ça persiste
RunningAu moins un conteneur tourneVérifier si l’application répond réellement
CrashLoopBackOffUn conteneur échoue puis redémarre en bouclekubectl logs --previous, kubectl describe pod
ImagePullBackOffL’image ne peut pas être téléchargéekubectl describe pod → Events (pull errors)
ErrorUn conteneur s’est arrêté avec une erreurkubectl logs --previous, kubectl describe pod

OOMKilled n’apparaît pas dans ce tableau car ce n’est pas un statut de pod au même titre que Pending ou Running. C’est une raison de terminaison du conteneur, visible dans kubectl describe pod sous Last State. Si vous voyez des redémarrages fréquents avec OOMKilled, augmentez limits.memory.

Les commandes fondamentales sont kubectl get, describe, logs et events. Elles couvrent la majorité des diagnostics. kubectl exec et kubectl debug complètent ensuite pour l’inspection interactive.

  1. kubectl describe pod — la vue complète

    Fenêtre de terminal
    kubectl describe pod <pod> -n <namespace>

    Sections à lire en priorité :

    • Events : messages du scheduler, du kubelet, des probes
    • Last State : raison de l’arrêt précédent (OOMKilled, Error, etc.)
    • Exit Code : indice sur la nature du crash
    • Containers → Env / Mounts : configuration du conteneur
    • Conditions : PodScheduled, Initialized, ContainersReady, Ready
  2. kubectl logs — les logs applicatifs

    Fenêtre de terminal
    # Logs du conteneur actuel
    kubectl logs <pod> -n <namespace>
    # Logs de l'exécution précédente (celle qui a crashé)
    kubectl logs <pod> -n <namespace> --previous
    # Pod multi-conteneur : préciser le conteneur
    kubectl logs <pod> -n <namespace> -c <conteneur> --previous
    # Les 50 dernières lignes seulement
    kubectl logs <pod> -n <namespace> --tail=50

    Cherchez : Exception, Error, panic, Traceback, connection refused, permission denied, OOM.

  3. kubectl events — les événements filtrés

    Fenêtre de terminal
    # Événements d'un pod spécifique
    kubectl events --for pod/<pod> -n <namespace>
    # Événements Warning du namespace
    kubectl events -n <namespace> --types=Warning

    Les événements complètent les logs en montrant ce que Kubernetes a fait (scheduling, pull d’image, kill par une probe, éviction).

  4. kubectl exec — entrer dans le conteneur

    Fenêtre de terminal
    kubectl exec -it <pod> -n <namespace> -- /bin/sh

    Utile pour vérifier :

    • La connectivité réseau (wget, curl, nslookup)
    • La présence de fichiers de configuration
    • Les variables d’environnement (env)
    • Les processus en cours (ps aux)

    Si le conteneur n’a pas de shell (image distroless), utilisez kubectl debug (voir ci-dessous).

Depuis Kubernetes v1.25, les conteneurs éphémères sont stables. Ils permettent d’inspecter un pod sans modifier son manifeste, même si l’image est minimaliste (distroless, scratch).

Fenêtre de terminal
kubectl debug -it <pod> -n <namespace> --image=busybox:1.37 --target=<conteneur>

Cette commande lance un conteneur busybox attaché au pod existant. Le conteneur de debug rejoint le pod et partage au minimum son contexte réseau ; l’accès au namespace de processus dépend du mode utilisé, de --target et du support effectif du runtime.

Profils disponibles avec --profile :

ProfilCe qu’il permetCas d’usage
legacyComportement historique (défaut si --profile absent)Compatibilité, amené à disparaître
generalConteneur isolé dans le podDiagnostic réseau basique
baselineComme general, plus contraintEnvironnements restrictifs
restrictedTrès limitéClusters avec politique stricte
netadminAccès réseau complet (NET_ADMIN)Diagnostic réseau avancé (tcpdump)
sysadminAccès complet (root, hostPID)Diagnostic système poussé
Fenêtre de terminal
# Diagnostic réseau avancé avec tcpdump
kubectl debug -it <pod> -n <namespace> \
--image=nicolaka/netshoot --profile=netadmin --target=<conteneur>
# Diagnostic d'un nœud directement
kubectl debug node/<nom-du-noeud> -it --image=busybox:1.37

Niveau 4 : diagnostiquer le réseau (Services et DNS)

Section intitulée « Niveau 4 : diagnostiquer le réseau (Services et DNS) »

Si le pod tourne (Running) mais que l’application n’est pas joignable, le problème est souvent au niveau du Service, du DNS ou des Network Policies.

Fenêtre de terminal
kubectl get svc <service> -n <namespace>

Vérifiez que le TYPE, le CLUSTER-IP et le PORT correspondent à ce que vous attendez.

Fenêtre de terminal
kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=<service>

Si la liste des endpoints est vide, le Service ne trouve aucun pod correspondant. Causes possibles :

  • Le sélecteur (spec.selector) du Service ne correspond pas aux labels des pods
  • Les pods ne sont pas Ready (probe échouée)
  • Les pods sont dans un autre namespace

Depuis un pod de test :

Fenêtre de terminal
kubectl run dnstest --image=busybox:1.37 --rm -it --restart=Never -- \
nslookup <service>.<namespace>.svc.cluster.local

Résultat attendu : le nom est résolu vers l’IP du Service (CLUSTER-IP).

Si la résolution échoue :

Fenêtre de terminal
# Vérifier que CoreDNS fonctionne
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Vérifier les logs de CoreDNS
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=20
Fenêtre de terminal
kubectl run curltest --image=curlimages/curl:8.14.1 --rm -it --restart=Never -- \
curl -v http://<service>.<namespace>.svc.cluster.local:<port>/

Si le DNS fonctionne mais la connexion échoue, vérifiez :

  • Le port cible (targetPort) dans la définition du Service
  • Les Network Policies qui pourraient bloquer le trafic
  • Le kube-proxy (mode iptables/IPVS) sur les nœuds

Utilisez ce tableau quand vous êtes face à un symptôme et que vous ne savez pas par quel niveau commencer :

SymptômeNiveau probablePremière commande
kubectl ne répond pas1 — ClusterVérifier kubeconfig, réseau, VPN
Nœud NotReady2 — Nœudkubectl describe node <noeud>
Pod Pending3 — Podkubectl describe pod <pod> (Events)
Pod CrashLoopBackOff3 — Podkubectl logs <pod> --previous
Pod ImagePullBackOff3 — Podkubectl describe pod <pod> (Events)
Pod Running mais application inaccessible4 — Réseaukubectl get svc, kubectl get endpointslices
Timeout intermittent4 — RéseauDNS check + Network Policies
Pods évincés sans raison apparente2 — Nœudkubectl describe node (conditions, pression)
SymptômeCause probableSolution
kubectl timeoutAPI server inaccessibleVérifier kubeconfig et connectivité réseau
Nœud NotReady persistantKubelet arrêté ou disque pleinSSH sur le nœud, systemctl status kubelet
Pod Pending longue duréePas de nœud avec assez de ressourceskubectl describe pod → Events → ajuster requests ou ajouter un nœud
Logs vides + exit code 137OOMKill (visible dans Last State de describe)kubectl describe pod → augmenter limits.memory
Logs vides + exit code 127Binaire introuvable dans l’imageVérifier command: et le tag de l’image
Pod Running mais connexion refuséeService mal configuré ou pod pas ReadyVérifier le sélecteur du Service et les probes
DNS ne résout pasCoreDNS en pannekubectl get pods -n kube-system -l k8s-app=kube-dns
Trafic bloqué sans erreurNetwork Policy restrictivekubectl get networkpolicies -n <namespace>
  • Toujours commencer par le haut : cluster → nœud → pod → réseau. Cela évite de perdre du temps à lire des logs quand le problème est un nœud en panne
  • Les 4 commandes de base sont kubectl get, describe, logs et events. kubectl exec et kubectl debug complètent ensuite pour l’inspection interactive
  • kubectl logs --previous est la commande la plus sous-utilisée : elle affiche les logs de l’exécution qui a planté, pas celle en cours
  • kubectl debug avec les conteneurs éphémères permet d’inspecter un pod sans le redémarrer, même sur une image distroless
  • Les problèmes réseau sont souvent des problèmes de configuration : sélecteur de Service incorrect, probe qui échoue, Network Policy qui bloque
  • Documentez votre diagnostic : notez les commandes exécutées et leurs résultats, cela aide à communiquer avec l’équipe et à créer des runbooks

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn