E-NO
DevOps 10 min de lecture

Architecture de débogage des conteneurs Docker expliquée avec des exemples pratiques

calendar_today Publié : 2026-10-16
update Dernière mise à jour : 2026-10-16
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Architecture de débogage des conteneurs Docker expliquée avec des exemples pratiques ».

Introduction

Déboguer une application conteneurisée ressemble souvent à résoudre un mystère. Les processus sont isolés de l'hôte, les systèmes de fichiers sont éphémères et le réseau ajoute des couches d'indirection. Lorsque votre application web ne répond plus ou plante, le chemin vers la résolution est rarement évident. Pour déboguer efficacement, vous devez comprendre l'architecture sous-jacente au débogage des conteneurs Docker : les composants impliqués, la circulation des données entre eux et les défaillances courantes. Ce guide fournit cette vue architecturale, accompagnée d'exemples pratiques, de commandes et d'extraits de configuration que vous pouvez utiliser immédiatement.

Le débogage des conteneurs Docker n'est pas un outil unique, mais une combinaison de fonctionnalités intégrées de Docker et d'utilitaires externes. Les composants principaux comprennent l'interface de ligne de commande Docker, le démon Docker, l'environnement d'exécution de conteneurs (runc ou containerd), les pilotes de journalisation, les commandes exec et inspect, ainsi que les outils de surveillance. En comprenant l'interaction entre ces éléments, vous pourrez diagnostiquer les problèmes plus rapidement et éviter les pièges courants. Ce guide couvre l'inventaire des versions et de l'environnement, la configuration sécurisée, la vérification et les diagnostics, les modes de défaillance et une liste de contrôle opérationnelle.

Tout au long de cet article, nous utiliserons un conteneur d'application web simple comme exemple concret. Il s'agit d'une application Node.js qui plante occasionnellement à cause d'exceptions non gérées, et nous la déboguerons étape par étape. Toutes les commandes ont été testées sur Linux (Ubuntu 22.04) avec Docker Engine 24.0, mais elles devraient fonctionner avec des modifications mineures sur d'autres systèmes.

Inventaire des versions et de l'environnement

Avant de déboguer un conteneur, établissez une base de référence claire. Connaissez la version de Docker, l'image et l'environnement d'exécution du conteneur, ainsi que le système d'exploitation de l'hôte. Ces informations sont souvent essentielles lors de la recherche de problèmes connus ou de la détermination de la compatibilité.

Prérequis

  • Docker Engine 20.10 ou version ultérieure (nous utilisons 24.0).
  • Connaissance de base de la ligne de commande.
  • Un conteneur à déboguer (nous utilisons webapp:1.0).
  • Accès aux journaux du conteneur et capacité d'exécuter des commandes à l'intérieur des conteneurs.

Vérification de la version et des informations de Docker

Exécutez les commandes suivantes sur l'hôte :

docker version --format '{{.Server.Version}}'

Sortie attendue (la vôtre peut différer) :

24.0.5
docker info --format '{{.OperatingSystem}} {{.Architecture}} {{.CgroupDriver}}'

Sortie attendue :

Ubuntu 22.04.3 LTS x86_64 systemd

Inspection du conteneur

Identifiez le conteneur à déboguer :

docker ps -a --filter "name=webapp" --format "table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Names}}"

Exemple de sortie :

CONTAINER ID   IMAGE        STATUS                     NAMES
3f4a5b6c7d8e   webapp:1.0   Up 10 minutes (unhealthy)  webapp

Notez le statut « (unhealthy) » ; cela indique que le contrôle de santé du conteneur échoue. Nous examinerons cela plus tard.

Topologie

Dans une configuration de débogage Docker typique, on trouve :

  • Hôte : exécute le démon Docker et fournit les ressources.
  • Démon Docker (dockerd) : gère les conteneurs, les images, les réseaux et les volumes.
  • Environnement d'exécution de conteneurs (containerd / runc) : crée et exécute réellement les conteneurs.
  • Conteneur : le processus applicatif et ses dépendances.
  • Pilote de journalisation : capture la sortie standard/erreur du conteneur et la transmet à une destination (json-file par défaut).
  • Outils de débogage : docker exec, docker logs, docker inspect, outils système comme strace, tcpdump, etc.

