Introduction
Les pilotes de journalisation Docker contrôlent la façon dont les journaux de conteneurs sont collectés et stockés. Le pilote par défaut json-file écrit les journaux localement, mais d'autres pilotes peuvent les envoyer vers un système distant, ajouter des métadonnées ou réduire l'utilisation du disque. Mettre en place un laboratoire local vous permet de tester le comportement des pilotes sans toucher aux environnements de production.
Ce guide présente un laboratoire complet de pilotes de journalisation Docker sur un hôte Linux unique. Vous allez inspecter la configuration actuelle, configurer et tester plusieurs pilotes, apprendre à faire tourner et lire les journaux, et vous entraîner à la récupération en cas de problème. Chaque étape inclut des commandes à exécuter et les résultats attendus, afin de pouvoir vérifier chaque résultat avant de continuer.
Les exemples supposent Docker Engine 24.0 ou version ultérieure, avec la CLI Docker et Docker Compose v2 installés. Sans accès au journal systemd ou à rsyslog, certains pilotes peuvent ne pas fonctionner comme indiqué. Nous aborderons les prérequis pour chaque pilote.
Inventaire de la version et de l'environnement
Avant de modifier toute configuration, enregistrez votre version de Docker, le pilote de stockage et la configuration de journalisation actuelle. Cela vous donne un point de restauration et vous aide à repérer les options incompatibles.
Exécutez ces commandes et sauvegardez la sortie :
docker version --format '{{.Server.Version}}'
docker info --format 'Storage Driver: {{.Driver}}'
docker info --format 'Logging Driver: {{.LoggingDriver}}'
La sortie attendue sur une installation Docker fraîche peut ressembler à ceci :
24.0.7
Storage Driver: overlay2
Logging Driver: json-file
Si votre sortie diffère, notez-la. Par exemple, certaines images cloud définissent journald ou syslog comme pilote par défaut. Le laboratoire suppose que vous pouvez remplacer le pilote par conteneur au moment de l'exécution, ce que toutes les versions modernes de Docker prennent en charge.
Vérifiez également que vous avez la permission d'exécuter Docker sans sudo. Si ce n'est pas le cas, ajoutez votre utilisateur au groupe docker et reconnectez-vous. Ce n'est pas strictement requis, mais cela évite les erreurs de permission lors de la lecture des fichiers journaux.
Chemin de configuration sûr
Nous allons configurer chaque pilote de journalisation avec un ensemble minimal d'options, puis exécuter un conteneur qui écrit des lignes de journal prévisibles. Cela permet de garder les modifications petites et faciles à annuler.
Pilote json-file par défaut et rotation des journaux
Le pilote json-file stocke les journaux sous forme d'objets JSON dans /var/lib/docker/containers/<container-id>/<container-id>-json.log. Sans rotation, ce fichier peut croître jusqu'à remplir le disque. La meilleure pratique de production consiste à définir max-size et max-file.
Démarrez un conteneur avec des paramètres de rotation explicites :
docker run -d --name log-json \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
alpine sh -c 'while true; do echo "$(date) hello from json-file"; sleep 1; done'
Cela écrit une ligne par seconde. Pour créer suffisamment de données pour la rotation, vous pouvez temporairement réduire max-size à 1k dans un second conteneur :
docker run -d --name log-rotate-test \
--log-driver json-file \
--log-opt max-size=1k \
--log-opt max-file=3 \
alpine sh -c 'while true; do echo "$(date) rotate me"; done'
Après une minute environ, listez les fichiers journaux :
sudo ls -lh /var/lib/docker/containers/$(docker inspect -f '{{.Id}}' log-rotate-test)/
Vous devriez voir plusieurs fichiers se terminant par -json.log, -json.log.1, -json.log.2, et éventuellement un fichier compressé .gz, selon votre version de Docker. Cela confirme que la rotation fonctionne.
Arrêtez et supprimez les conteneurs de test avant de continuer :
docker rm -f log-json log-rotate-test
Pilote syslog
Le pilote syslog envoie les journaux vers un démon syslog. Sur la plupart des hôtes Linux, rsyslog ou syslog-ng est déjà en cours d'exécution. Si ce n'est pas le cas, installez rsyslog :
sudo apt update && sudo apt install -y rsyslog # Debian/Ubuntu
sudo systemctl start rsyslog
Exécutez un conteneur utilisant le pilote syslog :
docker run -d --name log-syslog \
--log-driver syslog \
--log-opt syslog-address=udp://127.0.0.1:514 \
--log-opt tag="docker/{{.Name}}" \
alpine sh -c 'echo "syslog test from container" && sleep 60'
Vérifiez le syslog de l'hôte :
sudo tail -n 5 /var/log/syslog | grep 'syslog test'
La sortie attendue inclut une ligne avec le tag docker/log-syslog et le message. Si vous ne voyez rien, confirmez que rsyslog écoute sur UDP 514 :
sudo ss -ulnp | grep 514
La sortie devrait montrer un processus comme rsyslogd écoutant sur 0.0.0.0:514. Sinon, éditez /etc/rsyslog.conf et décommentez les lignes pour la réception UDP syslog, puis redémarrez rsyslog.
Arrêtez le conteneur après vérification :
docker rm -f log-syslog
Pilote journald
Le pilote journald écrit les journaux dans le journal systemd. Cela nécessite que le démon Docker s'exécute sur un hôte avec systemd. Vérifiez si journald est disponible :
systemctl is-active systemd-journald
Sortie attendue : active. Si elle indique inactive ou failed, vous devez le démarrer avec sudo systemctl start systemd-journald.
Exécutez un conteneur avec le pilote journald :
docker run -d --name log-journald \
--log-driver journald \
--log-opt tag="docker-journald-test" \
alpine sh -c 'echo "journald test" && sleep 60'
Lisez le journal depuis le journal systemd :
journalctl CONTAINER_NAME=log-journald --no-pager
La sortie attendue inclut la ligne journald test avec des métadonnées systemd. Si vous voyez une erreur de permission, exécutez journalctl avec sudo ou assurez-vous que votre utilisateur est dans le groupe systemd-journal.
Pilote fluentd
Le pilote fluentd envoie les journaux vers une instance Fluentd. C'est utile lorsque vous exécutez déjà Fluentd pour l'agrégation de journaux. Pour un laboratoire rapide, démarrez un conteneur Fluentd qui écoute sur le port TCP 24224 et écrit les journaux transférés sur stdout.
Créez un fichier de configuration Fluentd minimal fluent.conf :
<source>
@type forward
port 24224
</source>
<match **>
@type stdout
</match>
Exécutez Fluentd :
docker run -d --name fluentd-lab \
-p 24224:24224 \
-v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf \
fluent/fluentd:v1.16-1
Attendez quelques secondes, puis exécutez un conteneur qui utilise le pilote fluentd :
docker run --rm --name log-fluentd \
--log-driver fluentd \
--log-opt fluentd-address=127.0.0.1:24224 \
alpine echo "fluentd test from container"
Vérifiez les journaux de Fluentd pour voir l'entrée transmise :
docker logs fluentd-lab | tail -n 3
La sortie attendue inclut une ligne contenant "fluentd test from container" au format d'événement Fluentd. Si la connexion échoue, vérifiez que Fluentd écoute :
docker logs fluentd-lab | grep 'listening'
Vous devriez voir une ligne comme listening fluent socket on 0.0.0.0:24224.
Arrêtez Fluentd lorsque vous avez terminé :
docker rm -f fluentd-lab
Pilote gelf (optionnel)
Le pilote gelf envoie les journaux vers un point de terminaison Graylog ou autre compatible GELF. Pour un laboratoire, vous pouvez utiliser un simple écouteur UDP pour tester le format. Voici un serveur UDP Python rapide qui imprime les datagrammes reçus :
docker run --rm -d --name gelf-listener \
-p 12201:12201/udp \
python:3.11-alpine python -c "
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('0.0.0.0', 12201))
while True:
data, addr = s.recvfrom(65535)
print(data.decode(), flush=True)
"
Maintenant, exécutez un conteneur qui journalise vers GELF UDP :
docker run --rm --name log-gelf \
--log-driver gelf \
--log-opt gelf-address=udp://127.0.0.1:12201 \
alpine echo "gelf test"
Vérifiez la sortie de l'écouteur :
docker logs gelf-listener
Vous devriez voir une charge utile JSON GELF contenant le message gelf test. Sinon, vérifiez le mappage du port UDP avec docker port gelf-listener.
Nettoyez :
docker rm -f gelf-listener
Vérification et diagnostic
Après avoir configuré un pilote, vous devez confirmer que les journaux circulent réellement et que le pilote ne laisse pas passer silencieusement des messages.
Vérifier la sélection du pilote
Utilisez docker inspect pour voir quel pilote de journalisation un conteneur utilise et ses options :
docker inspect -f '{{.HostConfig.LogConfig.Type}} {{.HostConfig.LogConfig.Config}}' <container-name>
Par exemple, pour le conteneur log-json que vous avez exécuté précédemment, la sortie serait :
json-file map[max-file:3 max-size:10m]
Exécutez cette commande pour chaque conteneur après sa création afin de détecter les fautes de frappe dans les noms de pilotes ou les options.
Lire les journaux avec docker logs
docker logs fonctionne pour la plupart des pilotes, mais son comportement peut différer. Les pilotes json-file et journald prennent en charge docker logs nativement. Les pilotes syslog et fluentd ne renvoient pas les journaux via docker logs ; vous devez interroger la destination externe.
Testez ce comportement :
docker logs log-syslog
Attendu : une erreur comme the logging driver "syslog" does not support the "logs" subcommand ou aucune sortie du tout. C'est une limitation connue. Planifiez vos diagnostics en conséquence : pour les pilotes distants, vérifiez le point de terminaison de réception au lieu de docker logs.
Inspecter les fichiers journaux sur le disque
Pour le pilote json-file, vous pouvez lire directement le fichier journal pour voir la structure JSON :
sudo cat /var/lib/docker/containers/$(docker inspect -f '{{.Id}}' <container>) /<container>-json.log | head -n 2
Chaque ligne est un objet JSON avec les clés log, stream et time. Par exemple :
{"log":"hello from json-file\n","stream":"stdout","time":"2025-03-20T15:04:05Z"}
C'est utile pour les scripts ou lors du débogage d'outils d'analyse de journaux.
Vérifier les métriques du pilote
Docker expose les erreurs du pilote de journalisation dans les journaux du démon. Pour voir si le démon a des difficultés avec un pilote, consultez le journal du démon Docker :
sudo journalctl -u docker.service --since "10 minutes ago" | grep -i 'log'
Recherchez des messages comme Failed to log message ou des erreurs spécifiques au pilote. Pour le pilote syslog, une erreur courante est connection refused si l'adresse syslog est incorrecte.
Modes de défaillance et récupération
Les pilotes de journalisation peuvent échouer de manière non immédiatement évidente. Connaître les modes de défaillance courants vous aide à récupérer rapidement et à concevoir des configurations de journalisation robustes.
Défaillance : les journaux json-file remplissent le disque
Symptôme : Les conteneurs cessent d'écrire des journaux, ou le démon Docker signale no space left on device. La cause racine est généralement l'absence de rotation des journaux.
Récupération :
- Trouvez les fichiers journaux les plus volumineux :
sudo find /var/lib/docker/containers -name '*-json.log' -size +100M -ls
- Tronquez immédiatement les journaux surdimensionnés pour libérer de l'espace :
sudo truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log
- Prévenez la récurrence en définissant
max-sizeetmax-filesur le conteneur. Vous pouvez également définir des valeurs par défaut globales dans le fichier de configuration du démon/etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Redémarrez Docker après avoir modifié daemon.json :
sudo systemctl restart docker
Remarque : Ce redémarrage arrêtera tous les conteneurs en cours d'exécution. Faites-le pendant une fenêtre de maintenance.
Défaillance : le pilote syslog ne peut pas se connecter
Symptôme : Le conteneur démarre, mais aucun journal n'apparaît dans /var/log/syslog. Le journal du démon Docker affiche connection refused pour l'adresse syslog.
Récupération :
- Vérifiez que le démon syslog est en cours d'exécution et écoute sur le socket attendu :
sudo ss -ulnp | grep 514
- Si rien n'écoute, démarrez rsyslog :
sudo systemctl start rsyslog
- Si vous exécutez un serveur syslog conteneurisé, assurez-vous que son port est publié correctement. Pour l'exemple précédent, le récepteur syslog utilisait
udp://127.0.0.1:514. Si vous exécutez le récepteur dans un conteneur, vous devez publier le port UDP 514 et utiliser l'IP de l'hôte.
- Pour éviter les échecs de connexion futurs, ajoutez une nouvelle tentative et un délai d'attente plus long aux options du pilote :
--log-opt syslog-address=udp://127.0.0.1:514 \
--log-opt syslog-retries=5 \
--log-opt syslog-timeout=10s
Défaillance : le pilote journald perd des journaux au redémarrage
Symptôme : Les journaux d'un conteneur sont manquants après son redémarrage. Le pilote journald étiquette les journaux avec l'ID du conteneur, pas le nom. Si le conteneur est supprimé et recréé, l'ID change et les anciens journaux sont plus difficiles à trouver.
Récupération :
- Utilisez l'ID du conteneur pour interroger les journaux :
journalctl CONTAINER_ID=<full-container-id>
- Ajoutez un tag personnalisé incluant le nom du conteneur pour faciliter le filtrage :
--log-opt tag="myapp-{{.Name}}"
Puis interrogez avec :
journalctl SYSLOG_IDENTIFIER=myapp-<name>
- Dans les fichiers Compose, vous pouvez définir un nom de conteneur stable avec
container_namepour rendre le tag prévisible.
Défaillance : les tampons du pilote fluentd se remplissent
Symptôme : Les journaux du conteneur sont retardés, ou le pilote fluentd signale un débordement de tampon. Le pilote fluentd met en mémoire tampon les journaux lorsque le point de terminaison Fluentd est lent ou inaccessible. Si le tampon se remplit, le conteneur peut bloquer ou abandonner des journaux.
Récupération :
- Vérifiez le journal du démon Docker pour les erreurs fluentd :
sudo journalctl -u docker.service | grep fluentd
- Augmentez la limite de tampon fluentd si vous vous attendez à des rafales :
--log-opt fluentd-buffer-limit=64m
- Assurez-vous que le point de terminaison Fluentd a une capacité suffisante. Ajustez les intervalles de vidage et les tailles de tampon côté serveur.
- Pour la production, utilisez un collecteur de journaux dédié avec une file d'attente appropriée, comme Fluentd avec un tampon fichier.
Défaillance : le pilote gelf perd des journaux via UDP
Symptôme : Certains journaux n'apparaissent jamais au point de terminaison GELF. UDP est sans connexion et ne garantit pas la livraison. Sous charge ou en cas de problèmes réseau, des paquets peuvent être perdus.
Récupération :
- Utilisez TCP au lieu d'UDP pour GELF si votre point de terminaison le prend en charge :
--log-opt gelf-address=tcp://127.0.0.1:12201
- Augmentez le
gelf-compression-levelpour réduire la bande passante, mais cela n'empêche pas la perte UDP. Pour une livraison fiable, utilisez un pilote qui prend en charge TCP ou une file de messages.
- Surveillez le point de terminaison pour les numéros de séquence manquants ou les lacunes dans les journaux.
Pièges courants et comment les éviter
Plusieurs erreurs reviennent fréquemment lorsque l'on travaille avec les pilotes de journalisation Docker en laboratoire ou en production. En être conscient permet de gagner du temps et d'éviter la perte de données.
Ignorer la prise en charge de docker logs par le pilote
Beaucoup d'utilisateurs supposent que docker logs fonctionne pour tous les pilotes. Ce n'est pas le cas. Les pilotes json-file, journald et local prennent en charge docker logs. Les pilotes syslog, fluentd, gelf et awslogs ne le prennent pas en charge. Si vous comptez sur docker logs pour le débogage, choisissez un pilote compatible.
Comment éviter : Avant de sélectionner un pilote, vérifiez la documentation Docker pour sa prise en charge de docker logs. Testez avec un petit conteneur tôt.
Ne pas définir la rotation des journaux pour json-file
Le pilote json-file par défaut n'a pas de limite de taille. Au fil des mois, les journaux peuvent consommer tout l'espace disque, provoquant des défaillances de Docker et d'autres services.
Comment éviter : Définissez toujours max-size et max-file sur chaque conteneur utilisant json-file. Mieux encore, définissez des valeurs par défaut globales dans la configuration du démon.
Utiliser des montages bind pour les fichiers journaux sans permissions appropriées
Lorsque vous montez un répertoire de l'hôte pour stocker les fichiers journaux, l'utilisateur du conteneur peut ne pas avoir la permission d'écriture, ce qui empêche l'application de démarrer.
Comment éviter : Vérifiez l'utilisateur du conteneur et les permissions du montage. Utilisez plutôt un volume nommé :
docker volume create app-logs
docker run -d --name app \
-v app-logs:/var/log/app \
--log-driver json-file \
myapp
Les volumes nommés sont gérés par Docker et gèrent les permissions plus élégamment.
Mélanger les options du pilote de journalisation avec les paramètres au niveau du démon
Si vous définissez un pilote de journalisation global dans daemon.json mais que vous passez aussi --log-driver sur le conteneur, l'option du conteneur remplace le global. Cela peut conduire à une journalisation incohérente.
Comment éviter : Documentez le pilote prévu pour chaque service. Utilisez des options explicites au niveau du conteneur uniquement pour les cas spéciaux. Vérifiez avec docker inspect après le démarrage.
Oublier de publier les ports UDP pour les récepteurs de journalisation distants
Lorsque vous exécutez un récepteur syslog ou GELF dans un conteneur, vous devez publier son port UDP. Omettre -p 514:514/udp entraîne un échec silencieux ; le conteneur émetteur ne peut pas joindre le récepteur sur localhost.
Comment éviter : Vérifiez toujours les mappages de ports avec docker port <receiver-container>. Testez la connectivité avec nc -u <host> <port> avant de vous fier à la configuration.
Ne pas nettoyer les conteneurs et fichiers de laboratoire
Après les tests, les conteneurs orphelins et les fichiers de configuration résiduels peuvent interférer avec les expériences ultérieures ou consommer des ressources.
Comment éviter : Gardez un script de nettoyage. Par exemple :
docker rm -f log-json log-syslog log-journald log-fluentd log-gelf
rm -f fluent.conf
Exécutez régulièrement docker system prune dans un environnement de laboratoire, mais soyez prudent sur les hôtes partagés ou de production.
Liste de contrôle des opérations
Utilisez cette liste de contrôle chaque fois que vous déployez ou modifiez un pilote de journalisation Docker dans un environnement de laboratoire ou de type production.
| Étape | Action | Responsable | Fréquence de révision |
|---|---|---|---|
| 1 | Confirmer la version de Docker et les valeurs par défaut du démon de journalisation avec docker info | Ingénieur plateforme | Mensuelle |
| 2 | Documenter la destination des journaux prévue et la politique de conservation par service | Responsable DevOps | Trimestrielle |
| 3 | Appliquer la rotation des journaux pour le pilote json-file globalement dans daemon.json | Ingénieur plateforme | Sur changement |
| 4 | Tester chaque pilote avec un conteneur jetable et vérifier les journaux à destination | Développeur | À chaque déploiement |
| 5 | Vérifier l'utilisation du disque et les tailles des journaux hebdomadairement | Équipe de surveillance | Hebdomadaire |
| 6 | Examiner la compatibilité du pilote avec docker logs pour les besoins de débogage | Développeur | Par service |
| 7 | Effectuer un exercice de défaillance : arrêter le récepteur de journaux et observer le comportement du pilote | SRE | Trimestrielle |
| 8 | Mettre à jour la documentation après tout changement de pilote | Rédacteur technique | Sur changement |
Chaque élément a un seul responsable chargé de l'exécution et du suivi. La fréquence de révision garantit que la liste de contrôle reste pertinente à mesure que l'infrastructure évolue.
Exemple de configuration utilisant Docker Compose
Un fichier Compose complet pour un service web avec journalisation json-file et rotation :
version: '3.8'
services:
web:
image: nginx:1.25
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
deploy:
resources:
limits:
memory: 128M
Pour un service qui envoie des journaux à un sidecar Fluentd, vous pouvez définir :
services:
app:
image: myapp:latest
logging:
driver: fluentd
options:
fluentd-address: "fluentd:24224"
tag: "app.{{.Name}}"
fluentd:
image: fluent/fluentd:v1.16-1
ports:
- "24224:24224"
volumes:
- ./fluent.conf:/fluentd/etc/fluent.conf
Cela garde la configuration de journalisation visible et sous contrôle de version.
Conclusion
Un laboratoire local pour les pilotes de journalisation Docker vous offre un environnement sûr pour comprendre le comportement des pilotes, tester les options de configuration et vous entraîner à la récupération. En suivant les étapes de ce guide, vous avez configuré et vérifié les pilotes json-file, syslog, journald, fluentd et gelf, appris à lire les journaux de différentes destinations et vous êtes préparé aux défaillances courantes.
Rappelez-vous ces pratiques clés :
- Toujours définir la rotation des journaux pour les pilotes locaux.
- Vérifier si un pilote prend en charge
docker logsavant de s'y fier pour le débogage. - Vérifier la connectivité vers les points de terminaison de journaux distants du point de vue du conteneur.
- Utiliser
docker inspectpour confirmer le pilote de journalisation effectif et ses options. - Garder un plan de restauration : stocker la configuration précédente du démon et les commandes d'exécution des conteneurs.
Pour la production, choisissez un pilote de journalisation qui correspond à votre infrastructure de journaux centrale et à vos besoins de conservation. Testez-le avec des volumes de journaux réalistes et un test de charge. Documentez le comportement en cas de défaillance et les seuils de surveillance. Une bonne configuration de journalisation n'est pas statique ; elle nécessite une révision et un ajustement périodiques.
Commencez par un changement à faible risque dans votre laboratoire, observez le résultat, puis appliquez-le à un environnement de préproduction avant la production. Cette approche incrémentale renforce la confiance et réduit le risque de perte de journaux ou de perturbation du service.