Maîtrisez kubectl logs et describe pour un débogage efficace des pods

Ce guide fournit des techniques d'expert pour maîtriser les commandes essentielles de débogage Kubernetes : `kubectl logs` et `kubectl describe`. Apprenez les flags critiques, tels que `-f`, `--tail`, `-c` et `--previous`, nécessaires pour un dépannage efficace. Nous détaillons comment interpréter la section cruciale 'Events' dans `describe` pour diagnostiquer les problèmes de planification et de configuration, et comment utiliser `logs` pour extraire les erreurs d'exécution de pods en crash ou multi-conteneurs, accélérant ainsi votre flux de travail de débogage.

Maîtrisez kubectl logs et describe pour un débogage efficace des pods

Lorsqu'un pod Kubernetes échoue, kubectl describe et kubectl logs vous indiquent généralement où chercher. describe explique ce que Kubernetes a essayé de faire. logs montre ce que le conteneur a écrit avant, pendant ou après l'échec.

Ces commandes offrent des vues différentes, mais complémentaires, de l'état et de l'historique d'un pod Kubernetes. kubectl describe fournit les métadonnées du pod, son statut, les variables d'environnement et, surtout, un historique des événements système. kubectl logs fournit les flux de sortie standard (stdout) et d'erreur standard (stderr) générés par l'application conteneurisée elle-même.

L'astuce consiste à les utiliser dans le bon ordre. Si le pod n'a jamais été planifié, les logs ne vous aideront pas. Si le pod démarre et se termine, les événements peuvent seulement vous dire qu'il a planté ; les logs de l'application expliquent généralement pourquoi.


Le flux de travail de débogage de pod en trois étapes

Avant de plonger dans les commandes, il est utile de comprendre le flux de travail typique de débogage :

  1. Vérifier l'état : Utilisez kubectl get pods pour identifier l'état d'échec (Pending, CrashLoopBackOff, ImagePullBackOff, etc.).
  2. Obtenir le contexte et les événements : Utilisez kubectl describe pod pour comprendre pourquoi la transition d'état s'est produite (par exemple, échec du planificateur, échec de la sonde de vivacité, échec du montage de volume).
  3. Inspecter la sortie de l'application : Utilisez kubectl logs pour examiner le comportement d'exécution de l'application (par exemple, erreurs de configuration, échecs de connexion à la base de données, traces de pile).

1. kubectl describe : L'outil de triage système

kubectl describe est la première commande que vous devez exécuter lorsqu'un pod se comporte mal. Elle n'affiche pas la sortie de l'application, mais fournit les métadonnées critiques et l'historique que Kubernetes lui-même a enregistrés à propos du pod.

Utilisation de base

L'utilisation fondamentale nécessite uniquement le nom du pod :

kubectl describe pod my-failing-app-xyz789

Utilisez les espaces de noms explicitement lorsque vous n'êtes pas dans l'espace de noms par défaut :

kubectl describe pod my-failing-app-xyz789 -n payments

Si vous ne connaissez que le déploiement ou l'étiquette, trouvez d'abord le pod :

kubectl get pods -n payments -l app=checkout -o wide

Sections clés dans la sortie

Lors de l'examen de la sortie de describe, concentrez-vous sur ces sections critiques :

A. Statut et état

Regardez le champ Status en haut, puis examinez les états individuels des conteneurs dans le pod. Cela vous indique si le conteneur est Running, Waiting ou Terminated, et fournit la raison de cet état.

Champ Statut/Raison courante Signification
Status Pending Le pod attend d'être planifié ou a des ressources manquantes.
Reason ContainerCreating Le runtime du conteneur tire l'image ou exécute la configuration.
State Waiting / Reason: CrashLoopBackOff Le conteneur a démarré et s'est arrêté de manière répétée.
State Terminated / Exit Code Le conteneur a terminé son exécution. Les codes de sortie non nuls indiquent généralement des erreurs.

B. Configuration du conteneur

Cette section vérifie que vos variables d'environnement, vos demandes/limites de ressources, vos montages de volume et vos sondes de vivacité/readiness sont correctement définis, correspondant au manifeste que vous avez appliqué.

C. La section Events (Cruciale)

La section Events, située en bas de la sortie, est sans doute la partie la plus précieuse. Elle fournit un journal chronologique de ce que le plan de contrôle Kubernetes a fait pour et au pod, y compris les avertissements et les erreurs.

Erreurs courantes révélées par Events :

  • Problèmes de planification : Warning FailedScheduling : Indique que le planificateur n'a pas pu trouver un nœud approprié (par exemple, en raison de contraintes de ressources, de taints de nœud ou de règles d'affinité).
  • Échecs de tirage d'image : Warning Failed: ImagePullBackOff : Indique que le nom de l'image est incorrect, que le tag n'existe pas ou que Kubernetes manque d'informations d'identification pour tirer d'un registre privé.
  • Erreurs de volume : Warning FailedAttachVolume : Indique des problèmes de connexion au stockage externe.

Astuce : Si la section Events est propre et que le conteneur a démarré, le problème est souvent lié à l'application : une mauvaise variable d'environnement, une migration échouée, un secret manquant, une dépendance inaccessible ou un processus qui se termine immédiatement.

2. kubectl logs : Inspection de la sortie de l'application

Si describe montre que le pod a été planifié avec succès et que les conteneurs ont tenté de s'exécuter, l'étape suivante consiste à vérifier les flux de sortie standard à l'aide de kubectl logs.

Récupération de base des logs et streaming en temps réel

Pour afficher les logs actuels du conteneur principal dans un pod :

# Récupérer tous les logs jusqu'au moment présent
kubectl logs my-failing-app-xyz789

# Streamer les logs en temps réel (utile pour surveiller le démarrage)
kubectl logs -f my-failing-app-xyz789

Gestion des pods multi-conteneurs

Pour les pods utilisant le modèle Sidecar ou d'autres conceptions multi-conteneurs, vous devez spécifier quel conteneur vous souhaitez voir en utilisant le flag -c ou --container.

# Afficher les logs du conteneur 'sidecar-proxy' dans le pod
kubectl logs my-multi-container-pod -c sidecar-proxy

# Streamer les logs du conteneur d'application principal
kubectl logs -f my-multi-container-pod -c main-app

Débogage des conteneurs en redémarrage (--previous)

L'un des scénarios de débogage les plus courants est l'état CrashLoopBackOff. Lorsqu'un conteneur redémarre, kubectl logs n'affiche que la sortie de la tentative actuelle (échouée), qui contient souvent seulement le message de démarrage avant le plantage.

Pour afficher les logs de l'instance précédente, terminée, qui contient l'erreur réelle ayant provoqué la sortie, utilisez le flag --previous (-p) :

# Afficher les logs de l'instance de conteneur précédente et plantée
kubectl logs my-crashloop-pod --previous

# Combiner avec la spécification du conteneur si nécessaire
kubectl logs my-crashloop-pod -c worker --previous

Limitation de la sortie

Pour les logs à volume élevé, la récupération de tout l'historique peut être lente ou écrasante. Utilisez --tail pour limiter la sortie aux N dernières lignes.

# Afficher seulement les 50 dernières lignes des logs du conteneur
kubectl logs my-high-traffic-app --tail=50

Vous pouvez également ajouter des horodatages et une fenêtre de temps :

kubectl logs my-high-traffic-app --tail=100 --timestamps
kubectl logs my-high-traffic-app --since=10m

Pour un déploiement, les versions récentes de kubectl peuvent récupérer les logs via le nom de la charge de travail :

kubectl logs deploy/checkout-api -n payments --tail=100

Lorsque c'est trop large, utilisez un sélecteur d'étiquettes :

kubectl logs -n payments -l app=checkout --all-containers=true --tail=50

3. Combinaison de techniques pour un diagnostic avancé

Un débogage efficace implique souvent de basculer rapidement entre describe et des commandes logs spécifiques.

Étude de cas : Diagnostic d'un échec de sonde de vivacité

Imaginez un pod bloqué dans l'état Running mais qui redémarre occasionnellement, provoquant des perturbations.

Étape 1 : Vérifiez describe pour la vue système.

kubectl describe pod web-server-dpl-abc

La sortie montre dans la section Events :

Type     Reason      Age   From               Message
----     ------      ----  ----               -------
Warning  Unhealthy   2s    kubelet, node-a01  Liveness probe failed: HTTP GET http://10.42.0.5:8080/health failed: 503 Service Unavailable

