
Débogage avancé de conteneurs et du démon Docker
Maîtrisez le débogage avancé des conteneurs Docker et du démon dockerd avec des outils et techniques spécifiques pour résoudre les problèmes complexes.
Au-delà des logs : quand le débogage standard ne suffit plus
Lorsque vous êtes confronté à des problèmes persistants avec vos conteneurs ou le moteur Docker lui-même, les commandes de base comme docker logs ou docker exec peuvent s'avérer insuffisantes. Des erreurs de démarrage silencieuses, des comportements réseau inattendus, des problèmes de performance subtils ou des plantages inexpliqués du démon Docker nécessitent des techniques de diagnostic plus poussées. Ce chapitre explore ces méthodes avancées pour investiguer en profondeur.
Le débogage avancé implique souvent d'interagir plus intimement avec les processus du conteneur, d'utiliser des outils de diagnostic système ou même d'inspecter l'état interne du démon Docker. Cela requiert une compréhension plus fine des mécanismes d'isolation de Docker (namespaces, cgroups) et parfois, l'utilisation d'outils ou de privilèges qui sortent du cadre d'une utilisation standard.
L'objectif est de vous armer des connaissances nécessaires pour identifier la cause racine des problèmes complexes, qu'ils proviennent de l'application conteneurisée, de sa configuration ou de l'environnement d'exécution Docker lui-même. Nous aborderons des techniques spécifiques pour les conteneurs en cours d'exécution, les problèmes de démarrage et le dépannage du démon Docker.
Inspecter les conteneurs en profondeur : outils et astuces
Pour comprendre ce qui se passe à l'intérieur d'un conteneur en cours d'exécution au-delà des logs applicatifs, plusieurs approches existent. La plus simple reste docker exec -it (ou bash si disponible) pour obtenir un shell interactif. Cependant, l'image de base peut manquer d'outils de diagnostic essentiels (ps, netstat, ping, curl, etc.).
Une solution consiste à installer ces outils directement dans le conteneur en cours d'exécution via son gestionnaire de paquets (apt-get update && apt-get install -y pour Debian/Ubuntu, apk add pour Alpine). C'est une solution rapide mais temporaire (les changements sont perdus au redémarrage du conteneur) et peut poser des problèmes de sécurité ou de reproductibilité. Pour des outils plus puissants comme strace (trace les appels système) ou gdb (débogueur C/C++), vous pourriez avoir besoin de lancer le conteneur avec des capacités Linux supplémentaires via --cap-add=SYS_PTRACE ou même en mode privilégié (--privileged), ce qui réduit considérablement l'isolation et doit être fait avec une extrême prudence.
Une approche plus propre est le "sidecar debugging". Elle consiste à lancer un conteneur dédié au débogage (contenant tous les outils nécessaires) en partageant certains namespaces du conteneur cible. Par exemple, pour inspecter le réseau du conteneur "webapp", on peut lancer un conteneur "debug-tools" avec :
docker run -it --rm --network=container:webapp --pid=container:webapp nicolaka/netshootLe conteneur nicolaka/netshoot (une image populaire contenant de nombreux outils réseau) partagera ainsi l'interface réseau et l'espace des processus du conteneur webapp, permettant d'utiliser tcpdump, ss, ps, etc., comme si on était dans le conteneur cible, mais sans le modifier.
Pour une inspection encore plus fine depuis l'hôte, l'outil nsenter permet d'entrer dans les namespaces d'un processus existant. D'abord, trouvez le PID du processus principal du conteneur sur l'hôte (par exemple, via docker inspect -f '{{.State.Pid}}' ). Ensuite, utilisez nsenter pour rejoindre ses namespaces :
TARGET_PID=$(docker inspect -f '{{.State.Pid}}' my_container)
sudo nsenter --target $TARGET_PID --mount --uts --ipc --net --pid /bin/bashCela vous donne un shell qui s'exécute dans le contexte exact du conteneur (mêmes montages, réseau, IPC, PID), offrant un accès complet sans passer par l'API Docker.
Diagnostiquer les échecs de démarrage de conteneurs
Lorsqu'un conteneur refuse de démarrer ou s'arrête immédiatement, docker logs peut parfois donner une indication, mais pas toujours. Un problème courant est une erreur dans le script d'entrée (ENTRYPOINT) ou la commande par défaut (CMD) qui se produit avant que la journalisation ne soit configurée.
Une technique essentielle est de remplacer temporairement l'ENTRYPOINT et/ou le CMD de l'image pour obtenir un shell interactif avant l'exécution du point d'entrée original. Cela permet d'inspecter l'environnement, les fichiers et de tenter d'exécuter manuellement les commandes de démarrage pour voir où elles échouent :
# Remplacer l'entrypoint par un shell
docker run -it --rm --entrypoint /bin/sh my_image:latest
# Une fois dans le shell, vous pouvez explorer l'environnement,
# vérifier les permissions, et essayer de lancer la commande originale.
# Par exemple, si l'entrypoint original était "/app/start.sh" :
# /app/start.shVérifiez également attentivement la configuration passée via docker run ou Docker Compose : les volumes sont-ils correctement montés (chemins, permissions) ? Les variables d'environnement sont-elles bien définies et attendues par l'application ? Les ports mappés ne sont-ils pas déjà utilisés sur l'hôte ? Un docker inspect sur le conteneur échoué (même s'il est arrêté) peut révéler des informations utiles dans les sections Config et State.
Dépanner le démon Docker (dockerd)
Si Docker lui-même semble rencontrer des problèmes (commandes lentes, erreurs API, conteneurs qui ne répondent plus), le premier réflexe est de consulter les logs du démon Docker. L'emplacement dépend de votre système d'exploitation et de la configuration. Sur la plupart des systèmes Linux utilisant systemd, vous les trouverez avec :
sudo journalctl -u docker.service -fPour Docker Desktop (Windows/macOS), les logs sont accessibles via l'interface graphique (icône Docker > Troubleshoot > View logs).
Pour obtenir des informations beaucoup plus détaillées, vous pouvez activer le mode débogage du démon. Cela se fait généralement en modifiant le fichier de configuration /etc/docker/daemon.json (créez-le s'il n'existe pas) et en ajoutant ou modifiant la clé "debug" :
{
"debug": true
}Après avoir modifié ce fichier, rechargez la configuration et redémarrez le démon Docker (par exemple, sudo systemctl reload docker && sudo systemctl restart docker). Attention, le mode débogage est très verbeux et peut impacter les performances ; n'oubliez pas de le désactiver une fois le problème résolu.
Assurez-vous également que la configuration dans daemon.json est correcte (registries, pilotes de stockage, configuration réseau par défaut). Des erreurs de syntaxe JSON ou des options incompatibles peuvent empêcher le démon de démarrer correctement. Les commandes docker system info et docker system df peuvent fournir un aperçu de l'état du démon et de l'utilisation de l'espace disque par Docker.
Dans des cas rares, interagir directement avec l'API du démon via le socket Unix (/var/run/docker.sock) à l'aide d'outils comme curl peut aider à diagnostiquer des problèmes de communication entre le client CLI et le démon :
curl --unix-socket /var/run/docker.sock http://localhost/infoEnfin, n'oubliez pas l'étape de base : un simple redémarrage du service Docker (sudo systemctl restart docker ou via Docker Desktop) peut parfois résoudre des états internes incohérents ou des problèmes temporaires.