Flux de données : l'application écrit sur la sortie standard/erreur -> environnement d'exécution du conteneur -> pilote de journalisation -> fichier journal ou point de terminaison distant. Flux de contrôle : l'utilisateur lance docker exec -> CLI Docker -> démon -> environnement d'exécution -> exécute la commande dans l'espace de noms du conteneur.

Question rapide 1 sur 2

Quel est l'objectif de l'option `--log-opt max-size=10m` lors de l'exécution d'un conteneur ?

L'option `max-size` de `--log-opt` configure la taille maximale du fichier journal avant sa rotation. Cela permet d'éviter que les fichiers journaux ne grossissent indéfiniment.

Chemin de configuration sécurisé

Avant d'apporter des modifications, mettez en place une configuration de débogage sécurisée. Cela implique d'activer une journalisation appropriée, de configurer des contrôles de santé et de s'assurer de pouvoir exécuter des commandes dans le conteneur sans perturber la production si possible. Nous procéderons de manière ciblée et réversible.

Configuration des pilotes de journalisation

Le pilote de journalisation par défaut de Docker est json-file, qui stocke les journaux sur l'hôte. Pour le débogage, il est souvent utile de configurer un autre pilote ou d'ajuster les options. Nous conserverons json-file mais définirons une taille maximale pour éviter de remplir le disque.

Créez un conteneur avec les options de journalisation :

docker run -d --name webapp \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  -p 8080:8080 \
  webapp:1.0

Cela limite les fichiers journaux à 10 Mo chacun et conserve 3 fichiers après rotation. Si vous devez modifier la journalisation d'un conteneur existant, vous devez le recréer. Pour voir la configuration de journalisation actuelle :

docker inspect --format '{{.HostConfig.LogConfig.Type}} {{.HostConfig.LogConfig.Config}}' webapp

Sortie :

json-file map[max-file:3 max-size:10m]

Mise en place des contrôles de santé

Un contrôle de santé indique à Docker si l'application fonctionne correctement. Pour notre application Node.js, nous pouvons ajouter un point de terminaison HTTP de santé. Modifiez le Dockerfile pour inclure HEALTHCHECK :

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1
CMD ["node", "server.js"]

Reconstruisez l'image :

docker build -t webapp:1.1 .

Exécutez le nouveau conteneur :

docker run -d --name webapp-healthy \
  --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 \
  -p 8080:8080 \
  webapp:1.1

Vérifiez l'état de santé après une minute :

docker ps --format '{{.HealthStatus}}' --filter name=webapp-healthy

Attendu : healthy.

Activation de l'accès exec

Pour le débogage, vous devez exécuter des commandes à l'intérieur du conteneur. Assurez-vous que le conteneur n'est pas exécuté avec --read-only ou un profil de sécurité restreint qui empêche exec. Nous utiliserons docker exec pour un débogage interactif.

Vérification et diagnostics

Maintenant que le conteneur fonctionne avec une journalisation et des contrôles de santé appropriés, nous pouvons diagnostiquer les problèmes. Simulons une défaillance dans notre application Node.js : elle plante lorsqu'un certain point de terminaison est sollicité, à cause d'un rejet de promesse non géré.

Observation des journaux

Tout d'abord, vérifiez les journaux :

docker logs webapp-healthy

Vous pourriez voir quelque chose comme :

Listening on port 8080
...
(node:1) UnhandledPromiseRejectionWarning: Error: Something went wrong
    at /app/server.js:15:11
...

Cela nous indique où se trouve l'erreur. Nous pouvons également suivre les journaux en direct :

docker logs -f --tail 50 webapp-healthy

Exécution de commandes dans le conteneur

Nous pouvons inspecter le processus en cours d'exécution et l'environnement :

docker exec webapp-healthy ps aux

Sortie attendue (simplifiée) :

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.5 723456 45678 ?        Ssl  12:34   0:00 node server.js
root        12  0.0  0.0  15568  2024 ?        Rs   12:35   0:00 ps aux

Si le conteneur est en mauvaise santé, nous pouvons inspecter les journaux du contrôle de santé :

