Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 1013 minIntermédiaire

Journaux et supervision des conteneurs

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • choisir un pilote de journalisation et régler la rotation ;
  • centraliser les journaux des conteneurs vers un serveur syslog ;
  • superviser des conteneurs avec le modèle Docker de Zabbix ;
  • repérer les événements Docker suspects avec Wazuh.

4 exercices corrigés

Superviser des conteneurs, c'est collecter leurs journaux (ce qu'ils écrivent sur leur sortie standard), surveiller leur état et leur santé, et mesurer leur consommation de processeur, de mémoire et de disque, pour être alerté avant que les utilisateurs ne le soient. Ce chapitre règle la journalisation de Docker (pilotes, rotation, centralisation vers le serveur de journaux), puis branche srv-gestion sur Zabbix et Grafana pour les métriques et les alertes, et sur Wazuh pour les événements de sécurité.

Où vont les journaux d'un conteneur

Une application conteneurisée écrit ses journaux sur sa sortie standard et sa sortie d'erreur, pas dans des fichiers. Le démon les capture et les confie à un pilote de journalisation (logging driver). docker logs et docker compose logs les relisent :

bash
docker compose logs --tail 100 -t api      # 100 dernières lignes, avec l'horodatage de Docker
docker compose logs -f --since 15m         # tous les services, en continu, depuis 15 minutes
PiloteOù vont les journauxdocker logs
json-file (par défaut)Un fichier JSON par conteneur, sous /var/lib/docker/containers/, sans rotation par défautOui
localUn format binaire compact, avec rotation et compressionOui
journaldLe journal de systemd de l'hôteOui, et journalctl CONTAINER_NAME=gestion-api-1
syslogUn serveur syslog, local ou distantOui, grâce au cache local de Docker
gelf, fluentdGraylog, Fluentd et outils compatiblesOui, grâce au cache local
noneNulle partNon

Le pilote peut aussi se régler service par service dans compose.yaml :

yaml
services:
  api:
    logging:
      driver: local
      options:
        max-size: "20m"
        max-file: "5"

Centraliser les journaux vers srv-journaux

Des journaux qui restent sur srv-gestion disparaissent avec lui, et un attaquant qui prend la main sur le serveur peut les effacer. Chez Sorbier, tous les serveurs envoient leurs journaux à srv-journaux (192.168.10.180), en syslog chiffré par TLS sur le port TCP 6514, la même règle que pour le serveur web de la DMZ (cours Cybersécurité des infrastructures). Deux façons de faire :

1. Le pilote journald, et l'envoi par l'hôte. Les conteneurs écrivent dans le journal de systemd de srv-gestion, et le service rsyslog de l'hôte, déjà configuré pour transmettre ses journaux à srv-journaux, transmet aussi ceux des conteneurs. Dans daemon.json :

json
{
  "log-driver": "journald",
  "log-opts": {
    "tag": "{{.Name}}"
  }
}

Si srv-journaux est injoignable, rien ne se perd : les journaux attendent dans le journal local, et les conteneurs ne sont pas gênés.

2. Le pilote syslog, directement depuis Docker, service par service :

yaml
services:
  proxy:
    logging:
      driver: syslog
      options:
        syslog-address: "tcp+tls://192.168.10.180:6514"
        syslog-tls-ca-cert: "/etc/ssl/certs/sorbier-ca.pem"
        syslog-format: "rfc5424"
        tag: "{{.Name}}"

Plus direct, mais plus fragile : par défaut, si le serveur syslog est injoignable au démarrage, le conteneur ne démarre pas.

Surveiller l'état et la santé

Un conteneur peut être en marche sans que son service fonctionne. Trois signaux à surveiller :

SignalOù le lireCe qu'il révèle
L'état (running, exited, restarting)docker ps -a, docker inspect -f '{{.State.Status}}'Un service arrêté ou qui redémarre en boucle
La santé (healthy, unhealthy)docker ps, docker inspect -f '{{.State.Health.Status}}'Un service lancé mais qui ne répond plus
Le nombre de redémarragesdocker inspect -f '{{.RestartCount}}'Un service qui plante et repart, masqué par restart: unless-stopped

Le flux d'événements du démon montre tout ce qui arrive, en direct :

bash
docker events --filter event=die --filter event=health_status --filter event=oom
text
2026-11-03T14:02:11.508+01:00 container health_status: unhealthy 8b1e… (image=ghcr.io/sorbier/sorbier-frais:2.5.0, name=gestion-api-1)
2026-11-03T14:02:41.932+01:00 container die 8b1e… (exitCode=1, image=ghcr.io/sorbier/sorbier-frais:2.5.0, name=gestion-api-1)

Les métriques : docker stats et au-delà