Conclusion de l'étape 1 : Le conteneur est en cours d'exécution, mais la sonde de vivacité échoue avec une erreur 503, ce qui amène Kubernetes à redémarrer le conteneur.

Étape 2 : Vérifiez logs pour le contexte de l'application.

Maintenant, enquêtez sur la raison pour laquelle l'application renvoie un statut 503, qui est une défaillance au niveau de l'application.

kubectl logs web-server-dpl-abc --tail=200

La sortie des logs révèle :

2023-10-26 14:01:15 ERROR Database connection failure: Timeout connecting to DB instance 192.168.1.10

Conclusion finale : Le pod redémarre en raison d'un échec de la sonde de vivacité, et la sonde échoue car l'application ne peut pas se connecter à la base de données. Le problème est externe (réseau ou configuration de la base de données), pas le conteneur lui-même.

Étude de cas : Pod en attente sans logs

Un pod dans l'état Pending n'a souvent pas de logs de conteneur utiles car aucun conteneur n'a encore démarré.

kubectl get pod report-worker-6f9c7b9b7d-f2q8m -n analytics

Sortie :

NAME                                  READY   STATUS    RESTARTS   AGE
report-worker-6f9c7b9b7d-f2q8m        0/1     Pending   0          4m

Allez directement à describe :

kubectl describe pod report-worker-6f9c7b9b7d-f2q8m -n analytics

Les événements pourraient montrer :

Warning  FailedScheduling  default-scheduler  0/6 nodes are available: 6 Insufficient memory.

Ce n'est pas un bug d'application. Le pod demande plus de mémoire que le planificateur ne peut en placer. L'étape suivante consiste à inspecter les demandes de déploiement, la capacité du cluster, les taints de nœud et le comportement de l'autoscaler :

kubectl get deploy report-worker -n analytics -o yaml
kubectl top nodes

Étude de cas : ImagePullBackOff

Pour ImagePullBackOff, les logs sont généralement vides car l'image du conteneur n'a jamais démarré. describe donne l'erreur utile :

kubectl describe pod api-7dfb9c8b7f-bd2p9 -n staging

Les messages d'événement courants incluent un tag d'image qui n'existe pas, un échec d'authentification contre un registre privé, ou un problème DNS/réseau pour atteindre le registre. La correction peut être aussi simple que de corriger le tag :

kubectl set image deploy/api api=registry.example.com/api:2026-05-24 -n staging

Ou cela peut nécessiter de vérifier le secret de tirage d'image :

kubectl get secret regcred -n staging
kubectl describe serviceaccount default -n staging

Étude de cas : Pod multi-conteneurs avec une application silencieuse

Les sidecars peuvent masquer le signal si vous regardez le mauvais conteneur. Listez d'abord les noms des conteneurs :

kubectl get pod checkout-84f7c9d7bf-px5mx -n payments \
  -o jsonpath='{.spec.containers[*].name}{"\n"}'

Ensuite, inspectez chacun délibérément :

kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c checkout --tail=100
kubectl logs checkout-84f7c9d7bf-px5mx -n payments -c envoy --tail=100

Si les logs de l'application sont silencieux mais que les logs du proxy montrent des échecs de connexion en amont, le pod peut être sain du point de vue de Kubernetes tandis que le trafic échoue toujours à cause de la configuration du maillage de services ou du proxy.

Bonnes pratiques et avertissements

Pratique Commande Justification
Vérifiez toujours les logs précédents kubectl logs --previous Nécessaire pour diagnostiquer CrashLoopBackOff. L'erreur critique est presque toujours dans l'exécution précédente.
Spécifiez les conteneurs kubectl logs -c <nom> Évite l'ambiguïté dans les pods multi-conteneurs et empêche la récupération des logs de sidecars non intentionnels.
Utilisez les étiquettes pour les opérations en masse kubectl logs -l app=frontend -f Permet de diffuser les logs de plusieurs pods correspondant à un sélecteur simultanément (utile pour les mises à jour continues).
Avertissement : Rotation des logs N/A Les nœuds Kubernetes effectuent une rotation des logs. Les logs plus anciens que la politique de rétention configurée du nœud (souvent quelques jours ou basée sur la taille) seront purgés et indisponibles via kubectl logs. Utilisez une solution de journalisation centralisée externe (par exemple, Fluentd, Loki, Elastic Stack) pour la rétention à long terme.

Ce que ces commandes ne peuvent pas vous dire

kubectl logs n'affiche que stdout et stderr du conteneur tels que conservés par le nœud. Si l'application écrit dans un fichier à l'intérieur du conteneur, kubectl logs peut ne rien afficher. C'est un problème de conception de journalisation, pas un problème de kubectl.

kubectl describe montre l'état de l'objet Kubernetes et les événements récents, mais les événements ne sont pas des journaux d'audit permanents. Les anciens événements expirent. Pour les enquêtes de longue durée, copiez la sortie pertinente dans les notes d'incident.

Aucune de ces commandes ne remplace les métriques. Un pod peut être en cours d'exécution et journaliser normalement tandis que le throttling CPU, la pression mémoire ou la latence en aval causent des problèmes visibles par l'utilisateur. Après describe et logs, les commandes suivantes sont souvent :

kubectl top pod -n payments
kubectl top node
kubectl get events -n payments --sort-by=.lastTimestamp

Utilisez describe en premier lorsque Kubernetes n'a pas pu créer ou maintenir le pod en cours d'exécution. Utilisez logs en premier lorsque le pod est en cours d'exécution mais que l'application se comporte mal. Basculez entre eux jusqu'à ce que vous puissiez séparer les symptômes de la plateforme des symptômes de l'application.

Un flux de débogage réutilisable

Lorsque vous êtes sous pression, utilisez le même flux à chaque fois :

kubectl get pod <pod> -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --all-containers=true --tail=100
kubectl logs <pod> -n <namespace> --all-containers=true --previous --tail=100
kubectl get events -n <namespace> --sort-by=.lastTimestamp

L'ordre compte. get pod -o wide vous indique le nœud, l'IP du pod, le nombre de redémarrages et l'âge. describe vous indique les détails de planification, d'image, de volume, de sonde et d'état du conteneur. Les logs actuels montrent ce que le conteneur en cours d'exécution fait maintenant. Les logs précédents capturent le plantage qui a déjà eu lieu. Les événements montrent si le même problème se produit dans tout l'espace de noms.

Pour les déploiements, ajoutez une vérification de déploiement :

kubectl rollout status deploy/<nom> -n <namespace>
kubectl describe deploy/<nom> -n <namespace>
kubectl get rs -n <namespace> -l app=<label>

Parfois, le pod que vous déboguez provient d'un ancien ReplicaSet lors d'un déploiement. Si vous corrigez le déploiement mais continuez à lire les logs d'un ancien pod en cours de terminaison, vous pouvez poursuivre le mauvais problème pendant une demi-heure.

Lire correctement les redémarrages

La colonne RESTARTS est un indice, pas un diagnostic. Un nombre de redémarrages de 1 après un drain de nœud peut être inoffensif. Un nombre de redémarrages qui augmente chaque minute est un échec en direct. Utilisez describe pour vérifier le dernier état :

Last State:     Terminated
  Reason:       Error
  Exit Code:    1
  Started:      Sun, 24 May 2026 10:14:02 +0800
  Finished:     Sun, 24 May 2026 10:14:07 +0800

Un code de sortie de 1 signifie généralement que le processus s'est terminé avec une erreur d'application générale. 137 signifie souvent que le processus a été tué, généralement parce qu'il a dépassé les limites de mémoire, mais vous devez confirmer avec le champ Reason et le contexte du nœud/runtime du conteneur. 143 apparaît souvent lorsqu'un processus reçoit SIGTERM lors d'une terminaison normale. Ne traitez pas chaque code de sortie non nul comme le même type d'échec.

Lorsque la mémoire est suspectée, recherchez :

Reason:       OOMKilled
Exit Code:    137

Comparez ensuite la limite du conteneur avec l'utilisation réelle :

kubectl describe pod <pod> -n <namespace> | rg -A5 'Limits|Requests'
kubectl top pod <pod> -n <namespace>

Si metrics-server n'est pas installé, kubectl top ne fonctionnera pas. Dans ce cas, utilisez le système de métriques de votre plateforme ou les outils au niveau du nœud.