docker inspect --format '{{json .State.Health}}' webapp-healthy

La sortie comprend les entrées de journal des exécutions du contrôle de santé.

Utilisation de docker inspect pour la configuration

docker inspect révèle une mine d'informations :

docker inspect webapp-healthy

Champs clés : NetworkSettings.IPAddress, Mounts, Config.Env, HostConfig.Binds, etc. Pour le débogage, vérifiez les paramètres réseau pour assurer le mappage des ports :

docker inspect --format '{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{"\n"}}{{end}}' webapp-healthy

Sortie :

8080/tcp -> 8080

Copie de fichiers pour analyse

Parfois, vous devez extraire des fichiers d'un conteneur, comme des cœurs de mémoire ou des journaux écrits sur disque. Utilisez docker cp :

docker cp webapp-healthy:/app/server.js ./server.js

Débogage avec strace

Si le processus se comporte de manière étrange, strace peut tracer les appels système. D'abord, installez strace dans le conteneur (s'il n'est pas présent) :

docker exec -it webapp-healthy sh -c "apk add --no-cache strace"

Puis attachez-vous au processus :

docker exec -it webapp-healthy strace -p 1

Cela peut être lourd ; utilisez-le avec prudence sur les conteneurs de production.

Modes de défaillance et récupération

Comprendre les modes de défaillance courants vous aide à vous préparer et à récupérer des problèmes. Nous couvrirons les problèmes typiques : conteneur qui se termine immédiatement, conteneur qui ne répond pas, disque plein à cause des journaux et mauvaise configuration réseau.

Le conteneur se termine immédiatement

Si un conteneur démarre et se termine, vérifiez son code de sortie et ses journaux.

docker ps -a --filter "name=webapp" --format "{{.Status}}"

Exemple :

Exited (1) 10 seconds ago

Puis inspectez les journaux :

docker logs webapp

Souvent, c'est une dépendance manquante ou une erreur de configuration. Corrigez le Dockerfile ou le point d'entrée et redémarrez.

Conteneur qui ne répond pas

Si un conteneur se bloque et ne répond pas aux commandes, il peut être à court de mémoire ou avoir un processus en interblocage. Vérifiez l'utilisation des ressources :

docker stats --no-stream webapp-healthy

Exemple de sortie :

CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O   PIDS
3f4a5b6c7d8e   webapp-healthy    0.00%     45.2MiB / 3.8GiB      1.16%     2.1kB / 0B   0B / 0B     2

Si la mémoire est élevée, envisagez d'augmenter les limites ou de profiler l'application. Vous pouvez également utiliser docker exec pour exécuter des commandes de diagnostic, mais si le conteneur est vraiment bloqué, vous devrez peut-être le redémarrer.

Disque plein à cause des journaux

Si le disque de l'hôte se remplit, la journalisation des conteneurs peut en être la cause. Vérifiez l'utilisation du disque des journaux Docker :