docker stats donne la consommation instantanée de chaque conteneur (chapitre 3). Pour garder un historique, tracer des courbes et être alerté, on branche l'hôte sur l'outil de supervision de l'entreprise. Ce qu'il faut surveiller sur un hôte Docker :

MesureSeuil d'alerte typiquePourquoi
Espace libre de /var/lib/dockerMoins de 20 %Images, journaux et volumes remplissent le disque
Mémoire d'un conteneur par rapport à sa limitePlus de 90 %Au-delà, le noyau tue le processus (code 137, OOMKilled)
Conteneurs arrêtés qui devraient tournerUn seulService indisponible
Conteneurs unhealthyUn seulService qui ne répond plus
Redémarrages par heurePlus de quelques-unsApplication qui plante en boucle
Date d'expiration du certificat publiéMoins de 21 joursSite inaccessible le jour de l'expiration

Superviser Docker avec Zabbix et Grafana

Chez Sorbier, les métriques et les alertes sont dans Zabbix, et les tableaux de bord dans Grafana, branché sur Zabbix (cours Supervision). Zabbix fournit un modèle prêt à l'emploi, « Docker by Zabbix agent 2 » : l'agent 2, installé sur srv-gestion, interroge l'API du démon par son socket et découvre automatiquement chaque conteneur (état, processeur, mémoire, réseau, redémarrages), avec des déclencheurs prêts à l'emploi.

  1. Sur srv-gestion, installe l'agent 2 depuis le dépôt de Zabbix et déclare le serveur Zabbix dans /etc/zabbix/zabbix_agent2.conf (Server= et ServerActive=).

  2. Donne à l'agent l'accès au socket. La documentation propose d'ajouter l'utilisateur zabbix au groupe docker, puis de redémarrer l'agent :

    bash
    sudo usermod -aG docker zabbix
    sudo systemctl restart zabbix-agent2
    
  3. Dans l'interface de Zabbix, menu Data collection > Hosts, ouvre l'hôte srv-gestion et ajoute le modèle « Docker by Zabbix agent 2 » à côté de « Linux by Zabbix agent ».

  4. Vérifie la remontée dans Monitoring > Latest data, filtré sur l'hôte.

Complète la supervision de l'hôte par celle du service rendu : un scénario web Zabbix qui ouvre https://gestion.ad.sorbier.example/api/health toutes les minutes vérifie, du point de vue des utilisateurs, que la chaîne complète (DNS, pare-feu, proxy, API, base) fonctionne. L'expiration du certificat se surveille avec le modèle « Website certificate by Zabbix agent 2 » : sur l'hôte srv-gestion, la macro {$CERT.WEBSITE.HOSTNAME} reçoit le nom gestion.ad.sorbier.example, et la macro {$CERT.EXPIRY.WARN} (7 jours par défaut) passe à 21 jours, pour avoir le temps de faire signer un nouveau certificat.

Les événements de sécurité avec Wazuh

La supervision dit si le service fonctionne ; la détection dit si quelqu'un fait quelque chose d'anormal. L'agent Wazuh installé sur srv-gestion peut écouter les événements de Docker grâce à son module Docker listener : chaque pull, création, démarrage, arrêt et chaque docker exec dans un conteneur remonte au serveur Wazuh. On l'active dans /var/ossec/etc/ossec.conf de l'agent :

xml
<wodle name="docker-listener">
  <disabled>no</disabled>
</wodle>

Le module est écrit en Python et demande la bibliothèque Python docker sur l'hôte, dans la version indiquée par la documentation de ta version de Wazuh. Ce qu'on cherche à repérer :

  • un docker exec dans un conteneur de production en dehors d'une intervention planifiée ;
  • la création d'un conteneur privilégié, ou qui monte la racine de l'hôte ou le socket Docker ;
  • une image inconnue téléchargée sur le serveur ;
  • un conteneur qui redémarre en boucle (souvent le signe d'un problème, parfois d'une attaque).

La collecte des journaux de sécurité et la corrélation des alertes sont traitées dans le cours Cybersécurité des infrastructures.

Exercices

Exercice 1 sur 4 Le disque plein Réussi À revoir

Un lundi matin, plus aucun conteneur de srv-gestion n'arrive à écrire, et df -h montre /var/lib/docker plein à 100 %. sudo du -sh /var/lib/docker/containers/* montre un dossier de 38 Go. Explique la cause probable, rétablis le service et évite que cela se reproduise.

Voir la réponseMasquer la réponse de l'exercice 1

Cause probable : un conteneur bavard (souvent en boucle d'erreur) dont les journaux, avec le pilote json-file sans rotation, ont grossi jusqu'à remplir le disque. Le dossier de 38 Go est celui de ce conteneur ; son fichier *-json.log contient les journaux.

Rétablir :

  1. identifier le conteneur (le nom du dossier est son identifiant : docker ps -a --no-trunc | grep <début de l'identifiant>) et lire la fin de ses journaux pour comprendre l'erreur ;
  2. libérer l'espace : recréer le conteneur (docker compose up -d --force-recreate <service>), ce qui supprime l'ancien fichier, ou à défaut le vider avec sudo truncate -s 0 sur le fichier *-json.log ;
  3. corriger l'erreur de l'application qui produisait les journaux en boucle.

Éviter : rotation dans /etc/docker/daemon.json ("log-driver": "local" ou json-file avec max-size et max-file), puis recréer tous les conteneurs pour qu'ils l'appliquent ; alerte de supervision quand l'espace libre de /var/lib/docker passe sous 20 %.

Tu avais trouvé ?

Exercice 2 sur 4 Choisir la centralisation Réussi À revoir

Le technicien hésite entre le pilote syslog vers srv-journaux et le pilote journald avec envoi par rsyslog. Srv-journaux est redémarré chaque mois pour ses mises à jour. Que conseilles-tu ?

Voir la réponseMasquer la réponse de l'exercice 2

Le pilote journald avec envoi par rsyslog depuis l'hôte. Pendant le redémarrage mensuel de srv-journaux, les journaux restent dans le journal local de srv-gestion et rsyslog les renvoie quand le serveur revient. Avec le pilote syslog direct, un conteneur créé ou redémarré pendant cette fenêtre ne démarrerait pas (le pilote ne peut pas joindre le serveur), ce qui transformerait une maintenance du serveur de journaux en panne des applications.

Tu avais trouvé ?

Exercice 3 sur 4 Interpréter des événements Réussi À revoir

docker events a enregistré cette nuit, sur srv-gestion, la séquence suivante (simplifiée). Que s'est-il probablement passé, et que fais-tu ?

text
02:14:07 image pull alpine:3.24
02:14:09 container create (image=alpine:3.24, name=maintenance)
02:14:09 container start (name=maintenance)
02:14:40 container die (exitCode=0, name=maintenance)
02:14:41 container destroy (name=maintenance)

Aucune intervention n'était planifiée, et docker inspect n'est plus possible puisque le conteneur a été détruit.

Voir la réponseMasquer la réponse de l'exercice 3

Quelqu'un (ou un programme) qui a accès au démon Docker a téléchargé une image, lancé un conteneur jetable pendant une trentaine de secondes, puis l'a supprimé, en pleine nuit et sans intervention prévue. Avec l'accès au socket, un tel conteneur peut monter la racine de l'hôte et y modifier n'importe quoi (ajouter une clé SSH, un compte, une tâche planifiée) : c'est le schéma d'une prise de contrôle de l'hôte.

À faire : traiter comme un incident de sécurité. Prévenir le responsable ; ne pas éteindre le serveur à la légère (les traces en mémoire seraient perdues) ; rechercher qui avait accès au démon à cette heure (journaux d'authentification SSH, membres du groupe docker, jetons d'accès de la CI) ; vérifier les modifications récentes sur l'hôte (/root/.ssh/authorized_keys, /etc/passwd, tâches planifiées, services systemd) ; conserver les journaux de srv-journaux et de Wazuh comme preuves. La conduite à tenir est détaillée dans le cours Réponse à incident.

Tu avais trouvé ?

Exercice 4 sur 4 Les alertes à créer Réussi À revoir

Antoine Mercier te demande la liste des alertes à configurer dans Zabbix pour l'application sorbier-frais. Propose-en cinq, avec leur seuil et leur sévérité.

Voir la réponseMasquer la réponse de l'exercice 4
AlerteSeuilSévérité
Scénario web https://gestion.ad.sorbier.example/api/health en échec3 échecs consécutifs (3 minutes)Haute : le service est indisponible pour les utilisateurs
Conteneur gestion-api-1 ou gestion-bdd-1 arrêtéDès qu'il n'est plus runningHaute
Conteneur redémarré plusieurs foisPlus de 3 redémarrages en une heureMoyenne : l'application plante, même si elle repart
Espace libre de /var/lib/dockerMoins de 20 % (moyenne), moins de 10 % (haute)Moyenne puis haute
Expiration du certificat de gestion.ad.sorbier.exampleMoins de 21 joursMoyenne : le temps de faire signer un nouveau certificat

D'autres réponses sont possibles : mémoire de l'API proche de sa limite, export nocturne de la base absent, conteneur unhealthy.

Tu avais trouvé ?

Chapitre terminé !

Fais les 4 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Sécuriser Docker : images, secrets, rootless et socketRevoir le sommaire du cours