Mehdi Assabbane
← Tous les articles

Superviser un serveur Docker avec Prometheus et Grafana

Mehdi Assabbane ·

Introduction

Un serveur Docker qui tourne sans supervision, c'est un serveur dont on découvre les problèmes quand les utilisateurs appellent : disque plein, conteneur qui redémarre en boucle, mémoire saturée. Mettre en place une supervision complète ne demande pourtant que quelques conteneurs et une heure de travail.

Ce guide présente une architecture éprouvée, entièrement open source :

  • Prometheus collecte et stocke les métriques ;
  • node_exporter expose les métriques du serveur (CPU, mémoire, disque, réseau) ;
  • cAdvisor expose les métriques de chaque conteneur ;
  • Grafana affiche des tableaux de bord et peut envoyer des alertes.

Le tout se déploie avec un seul fichier Docker Compose.

L'architecture

 serveur ──► node_exporter ─┐
                            ├──► Prometheus ──► Grafana ──► vous
 conteneurs ──► cAdvisor ───┘     (stockage)    (tableaux de bord, alertes)

Prometheus fonctionne en mode pull : il interroge à intervalle régulier (par défaut toutes les 15 à 60 secondes selon la configuration) les points de collecte de node_exporter et cAdvisor, et stocke les séries temporelles sur disque.

Le fichier Docker Compose

Créez un répertoire monitoring/ contenant ce docker-compose.yml :

services:
  prometheus:
    image: prom/prometheus:<version>
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.retention.time=30d
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./alerts.yml:/etc/prometheus/alerts.yml:ro
      - prometheus-data:/prometheus
    ports:
      - "127.0.0.1:9090:9090"
    restart: unless-stopped

  node-exporter:
    image: prom/node-exporter:<version>
    command:
      - --path.rootfs=/host
    volumes:
      - /:/host:ro,rslave
    network_mode: host
    pid: host
    restart: unless-stopped

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:<version>
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    devices:
      - /dev/kmsg
    privileged: true
    restart: unless-stopped

  grafana:
    image: grafana/grafana:<version>
    environment:
      - GF_SECURITY_ADMIN_PASSWORD__FILE=/run/secrets/grafana_admin
    secrets:
      - grafana_admin
    volumes:
      - grafana-data:/var/lib/grafana
    ports:
      - "127.0.0.1:3000:3000"
    restart: unless-stopped

secrets:
  grafana_admin:
    file: ./grafana_admin.txt

volumes:
  prometheus-data:
  grafana-data:

Quelques choix à expliquer :

  • <version> : remplacez-le par une version stable précise de chaque image. Évitez latest, qui peut changer de version majeure sans prévenir lors d'un redémarrage.
  • 127.0.0.1: devant les ports : Prometheus et Grafana ne sont accessibles que depuis le serveur lui-même. On y accède via un tunnel SSH ou un reverse proxy avec authentification et HTTPS, jamais en direct sur Internet.
  • network_mode: host et pid: host pour node_exporter : il doit voir le réseau et les processus réels du serveur, pas ceux d'un conteneur.
  • privileged: true pour cAdvisor : nécessaire pour lire les statistiques de tous les conteneurs. C'est un conteneur à privilèges élevés ; utilisez l'image officielle et tenez-la à jour.
  • Le mot de passe Grafana est lu depuis un fichier secret, et non écrit en clair dans le fichier Compose.

La configuration de Prometheus

prometheus.yml :

global:
  scrape_interval: 30s

rule_files:
  - /etc/prometheus/alerts.yml

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: node
    static_configs:
      - targets: ["host.docker.internal:9100"]

  - job_name: cadvisor
    static_configs:
      - targets: ["cadvisor:8080"]

node_exporter tournant sur le réseau de l'hôte, Prometheus doit le joindre par l'adresse de l'hôte. Sous Linux, ajoutez au service prometheus :

    extra_hosts:
      - "host.docker.internal:host-gateway"

Et assurez-vous que le pare-feu n'expose pas le port 9100 de node_exporter à l'extérieur.

Des règles d'alerte utiles

alerts.yml :

groups:
  - name: essentiel
    rules:
      - alert: CibleInjoignable
        expr: up == 0
        for: 2m
        annotations:
          summary: "{{ $labels.job }} ne répond plus"

      - alert: DisquePresquePlein
        expr: node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes < 0.10
        for: 10m
        annotations:
          summary: "Moins de 10 % d'espace libre sur {{ $labels.mountpoint }}"

      - alert: MemoireSaturee
        expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.10
        for: 5m
        annotations:
          summary: "Moins de 10 % de mémoire disponible"

      - alert: ConteneurRedemarreEnBoucle
        expr: changes(container_start_time_seconds{name!=""}[15m]) > 3
        annotations:
          summary: "Le conteneur {{ $labels.name }} redémarre en boucle"
  • up == 0 détecte une cible de collecte qui ne répond plus.
  • Les règles disque et mémoire alertent sous 10 % de ressources disponibles pendant plusieurs minutes, ce qui évite les fausses alertes sur un pic passager.
  • La dernière règle repère un conteneur dont l'heure de démarrage change plusieurs fois en un quart d'heure.

Ces règles sont visibles dans l'interface de Prometheus. Pour recevoir des notifications (e-mail, Slack, Teams…), ajoutez Alertmanager ou configurez les alertes directement dans Grafana.

Démarrer et vérifier

cd monitoring
docker compose up -d
docker compose ps

Démarre les quatre services et affiche leur état.

curl -s localhost:9090/api/v1/targets | grep -o '"health":"[a-z]*"'

Interroge l'API de Prometheus : chaque cible doit être en "health":"up".

ssh -L 3000:localhost:3000 utilisateur@votre-serveur

Depuis votre poste, ouvre un tunnel SSH : Grafana est alors accessible sur http://localhost:3000, sans être exposé sur Internet.

Configurer Grafana

  1. Connectez-vous avec le compte admin et le mot de passe du fichier secret.
  2. Ajoutez une source de données Prometheus avec l'adresse http://prometheus:9090.
  3. Importez un tableau de bord communautaire depuis grafana.com : le tableau Node Exporter Full (identifiant 1860) est une référence pour les métriques serveur. Pour les conteneurs, cherchez un tableau « cAdvisor » récent et bien noté.
  4. Créez ensuite votre propre tableau de bord avec les quelques indicateurs qui comptent vraiment pour vous.

Quelques requêtes PromQL utiles

100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Pourcentage d'utilisation du processeur sur les 5 dernières minutes.

sum by (name) (rate(container_cpu_usage_seconds_total{name!=""}[5m]))

Consommation CPU par conteneur.

sum by (name) (container_memory_working_set_bytes{name!=""})

Mémoire réellement utilisée par chaque conteneur.

Checklist

  • Versions d'images épinglées, pas de latest.
  • Prometheus, Grafana et node_exporter non exposés sur Internet.
  • Mot de passe administrateur Grafana robuste, stocké hors du fichier Compose.
  • Toutes les cibles en état up.
  • Règles d'alerte disque, mémoire, disponibilité et redémarrages en place.
  • Notifications configurées (Alertmanager ou Grafana).
  • Rétention des métriques adaptée à l'espace disque.
  • Les données de Prometheus et Grafana sont incluses dans les sauvegardes.

FAQ

Quelle ressource faut-il prévoir ? Pour un serveur et quelques dizaines de conteneurs, la pile tient dans quelques centaines de mégaoctets de mémoire. L'espace disque dépend de la rétention et du nombre de séries collectées : surveillez la taille du volume Prometheus les premiers jours.

Peut-on superviser plusieurs serveurs ? Oui : installez node_exporter et cAdvisor sur chaque serveur, et ajoutez-les comme cibles dans prometheus.yml, en sécurisant les flux entre serveurs (réseau privé, pare-feu).

Prometheus remplace-t-il la centralisation des journaux ? Non. Prometheus traite des métriques (des nombres dans le temps). Les journaux (les messages des applications) relèvent d'une autre pile, comme ELK ou Loki. Les deux sont complémentaires.

Pourquoi ne pas utiliser un service de supervision en ligne ? C'est une option valable. La pile auto-hébergée a l'avantage de garder les données chez vous et de ne rien coûter en licence ; en contrepartie, il faut la maintenir.

Conclusion

Avec quatre conteneurs, vous savez en permanence ce que consomment votre serveur et chacun de vos conteneurs, et vous êtes prévenu avant que le disque ne soit plein.

  1. Déployez la pile avec des versions épinglées et sans exposition publique.
  2. Commencez par quatre alertes : disponibilité, disque, mémoire, redémarrages.
  3. Enrichissez progressivement vos tableaux de bord avec les métriques de vos applications.

Sources officielles