Aller au contenu

Comment débugger avec kubectl exec et kubectl debug

Mise à jour :

logo kubernetes

Ce guide fait partie d’une série dédiée à kubectl, l’outil en ligne de commande pour interagir avec Kubernetes. Dans ce guide on va se concentrer sur les commandes kubectl exec et kubectl debug. Que ce soit pour déboguer une application, vérifier des fichiers, ou ouvrir un shell interactif, kubectl exec est un outil puissant à maîtriser.

Pourquoi utiliser kubectl exec ?

Lorsque l’on travaille avec des applications déployées dans Kubernetes, il peut être nécessaire d’interagir avec un conteneur sans devoir reconstruire ou redéployer l’image. kubectl exec permet d’exécuter des commandes directement dans un pod en cours d’exécution, un peu comme si on se connectait à une machine distante via SSH.

Voici quelques cas d’usage courants :

  • Vérifier l’état d’un conteneur : Lire des fichiers de configuration, voir les processus en cours.
  • Déboguer une application : Tester des connexions réseau, exécuter des scripts de diagnostic.
  • Ouvrir un shell interactif : Lancer /bin/sh ou /bin/bash pour explorer un pod manuellement.
  • Tester une commande rapidement : Par exemple, vérifier si une dépendance est installée dans le conteneur.

Utilisation de la commande kubectl exec

La commande kubectl exec permet d’exécuter une commande à l’intérieur d’un pod en cours d’exécution. Que ce soit pour exécuter une commande simple, ouvrir un shell interactif ou interagir avec un conteneur spécifique, son utilisation suit une syntaxe bien définie.

Syntaxe de base

La commande kubectl exec s’utilise avec la syntaxe suivante :

Terminal window
kubectl exec [OPTIONS] <nom-du-pod> -- <commande>

Les options les plus courantes sont :

  • -it : Ouvre un terminal interactif (utile pour un shell).
  • -c <nom-du-conteneur> : Spécifie le conteneur dans un pod multi-conteneurs.
  • -n <namespace> : Exécute la commande dans un pod appartenant à un namespace spécifique.

Exécuter une commande simple

Si l’on souhaite exécuter une commande unique dans un pod, il suffit d’indiquer son nom et la commande à exécuter. Par exemple, pour afficher la liste des fichiers à la racine d’un pod nommé my-pod :

Terminal window
kubectl exec my-pod -- ls /

Pour afficher le contenu d’un fichier :

Terminal window
kubectl exec my-pod -- cat /etc/hostname

Ces commandes permettent d’examiner rapidement l’environnement d’un conteneur sans avoir besoin d’un accès interactif.

Ouvrir un shell interactif dans un pod

Pour exécuter des commandes successives dans un conteneur, il est plus pratique d’ouvrir un shell interactif avec l’option -it :

Terminal window
kubectl exec -it my-pod -- /bin/sh

Si le conteneur utilise bash, on peut l’appeler directement :

Terminal window
kubectl exec -it my-pod -- /bin/bash

L’option -i (interactive) maintient l’entrée standard ouverte, et -t (TTY) active un terminal interactif.

Dans certains cas, notamment avec des images minimalistes comme Alpine ou Distroless, le conteneur peut ne pas contenir de shell. Si un message d’erreur indique que /bin/sh est introuvable, il faudra utiliser d’autres méthodes pour interagir avec le pod, comme kubectl debug.

Exécuter une commande dans un conteneur spécifique

Lorsqu’un pod contient plusieurs conteneurs, il est nécessaire de préciser dans lequel exécuter la commande à l’aide de l’option -c :

Terminal window
kubectl exec -it my-pod -c my-container -- ls /

Sans cette option, Kubernetes essaiera d’exécuter la commande dans le premier conteneur du pod, ce qui peut ne pas être le comportement souhaité.

Pour obtenir la liste des conteneurs d’un pod, on peut utiliser :

Terminal window
kubectl get pod my-pod -o jsonpath='{.spec.containers[*].name}'

Exécuter une commande dans un pod d’un namespace spécifique

Si le pod se trouve dans un namespace autre que default, il faut ajouter l’option --namespace=<nom-du-namespace> :

Terminal window
kubectl exec -it my-pod --namespace=mon-namespace -- /bin/sh

Erreurs courantes avec kubectl exec et solutions

L’utilisation de kubectl exec peut parfois entraîner des erreurs qui empêchent d’exécuter des commandes dans un pod. Voici les erreurs les plus fréquentes et comment les résoudre.

1. error: unable to upgrade connection: pod does not exist

Problème : Cette erreur indique que le pod spécifié n’existe pas ou n’est pas en cours d’exécution.

Solutions :

  • Vérifier que le pod est bien actif avec :

    Terminal window
    kubectl get pods
  • Si le pod est dans un autre namespace, préciser --namespace :

    Terminal window
    kubectl exec -it my-pod --namespace=mon-namespace -- /bin/sh
  • Si le pod est en CrashLoopBackOff, il faudra d’abord corriger la cause du plantage avant d’y accéder.

2. error: unable to upgrade connection: container not found

Problème : Le pod contient plusieurs conteneurs, et Kubernetes ne sait pas dans lequel exécuter la commande.

Solutions :

  • Lister les conteneurs du pod avec :

    Terminal window
    kubectl get pod my-pod -o jsonpath='{.spec.containers[*].name}'
  • Exécuter la commande en précisant le conteneur avec -c :

    Terminal window
    kubectl exec -it my-pod -c mon-conteneur -- /bin/sh

3. OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory"

Problème : Le conteneur ne contient pas de shell (/bin/sh ou /bin/bash). C’est fréquent avec des images minimalistes comme Distroless ou Alpine.

Solutions :

  • Vérifier si d’autres shells sont disponibles :

    Terminal window
    kubectl exec -it my-pod -- ls /bin /usr/bin
  • Tester une autre commande comme :

    Terminal window
    kubectl exec -it my-pod -- /busybox/sh
  • Si aucun shell n’est disponible, utiliser kubectl debug pour lancer un pod de débogage :

    Terminal window
    kubectl debug my-pod -it --image=busybox -- /bin/sh

4. error: the server doesn't have a resource type "exec"

Problème : Le compte utilisateur ou service utilisé pour exécuter la commande ne dispose pas des permissions nécessaires pour exécuter kubectl exec.

Solutions :

  • Vérifier si l’utilisateur a bien les droits RBAC :

    Terminal window
    kubectl auth can-i create pods/exec
  • Si l’accès est refusé, contacter l’administrateur Kubernetes pour ajouter la permission pods/exec dans les rôles RBAC.

5. command terminated with exit code 137

Problème : L’erreur exit code 137 signifie que le conteneur a été arrêté par le système avant que la commande ne se termine, souvent à cause d’un OOMKill (Out of Memory Kill).

Solutions :

  • Vérifier l’état du pod avec :

    Terminal window
    kubectl describe pod my-pod
  • Si l’on voit un message indiquant OOMKilled, cela signifie que le conteneur a dépassé sa limite de mémoire.

  • Augmenter la mémoire allouée dans la configuration du pod (requests.memory et limits.memory).

6. Error from server: error dialing backend: dial tcp ... connection refused

Problème : Ce message indique que la connexion au pod a échoué, souvent à cause d’un problème réseau ou d’un pod qui tourne sur un nœud injoignable.

Solutions :

  • Vérifier si le pod est en cours d’exécution :

    Terminal window
    kubectl get pods -o wide
  • Vérifier l’état du nœud où tourne le pod :

    Terminal window
    kubectl get nodes
  • Si le pod tourne sur un nœud marqué NotReady, il peut être nécessaire de redémarrer le nœud ou de replanifier le pod ailleurs.

7. Defaulting container name to <nom-du-conteneur> et exécution bloquée

Problème : Lorsque kubectl exec semble bloqué et n’affiche rien, il se peut que :

  • La commande exécutée attende une entrée utilisateur.
  • Le TTY (-t) ne soit pas activé.