sudo du -sh /var/lib/docker/containers/*/*-json.log

Si un fichier est énorme, faites-le tourner ou supprimez-le. Mieux, configurez la rotation des journaux dès le départ. Pour effacer les journaux sans redémarrer le conteneur, utilisez :

truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log

Obtenez l'ID du conteneur avec docker ps -q.

Mauvaise configuration réseau

Si l'application ne peut pas se connecter à d'autres services, inspectez le réseau :

docker network inspect bridge

Vérifiez si les conteneurs sont sur le même réseau. Pour les réseaux personnalisés, créez-en un :

docker network create mynet

Puis exécutez les conteneurs avec --network mynet. Utilisez docker exec pour tester la connectivité :

docker exec webapp-healthy curl http://database:5432

Étapes de récupération

  • Pour une récupération immédiate, redémarrez le conteneur : docker restart webapp-healthy.
  • Si le problème persiste, recréez le conteneur avec une configuration actualisée.
  • Pour les bugs de code, corrigez l'application et reconstruisez l'image.

Retour en arrière

Conservez les versions d'image précédentes pour pouvoir revenir en arrière :

docker tag webapp:1.1 webapp:stable
docker run -d --name webapp-stable ... webapp:stable

Si la nouvelle version échoue, revenez à l'image stable.

Question rapide 2 sur 2

Quel est le pilote de journalisation par défaut pour Docker ?

Le pilote de journalisation par défaut est `json-file`, qui écrit les données de journal dans des fichiers au format JSON sur le système de fichiers hôte.

Pièges courants et comment les éviter

Même les utilisateurs expérimentés de Docker tombent dans des pièges prévisibles lors du débogage des conteneurs. Voici les plus courants, pourquoi ils surviennent et comment les éviter ou s'en remettre.

Piège 1 : Négliger la rotation des journaux

Pourquoi cela arrive : La configuration de journalisation par défaut stocke toute la sortie du conteneur dans un seul fichier JSON sans limite de taille. Avec le temps, ce fichier peut remplir le disque de l'hôte, provoquant des défaillances à l'échelle du système.

Comment éviter : Définissez toujours des options de rotation des journaux lors de l'exécution des conteneurs, soit via les options --log-opt, soit dans le fichier de configuration du démon Docker (/etc/docker/daemon.json). Par exemple, ajoutez ceci à daemon.json :

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Puis redémarrez le démon Docker.

Récupération : Si le disque est déjà plein, identifiez les gros fichiers journaux avec sudo du -sh /var/lib/docker/containers//-json.log et tronquez-les comme indiqué dans la section précédente. Ensuite, mettez en place la rotation pour éviter la récidive.

Piège 2 : Ignorer l'état du contrôle de santé

Pourquoi cela arrive : De nombreux développeurs ne configurent pas de contrôles de santé pour leurs conteneurs. Sans eux, Docker ne peut pas signaler si l'application fonctionne réellement, seulement si le processus est en cours d'exécution. Un conteneur peut être « Up » mais ne pas répondre.

Comment éviter : Définissez toujours un contrôle de santé dans votre Dockerfile ou lors de l'exécution du conteneur. Utilisez une commande légère qui vérifie la fonctionnalité essentielle de l'application, comme un point de terminaison HTTP ou un script simple. Par exemple :

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

Récupération : Si un conteneur est en mauvaise santé, inspectez les journaux de son contrôle de santé avec docker inspect --format '{{json .State.Health}}' <container> pour comprendre ce qui échoue.

Piège 3 : Modifier un conteneur en cours d'exécution au lieu de le recréer

Pourquoi cela arrive : Il est tentant d'utiliser docker exec pour modifier un conteneur en cours d'exécution (par exemple, installer des paquets manquants) plutôt que de mettre à jour le Dockerfile et de recréer le conteneur. Cependant, ces modifications sont perdues lorsque le conteneur est redémarré ou remplacé, ce qui conduit à des environnements incohérents.

Comment éviter : Traitez les conteneurs comme immuables. Toute modification nécessaire doit être reflétée dans le Dockerfile ou le point d'entrée, et le conteneur doit être recréé. Utilisez docker exec uniquement pour les diagnostics, pas pour les changements persistants.

Récupération : Si vous avez déjà modifié un conteneur en cours d'exécution, documentez les modifications et reconstruisez immédiatement l'image avec ces modifications incorporées.

Piège 4 : Négliger l'isolation réseau

Pourquoi cela arrive : Les conteneurs sur des réseaux différents ne peuvent pas communiquer par défaut. Les développeurs supposent souvent que tous les conteneurs peuvent se joindre, ce qui conduit à des erreurs de connexion refusée.

Comment éviter : Définissez explicitement des réseaux et attachez les conteneurs qui doivent communiquer. Utilisez des réseaux personnalisés pour une meilleure isolation et une résolution DNS. Par exemple :

docker network create backend
docker run -d --network backend --name db postgres
docker run -d --network backend --name webapp myapp

Récupération : Si un conteneur ne peut pas atteindre un autre service, vérifiez docker network inspect <network> pour voir si les deux conteneurs sont sur le même réseau. Sinon, recréez-en un avec le bon indicateur --network.

Piège 5 : Exécuter des conteneurs en tant que root

Pourquoi cela arrive : De nombreuses images de base exécutent les processus en tant que root par défaut. Si l'application est compromise, l'attaquant obtient les privilèges root à l'intérieur du conteneur, ce qui peut potentiellement mener à une compromission de l'hôte.

Comment éviter : Créez toujours un utilisateur non root dans votre Dockerfile et exécutez l'application en tant que cet utilisateur. Par exemple :

RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

Récupération : Si vous avez des conteneurs qui s'exécutent en tant que root, prévoyez de les reconstruire avec un utilisateur non root. C'est particulièrement important pour les environnements de production.

Piège 6 : Utiliser l'étiquette latest en production

Pourquoi cela arrive : L'utilisation de l'étiquette « latest » facilite le tirage de l'image la plus récente, mais ce n'est pas déterministe. Le contenu de l'image peut changer sans avertissement, ce qui entraîne un comportement inattendu et rend le retour en arrière difficile.

Comment éviter : Utilisez des étiquettes de version explicites pour toutes les images, et envisagez d'utiliser des empreintes d'image pour une immuabilité absolue. Par exemple, utilisez myapp:1.4.2 au lieu de myapp:latest.

Récupération : Si vous avez utilisé latest, commencez à étiqueter les images avec des versions spécifiques à l'avenir. Vous pouvez également utiliser docker image inspect myapp:latest pour trouver l'empreinte et l'étiqueter avec une version pour les déploiements actuels.

Liste de contrôle opérationnelle

Utilisez cette liste de contrôle pour le débogage et la maintenance de routine. Chaque élément a un propriétaire (un rôle responsable unique, pas un groupe) et une fréquence d'examen pour assurer la responsabilisation.

ÉtapeActionCommande/ExtraitPropriétaireFréquence d'examen
1Vérifier la version et l'environnement de Dockerdocker version et docker infoIngénieur DevOps (par ex., Priya Shah)Mensuelle ou après les mises à jour de l'hôte
2Lister les conteneurs en cours d'exécution avec leur statutdocker ps -aIngénieur de gardeQuotidienne ou par incident
3Vérifier les journaux du conteneurdocker logs <container> --tail 100Propriétaire de l'application (par ex., Alex Chen)À chaque déploiement ou incident
4Inspecter la configuration du conteneurdocker inspect <container>Ingénieur DevOpsLorsque la configuration change
5Vérifier l'état de santédocker inspect --format '{{.State.Health.Status}}' <container>Ingénieur de gardeSurveillance continue (avec alertes)
6Voir l'utilisation des ressourcesdocker stats --no-streamSRE (par ex., Maria Garcia)Hebdomadaire ou en cas de problème de performance
7Exécuter des commandes de diagnostic dans le conteneurdocker exec -it <container> shDéveloppeur de gardeUniquement pendant le débogage
8Vérifier la configuration de journalisationdocker inspect --format '{{.HostConfig.LogConfig.Type}}' <container>Ingénieur DevOpsAprès la création du conteneur ou mensuellement
9Tester la connectivité réseau depuis le conteneurdocker exec <container> ping <target>Ingénieur réseau (si disponible) ou de gardeLorsque des problèmes réseau sont signalés
10Sauvegarder ou copier les fichiers importants du conteneurdocker cp <container>:<path> <local-path>Propriétaire des donnéesAvant la suppression ou la migration du conteneur
11Nettoyer les conteneurs et images inutilisésdocker system prune (avec prudence)Ingénieur DevOpsHebdomadaire (planifiée)
12Documenter les conclusions et mettre à jour les procédures-Répondant à l'incidentAprès chaque incident significatif

Conclusion

Le débogage des conteneurs Docker nécessite une approche systématique fondée sur la compréhension de l'architecture. En inventoriant votre environnement, en configurant la journalisation et les contrôles de santé de manière sécurisée, en utilisant les commandes de diagnostic de manière efficace et en vous préparant aux défaillances courantes, vous pouvez résoudre les problèmes rapidement et prévenir les futurs. Les commandes et configurations de ce guide fournissent une base solide. Commencez par appliquer ces techniques à vos conteneurs actuels et construisez une liste de contrôle de débogage adaptée à vos applications. N'oubliez pas de versionner les images pour un retour en arrière facile et de toujours surveiller les journaux et l'état de santé. Avec la pratique, le débogage des conteneurs devient une routine gérable plutôt qu'un mystère.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO