Introduction
La surveillance des images Docker est essentielle pour maintenir la fiabilité des applications conteneurisées. Ce guide propose une approche pratique pour surveiller les images Docker, configurer des alertes et répondre aux incidents. Nous couvrirons l'inventaire des versions et de l'environnement, les chemins de configuration sécurisés, la vérification et le diagnostic, les modes de défaillance et une liste de contrôle opérationnelle, avec des commandes concrètes et des exemples.
Cet article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui doivent passer de l'observation d'un problème à la vérification de la résolution. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, protéger les informations sensibles, vérifier les résultats et documenter les procédures de récupération.
Inventaire des versions et de l'environnement
Avant d'effectuer toute modification, établissez une image claire de votre environnement Docker. Commencez par vérifier la version de Docker et l'état du démon. Exécutez docker version pour voir les versions du client et du serveur, et docker info pour obtenir les détails du démon tels que le pilote de stockage, le pilote de journalisation et le nombre de conteneurs. Cela permet de garantir la compatibilité avec les outils de surveillance.
Pour observer les conteneurs en cours d'exécution, utilisez docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" pour lister les conteneurs avec leurs noms, statuts et ports. Cette commande en lecture seule est sûre pour la production.
Si un conteneur se comporte mal, examinez ses journaux : docker logs <nom_du_conteneur> --tail 100 affiche les 100 dernières lignes. Pour une inspection plus approfondie, utilisez docker inspect <nom_du_conteneur> pour voir les montages, les réseaux, les variables d'environnement et l'état de santé.
Pour les projets Compose, utilisez docker compose ps pour voir l'état des services, docker compose logs -f <service> pour diffuser les journaux en continu, et docker compose exec <service> sh pour entrer dans un shell sans reconstruire l'image.
Lorsque la persistance des données est importante, identifiez où les fichiers sont stockés avant de modifier quoi que ce soit. Un volume nommé comme app_data:/var/lib/app est géré par Docker et généralement plus facile à réutiliser lors des reconstructions. Un montage de liaison tel que ./data:/var/lib/app mappe un répertoire de l'hôte dans le conteneur, utile pour le développement mais pouvant causer des problèmes de permissions et de portabilité si le chemin diffère d'une machine à l'autre.
Effectuez un test de redémarrage dans un environnement de préproduction : arrêtez le conteneur, recréez-le et vérifiez que l'application accède toujours aux données attendues. Si les données disparaissent, le service écrit probablement dans le système de fichiers du conteneur au lieu d'un volume ou d'un montage.
Exemple de vérification :
docker run -d --name test-app -v app_data:/var/lib/app myapp:latest
docker stop test-app
docker rm test-app
docker run -d --name test-app -v app_data:/var/lib/app myapp:latest
docker exec test-app ls /var/lib/app
La sortie attendue devrait inclure vos fichiers d'application, confirmant la persistance.
Chemin de configuration sécurisé
La configuration de la surveillance Docker implique la mise en place de la collecte de métriques, de la journalisation et des alertes sans compromettre la sécurité. Séparez toujours l'observation de l'intervention.
Commencez par définir la portée de la surveillance. Décidez quels conteneurs et images sont critiques. Utilisez des étiquettes pour organiser : docker run -d --label env=prod --label app=web myapp:latest. Cela facilite le filtrage des métriques.
Pour les métriques, activez le point de terminaison des métriques du démon Docker. Modifiez /etc/docker/daemon.json :
{
"metrics-addr": "127.0.0.1:9323",
"experimental": true
}
Redémarrez Docker : sudo systemctl restart docker. Testez avec curl http://127.0.0.1:9323/metrics pour voir les métriques au format Prometheus.
Pour les journaux, utilisez les pilotes de journalisation de Docker. Configurez le pilote de fichier JSON avec rotation pour éviter l'épuisement du disque :
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Appliquez globalement dans daemon.json ou par conteneur avec --log-opt.
Configurez une alerte de base en utilisant un outil comme cAdvisor combiné à Prometheus et Alertmanager. Exécutez cAdvisor pour collecter les métriques des conteneurs :
docker run -d \
--name=cadvisor \
-p 8080:8080 \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro \
gcr.io/cadvisor/cadvisor:latest
Ensuite, configurez Prometheus pour scraper cAdvisor et définissez des règles d'alerte dans alert.rules :
groups:
- name: container_alerts
rules:
- alert: ContainerHighCPU
expr: sum(rate(container_cpu_usage_seconds_total{name!=""}[5m])) by (name) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Container {{ $labels.name }} high CPU usage"
Acheminez les alertes via Alertmanager vers e-mail, Slack ou d'autres canaux.
Protégez les valeurs sensibles : ne codez jamais en dur les mots de passe dans les fichiers de configuration. Utilisez les secrets Docker ou les variables d'environnement. Par exemple, utilisez docker secret create db_password ./password.txt et référencez-le dans le service comme db_password.
Avant d'appliquer les modifications, testez dans un environnement de non-production. Utilisez docker compose config pour valider la syntaxe du fichier Compose.
Vérification et diagnostic
Après avoir configuré la surveillance, vérifiez que les métriques et les alertes fonctionnent comme prévu.
Vérifiez si les métriques sont scrapées par Prometheus : ouvrez l'interface Prometheus (port par défaut 9090), allez dans Statut > Cibles, et assurez-vous que la cible cAdvisor est opérationnelle. Interrogez une métrique comme container_memory_usage_bytes pour voir les données.
Pour les alertes, simulez une condition. Par exemple, exécutez un conteneur qui génère une charge CPU :
docker run -d --name stress --rm alpine sh -c "while true; do :; done"
Attendez que l'alerte se déclenche (vérifiez l'interface Alertmanager ou le canal configuré). Ensuite, arrêtez le conteneur et confirmez que l'alerte se résout.
Diagnostiquez les problèmes spécifiques à l'image en utilisant docker image inspect <image> pour afficher les métadonnées, les couches et l'environnement. Vérifiez les vulnérabilités avec un scanner comme Trivy :
trivy image --severity HIGH,CRITICAL myapp:latest
Cela analyse l'image et liste les vulnérabilités, vous aidant à décider de mettre à jour ou de corriger.
Pour la santé des conteneurs, configurez un healthcheck dans le Dockerfile ou la commande d'exécution :
HEALTHCHECK CMD curl --fail http://localhost/health || exit 1
Ensuite, docker ps affiche l'état de santé. Utilisez docker inspect --format='{{.State.Health.Status}}' <conteneur> pour obtenir le statut actuel.
Si les métriques n'apparaissent pas, vérifiez la connectivité : depuis le conteneur Prometheus, faites un curl vers le point de terminaison cAdvisor. Assurez-vous de la connectivité réseau et des ports corrects. Vérifiez que le point de terminaison des métriques du démon est accessible depuis l'hôte Prometheus.
Utilisez docker events pour diffuser les événements en temps réel : docker events --filter 'event=die' pour surveiller les sorties de conteneurs. Cela peut aider à corréler les alertes avec les incidents.
Modes de défaillance et récupération
Les conteneurs échouent pour diverses raisons : plantages d'application, épuisement des ressources, mauvaise configuration ou problèmes d'hôte. La surveillance doit alerter sur ces défaillances.
Modes de défaillance courants :
- Le conteneur se termine de manière inattendue : alertez sur la métrique
container_last_seenou utilisezdocker events. - CPU/mémoire élevés : alertez sur les seuils d'utilisation.
- Échecs de tirage d'image : surveillez la disponibilité du registre et l'authentification.
- Épuisement de l'espace disque dû aux journaux ou volumes : alertez sur l'utilisation du disque de l'hôte.
- Problèmes réseau : le conteneur ne peut pas atteindre les services dépendants.
Les procédures de récupération doivent être documentées. Pour un conteneur planté, vérifiez la politique de redémarrage : docker inspect --format='{{.HostConfig.RestartPolicy.Name}}' <conteneur>. Si elle n'est pas définie sur always ou unless-stopped, mettez à jour avec docker update --restart unless-stopped <conteneur>.
Pour l'épuisement des ressources, identifiez le coupable : docker stats --no-stream affiche l'utilisation du CPU, de la mémoire et des E/S par conteneur. Augmentez les limites ou optimisez l'application. Pour les fuites de mémoire, envisagez de redémarrer périodiquement ou de corriger le code.
Si le disque est plein, nettoyez les images et volumes inutilisés : docker system prune -a --volumes (avec prudence, cela supprime les données non utilisées). Configurez la rotation des journaux comme décrit précédemment.
Pour les échecs de tirage d'image, vérifiez les informations d'identification du registre : docker login et assurez-vous que l'image existe et que la balise est correcte. docker image ls pour vérifier les images locales.
Créez un runbook avec des étapes pour chaque mode de défaillance. Incluez les commandes à exécuter, les sorties attendues et les étapes de retour en arrière. Par exemple, pour revenir en arrière après un déploiement d'image défectueux, marquez la version précédente et redéployez :
docker tag myapp:previous myapp:latest
docker stack deploy -c docker-compose.yml myapp
Testez régulièrement la récupération en préproduction. Simulez des défaillances (tuez un conteneur, remplissez le disque) et pratiquez le runbook.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle pour les opérations continues de surveillance des images Docker. Attribuez un propriétaire à chaque élément (par exemple, ingénieur DevOps) et une fréquence de révision (par exemple, hebdomadaire).
- [ ] Vérifier que tous les conteneurs critiques sont en cours d'exécution et en bonne santé (
docker ps). Propriétaire : ingénieur DevOps. Fréquence : quotidienne. - [ ] Vérifier les tableaux de bord de métriques pour détecter les anomalies (CPU, mémoire, réseau). Propriétaire : ingénieur d'astreinte. Fréquence : par quart.
- [ ] S'assurer que les règles d'alerte sont à jour et correctement acheminées. Propriétaire : administrateur de la surveillance. Fréquence : mensuelle.
- [ ] Analyser les images à la recherche de vulnérabilités avec Trivy ou similaire. Propriétaire : équipe de sécurité. Fréquence : hebdomadaire.
- [ ] Examiner et tester les runbooks de récupération. Propriétaire : responsable DevOps. Fréquence : trimestrielle.
- [ ] Surveiller l'utilisation du disque et de la mémoire de l'hôte. Propriétaire : administrateur système. Fréquence : quotidienne.
- [ ] Vérifier les journaux du démon pour détecter les erreurs (
journalctl -u docker). Propriétaire : ingénieur DevOps. Fréquence : quotidienne. - [ ] Valider la sauvegarde des volumes persistants. Propriétaire : administrateur de sauvegarde. Fréquence : quotidienne.
- [ ] Examiner les performances et l'évolutivité de l'outillage de surveillance. Propriétaire : architecte. Fréquence : mensuelle.
Chaque élément devrait avoir un chemin de résolution défini. Par exemple, si l'utilisation du disque dépasse 80 %, alertez et nettoyez les journaux ou augmentez le disque.
Utilisez l'automatisation lorsque cela est possible. Planifiez des scripts avec cron ou des pipelines CI/CD pour exécuter des vérifications et envoyer des rapports.
Pièges courants et comment les éviter
- Ignorer la taille excessive de l'image : les images volumineuses ralentissent les déploiements et augmentent la surface d'attaque. Surveillez la taille des images avec
docker imageset utilisez des constructions multi-étapes. Évitez d'installer des paquets inutiles.
- Ne pas définir de limites de ressources : sans limites, un conteneur incontrôlable peut priver les autres. Définissez des limites dans Compose ou run :
docker run --memory=512m --cpus=1 myapp. Alertez sur l'utilisation approchant les limites.
- Négliger la gestion des journaux : des journaux non gérés peuvent remplir les disques. Configurez toujours la rotation des journaux et expédiez les journaux vers un système central.
- Coder en dur les secrets dans les images : les secrets dans les images sont exposés si l'image est partagée. Utilisez les secrets Docker ou les variables d'environnement, et analysez les images à la recherche de secrets.
- Ne pas surveiller les échecs de tirage d'image : les échecs de tirage peuvent provoquer des pannes de déploiement. Surveillez le registre et configurez des alertes sur les erreurs de tirage.
- Ignorer les vulnérabilités de l'image de base : des images de base obsolètes peuvent avoir des exploits connus. Reconstruisez régulièrement les images avec une base mise à jour et analysez.
- Manque de healthchecks : sans healthchecks, Docker ne peut pas détecter les conteneurs en mauvaise santé. Définissez des healthchecks dans le Dockerfile ou Compose.
- Ne pas tester la récupération : des runbooks non testés échouent lors d'incidents réels. Simulez des défaillances et pratiquez.
Conclusion
Une surveillance efficace des images Docker nécessite une approche systématique : inventoriez votre environnement, configurez une surveillance sécurisée, vérifiez la fonctionnalité, préparez-vous aux défaillances et suivez une liste de contrôle opérationnelle. En mettant en œuvre les pratiques et commandes de ce guide, vous pouvez garantir que vos applications conteneurisées fonctionnent de manière fiable et sécurisée.
Commencez par une étape à faible risque : configurez la collecte de métriques de base avec cAdvisor et Prometheus. Ajoutez ensuite des alertes pour les conditions critiques. Au fur et à mesure que vous gagnez en confiance, étendez à une surveillance complète avec des tableaux de bord et des réponses automatisées.
Rappelez-vous : la surveillance ne consiste pas seulement à collecter des données ; il s'agit de prendre des décisions éclairées rapidement. Un environnement Docker bien surveillé vous permet de détecter les problèmes tôt et de récupérer avec un temps d'arrêt minimal.