Solutions :

  • Ajouter l’option -it si l’on souhaite interagir avec le terminal :

    Terminal window
    kubectl exec -it my-pod -- /bin/sh
  • Tester sans TTY si l’application ne supporte pas l’interaction :

    Terminal window
    kubectl exec my-pod -- ls /

Déboguer avec kubectl debug

Lorsqu’une application s’exécute dans un cluster Kubernetes, il peut être nécessaire de la déboguer, surtout si un conteneur plante ou si son image ne contient pas les outils de diagnostic requis. Dans de tels cas, la commande kubectl debug et les conteneurs éphémères offrent une solution efficace.

Qu’est-ce qu’un conteneur éphémère ?

Un conteneur éphémère est un type spécial de conteneur que l’on peut ajouter à un Pod existant pour des tâches de débogage. Contrairement aux conteneurs standards, les conteneurs éphémères :

  • Ne sont pas destinés à des charges de travail en production : ils sont conçus pour le débogage et le diagnostic temporaires.
  • Ne garantissent pas de ressources ou d’exécution : ils ne sont pas redémarrés automatiquement en cas de défaillance.
  • Ne peuvent pas définir certains champs : par exemple, les ports, les probes de liveness ou de readiness, et les ressources sont interdits dans leur spécification.

Pour plus de détails, consultez la documentation officielle sur les conteneurs éphémères.

Pourquoi utiliser kubectl debug avec des conteneurs éphémères ?

Les conteneurs éphémères sont particulièrement utiles lorsque :

  • kubectl exec est insuffisant : par exemple, si le conteneur principal a planté ou ne dispose pas des outils nécessaires pour le débogage.
  • Les images sont minimalistes : comme les images distroless qui n’incluent pas de shell ou d’outils de diagnostic, rendant le débogage avec kubectl exec difficile.

Comment utiliser kubectl debug pour ajouter un conteneur éphémère

Pour ajouter un conteneur éphémère à un Pod en cours d’exécution, on utilise la commande kubectl debug :

Terminal window
kubectl debug -it <nom-du-pod> --image=<image-de-debug>

Par exemple, pour ajouter un conteneur de débogage basé sur l’image busybox à un Pod nommé my-pod :

Terminal window
kubectl debug -it my-pod --image=busybox --target=my-container

Dans cet exemple :

  • -it : ouvre un terminal interactif.
  • --image=busybox : spécifie l’image à utiliser pour le conteneur éphémère.
  • --target=my-container : (optionnel) spécifie le conteneur cible à déboguer dans le Pod.

En intégrant kubectl debug et les conteneurs éphémères dans votre boîte à outils, vous disposerez d’une méthode puissante pour diagnostiquer et résoudre les problèmes au sein de vos applications Kubernetes.

Bonnes pratiques pour éviter les erreurs

  • Toujours vérifier le nom exact du pod avec kubectl get pods avant d’exécuter une commande.
  • En cas de problème, utiliser kubectl describe pod <nom-du-pod> pour voir les événements récents.
  • Si une erreur indique un manque de permissions, demander à l’administrateur Kubernetes les droits RBAC nécessaires.
  • Pour les conteneurs sans shell, privilégier kubectl debug ou l’utilisation de kubectl cp pour transférer des fichiers d’exécution.

Conclusion

kubectl exec est un outil indispensable pour interagir avec les conteneurs en cours d’exécution dans Kubernetes. Que ce soit pour déboguer, vérifier des fichiers, ou ouvrir un shell interactif, il simplifie la gestion des pods au quotidien.

Cependant, il peut parfois rencontrer des limitations (images minimalistes, erreurs réseau, problèmes d’autorisation). Dans ces cas-là, des alternatives comme kubectl debug et les conteneurs éphémères offrent des solutions complémentaires.

En maîtrisant ces commandes et en adoptant les bonnes pratiques, vous serez mieux équipé pour gérer efficacement vos applications dans un cluster Kubernetes. 🚀