Le moteur Docker enregistre un événement chaque fois que des actions significatives sont effectuées par le démon. Vous pouvez accéder au journal des événements pour identifier quand une action s’est produite et suivre les modifications apportées aux objets au fil du temps.

Dans cet article, nous expliquerons ce qui est capturé en tant qu’événements et quand vous voudrez les consulter. Nous vous montrerons ensuite comment surveiller les événements en temps réel à l’aide de la CLI et de l’API REST de Docker.

Comment exécuter Grafana dans un conteneur Docker ?

Que sont les événements Docker ?

Les événements Docker décrivent les activités entreprises par votre démon Docker. La plupart des interactions avec des objets tels que des conteneurs, des images, des volumes et des réseaux enregistrent un événement, créant ainsi un journal que vous pouvez utiliser pour inspecter les changements passés.

Il existe de nombreux types d’événements qui identifient des changements spécifiques dans votre environnement :

  • Création et suppression de conteneurs
  • États de vérification de la santé des conteneurs
  • Commandes exécutées dans les conteneurs avec docker exec
  • Extraction et poussée d’images
  • Création, destruction, montage et démontage de volumes
  • Activation et désactivation des plugins du démon Docker.

Vous pouvez consulter la liste complète dans la documentation de Docker.

Chaque événement enregistré comprend un horodatage et l’ID de l’objet concerné. Vous pouvez utiliser ces informations pour assembler un historique des modifications apportées à votre environnement, que vous ayez observé ou non leurs déclencheurs originaux.

Les événements enregistrés peuvent également aider à diagnostiquer des problèmes tels que des défaillances inattendues de conteneurs. L’affichage du journal vous permet d’identifier le moment précis où un conteneur s’est arrêté, fournissant un point de données que vous pouvez corréler avec vos autres journaux. Les événements peuvent établir quand les contrôles de santé d’un conteneur ont commencé à échouer, réduisant ainsi la période d’intérêt lorsque vous devez inspecter des services externes pour déterminer la cause profonde d’un problème.

Streaming d’événements Docker avec l’interface CLI de Docker

La commande docker events CLI diffuse les événements de votre démon Docker dans votre fenêtre de terminal. Les événements s’affichent en temps réel jusqu’à ce que vous terminiez le processus en appuyant sur la combinaison de touches Ctrl+C.

L’exécution de la commande sans arguments n’affiche aucune sortie au départ. Seule la nouvelle activité est affichée, la sortie reste donc vide jusqu’à ce qu’un événement se produise. Vous pouvez en provoquer un en démarrant un nouveau conteneur dans un autre shell :

$ docker run –rm hello-world

Plusieurs événements devraient maintenant apparaître dans la fenêtre du terminal qui exécute la commande docker events :
2022-05-31T15:20:00.267970018+01:00 image pull hello-world:latest (name=hello-world)
2022-05-31T15:20:00.347054862+01:00 container create 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse)
2022-05-31T15:20:00.347805277+01:00 container attach 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse)
2022-05-31T15:20:00.621070053+01:00 container start 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse)

Chaque événement s’affiche sur sa propre ligne. L’horodatage de l’événement est affiché en premier, suivi du type d’objet affecté (tel que l’image ou le conteneur) et ensuite de l’action qui a été prise (comme créer, attacher et démarrer). Le reste du message contient des métadonnées utiles sur l’objet. L’exemple ci-dessus révèle que l’image hello-world:latest a été extraite et qu’un conteneur a été créé à partir de celle-ci.

Formatage de la sortie

La liste brute des événements est souvent peu maniable. Vous pouvez reformater la sortie en utilisant l’indicateur –format qui accepte une chaîne de modèle Go :

$ docker events –format ‘{{ .Time }} {{ .Action }} {{ .Type}} {{ .ID }} »

L’exécution de cet exemple produira une sortie qui ressemble à ceci :
1654006800 pull image hello-world:latest
1654006800 create container 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 attach container 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 start container 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378

Vous pouvez obtenir des événements représentés sous forme d’objets JSON en utilisant {{ json . }} comme chaîne de modèle :

$ docker events –format ‘{{ json . }}’ | jq
{
« status » : « create »,
« id » : « 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 »,
« de » : « hello-world »,
« Type » : « container »,
« Action » : « create »,
« Acteur » : {
« ID » : « 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 »,
« Attributs » : {
« image » : « hello-world »,
« name » : « nifty_morse »
}
},
« scope » : « local »,
« time » : 1654006800,
« timeNano » : 1654006800347054800
}

Ici, le JSON brut est transmis par jq pour être imprimé dans votre terminal. Cela rend l’information plus facile à parcourir.

Lorsque vous créez des chaînes de format personnalisées, vous pouvez utiliser les propriétés de la sortie JSON comme référence pour les caractères de remplacement pris en charge. Dans la plupart des cas, vous devrez mettre en majuscule la première lettre de chaque propriété, par exemple time pour {{ .Time }}.

Filtrage des événements

Le journal des événements d’un démon Docker occupé peut rapidement devenir bruyant. Vous pouvez réduire les événements à une action, un objet ou un type d’objet spécifique à l’aide du drapeau –filter :
docker events –filter type=container – Obtenir tous les événements qui se rapportent aux conteneurs.
docker events –filter event=create – Obtenir les événements de création de conteneur.
docker events –filter container=demo-container – Obtenez tous les événements enregistrés pour le conteneur appelé demo-container (vous pouvez faire référence à l’ID ou au nom du conteneur).

Outre le conteneur, vous pouvez filtrer par tous les noms de types d’objets pris en charge, tels que l’image, le réseau et le volume.

Plusieurs filtres sont pris en charge lorsque vous répétez l’indicateur –filter. Les filtres distincts sont interprétés comme des conditions logiques AND ; les utilisations multiples du même filtre deviennent des clauses OR. Voici un exemple de surface de l’événement create pour les conteneurs app-container et api-container :
$ docker events \
–filtre container=app-container
–filtre container=api-container
–filtre event=create

Accès aux événements historiques

Par défaut, docker events affiche uniquement les événements stockés depuis l’exécution de la commande. Vous pouvez inclure des événements historiques en ajoutant l’indicateur –since. Cette option accepte une expression temporelle lisible par l’homme ou un horodatage absolu :
$ docker events –since 1h
$ docker events –since ‘2021-05-01T16:00:00’ (en anglais)

Les événements enregistrés après l’heure donnée seront immédiatement affichés dans votre terminal. Les nouveaux événements continueront à s’afficher en temps réel au fur et à mesure qu’ils sont enregistrés.

Vous pouvez exclure les événements après un temps particulier avec le drapeau –until. Son fonctionnement est similaire à celui de –since. L’utilisation de –until désactivera la diffusion en continu et en temps réel des nouveaux événements, car ils se situeront en dehors de la période demandée.

Streaming d’événements Docker à partir de l’API REST de Daemon

Une autre façon d’accéder aux événements stockés est de passer par l’API REST du démon Docker. Vous pouvez utiliser le point de terminaison /events pour diffuser des événements en temps réel après avoir activé l’API sur votre hôte Docker. Les événements seront renvoyés au format JSON :

$ curl http://127.0.0.1:2375/v1.41/events
{
« Type » : « Conteneur »,
« Action » : « create »,
« Acteur » : {
« ID » : « 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 »,
« Attributs » : {
« image » : « hello-world »,
« name » : « nifty_morse »
}
},
« scope » : « local »,
« time » : 1654006800,
« timeNano » : 1654006800347054800
}

Le point de terminaison de l’API prend en charge les paramètres filter, since et until qui ont les mêmes comportements que leurs homologues CLI. Voici comment récupérer tous les événements de création de conteneur enregistrés au cours de la dernière heure :

$ curl http://127.0.0.1:2375/v1.41/events?since=1h&filters={‘type’:’container’, ‘action’:’create’}

Envoi d’événements à un service externe

Docker ne dispose pas d’un moyen intégré pour envoyer des événements à un service externe. Cela peut être utile si vous souhaitez que toutes vos créations de conteneurs soient enregistrées dans une plateforme de surveillance ou d’audit existante.

Vous pouvez mettre en place votre propre solution en créant un service système qui exécute continuellement les événements de Docker. Il doit envoyer chaque nouvelle ligne de sortie à votre système externe.

Commencez par écrire un script Bash qui implémente la fonctionnalité dont vous avez besoin :

!/bin/bash

docker events –format ‘{{ .Time }} {{ .Action }} {{ .Type }} {{ .ID }} » | while read event
do
curl \
-X POST \
-H « Content-Type : application/json » \
-d ‘{« event » : « $event »}’ \
https://example.com/events
terminé

Créez maintenant une nouvelle unité de service systemd dans /etc/systemd/system/docker-events.service :

[Unité]
Description=Service personnalisé de surveillance des événements de Docker

[Service]
Type=forking
ExecStart=/usr/local/bin/docker-events.sh

[Installer]
WantedBy=multi-user.target

Enfin, rechargez systemd pour charger votre service, puis démarrez et activez l’unité :
$ sudo systemctl daemon-reload
$ sudo systemctl start docker-events
$ sudo systemctl enable docker-events

Votre service va maintenant transmettre chaque nouvel événement à votre plateforme de surveillance. L’activation du service le configure pour qu’il démarre automatiquement à chaque redémarrage de votre hôte.

Conclusion

Les événements Docker sont créés chaque fois que le démon modifie des objets dans votre environnement. La diffusion en continu du journal des événements vous permet de surveiller l’activité du démon en temps réel. Cela peut vous aider à déboguer les problèmes, à auditer les changements et à assurer la conformité.

Comme les événements sont récupérés directement à partir du serveur Docker, il ne faut pas s’y fier si vous devez récupérer des informations à l’avenir. Seules 1 000 entrées sont conservées au fur et à mesure et vous ne pouvez pas accéder aux événements via le système de fichiers de votre hôte Docker. Ce mécanisme est mieux adapté aux tâches ad hoc rapides où vous recherchez des informations spécifiques liées à une activité récente. Pour une conservation à long terme, vous devez utiliser votre propre service système pour envoyer les événements à un référentiel externe.