infra / monitoring-observabilite
Monitoring d'infrastructure avec node_exporter
Explication
Ce que vous allez apprendre
- Comprendre le pattern "exporter" utilisé dans tout l'écosystème Prometheus
- Installer node_exporter en service systemd permanent
- Calculer l'utilisation CPU, mémoire et disque à partir de métriques brutes
- Écrire des alertes infrastructure classiques (CPU, mémoire, disque)
- Éviter le piège de la métrique CPU cumulée mal interprétée
Dans quel contexte ?
mon-api est bien instrumentée et surveillée applicativement (leçons précédentes), mais un incident totalement différent peut survenir : le serveur lui-même manque de mémoire ou son disque est plein, indépendamment de tout bug dans le code. L'équipe infra a besoin d'une vue sur la machine elle-même, pas seulement sur l'application qui tourne dessus.
D'abord, il faut comprendre un principe qui structure tout l'écosystème Prometheus
Prometheus ne sait scraper QUE des endpoints /metrics au format qu'il comprend. Or la grande majorité des systèmes existants (le noyau Linux, une base de données, un cache Redis) n'exposent rien de tel nativement. Le rôle d'un "exporter" est justement de faire le pont : il interroge le système cible par ses propres moyens, puis traduit le résultat au format texte attendu par Prometheus.
node_exporter est l'exporter le plus utilisé de tout l'écosystème : il traduit les informations du noyau Linux (via /proc et /sys) en métriques Prometheus standardisées.
| Composant | Rôle |
|---|---|
Noyau Linux (/proc, /sys) | Source brute des données système |
| node_exporter | Traduit ces données au format Prometheus |
| Prometheus | Scrape node_exporter:9100/metrics |
| Grafana | Affiche les dashboards CPU/mémoire/disque |
Prérequis
Avoir déjà installé Prometheus et compris le mécanisme de scraping (deuxième leçon du cours) est indispensable : node_exporter n'est qu'une nouvelle cible ajoutée à scrape_configs.
Une fois l'exporter installé, une question de fiabilité se pose immédiatement
Un exporter lancé simplement en ligne de commande s'arrête au premier redémarrage du serveur, ou pire, plante silencieusement sans que personne ne le remarque — créant un trou invisible dans le monitoring, précisément au moment où on en aurait le plus besoin. C'est pour ça qu'on le fait toujours tourner comme un service systemd avec Restart=always.
Maintenant, le piège le plus fréquent de cette leçon : interpréter correctement la métrique CPU
Piège fréquent
node_cpu_seconds_total est un COUNTER cumulé, découpé par mode (idle, user, system, iowait...), qui ne fait qu'augmenter depuis le démarrage de la machine. L'utiliser directement comme "pourcentage d'utilisation CPU" n'a aucun sens : il faut impérativement passer par rate() sur une fenêtre de temps, puis calculer le complément du mode "idle" pour obtenir un pourcentage d'utilisation exploitable.
La formule 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) illustre exactement ce calcul : elle mesure combien de temps le CPU n'a PAS été inactif, ramené en pourcentage.
Il reste un indicateur souvent négligé : la charge liée aux I/O disque
Bonne pratique
Ne te limite pas à surveiller CPU, mémoire et disque : le temps d'attente d'I/O (node_disk_io_time_seconds_total) révèle souvent un goulot d'étranglement invisible autrement — un serveur peut sembler avoir du CPU disponible tout en étant en réalité bloqué à attendre son disque.
Le dernier point à retenir avant de passer à la suite
Le load average (node_load1) n'a de sens qu'une fois rapporté au nombre de coeurs disponibles : une charge de 4 est normale sur une machine à 8 coeurs, mais critique sur une machine à 2 coeurs. Toujours diviser par le nombre de coeurs avant de fixer un seuil d'alerte.
Le monitoring de machines physiques ou virtuelles maîtrisé, la prochaine leçon adapte ces mêmes principes à un environnement bien plus dynamique : les conteneurs Docker et Kubernetes.
Commandes & code
Monitoring d'infrastructure avec node_exporter
# Installation en binaire (le pattern "exporter" est universel dans l'écosystème Prometheus)
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xvf node_exporter-1.8.2.linux-amd64.tar.gz
./node_exporter-1.8.2.linux-amd64/node_exporter &
curl -s http://localhost:9100/metrics | head -20# systemd unit pour tourner en service permanent
# /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
Restart=always
[Install]
WantedBy=multi-user.target# prometheus.yml : ajouter la cible node_exporter
scrape_configs:
- job_name: "node"
static_configs:
- targets: ["server1:9100", "server2:9100", "server3:9100"]# Métriques CPU, mémoire, disque, réseau les plus utilisées en production
# Utilisation CPU (%) — attention, node_cpu_seconds_total est un COUNTER cumulé par mode (idle, user, system...)
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Mémoire disponible (%)
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100
# Espace disque libre (%) par point de montage
node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100
# Débit réseau (octets/s) par interface
rate(node_network_receive_bytes_total{device="eth0"}[5m])
rate(node_network_transmit_bytes_total{device="eth0"}[5m])
# Load average (charge système, à comparer au nombre de coeurs)
node_load1 / count(count(node_cpu_seconds_total) by (cpu)) # ratio load/coeurs : >1 = système en surcharge
# I/O disque (temps passé en attente d'I/O, souvent un goulot d'étranglement méconnu)
rate(node_disk_io_time_seconds_total[5m])# Règles d'alerte infra classiques
groups:
- name: infra_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 10m
labels: { severity: warning }
- alert: LowDiskSpace
expr: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100 < 10
for: 5m
labels: { severity: critical }
- alert: HostOutOfMemory
expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 10
for: 5m
labels: { severity: critical }Résumé
- Le pattern "exporter" (node_exporter, mysqld_exporter, redis_exporter...) traduit les métriques d'un système tiers en format Prometheus.
node_cpu_seconds_totalest un counter cumulé par mode : toujours passer parrate()avant de l'interpréter, jamais la valeur brute.- Les alertes infra de base (CPU, mémoire, disque, load) couvrent la majorité des incidents de capacité en production.
- Toujours faire tourner l'exporter comme service systemd avec
Restart=always: un exporter mort = un trou invisible dans le monitoring.
Exercices pratiques
Mission : le serveur qui "a l'air normal"
Objectif : Diagnostiquer l'état réel d'un serveur à partir de métriques node_exporter brutes, en évitant les pièges d'interprétation classiques.
Contexte
Un serveur de 4 coeurs affiche un node_load1 de 3.8, une utilisation CPU calculée naïvement comme node_cpu_seconds_total{mode="idle"} de 12000 (une valeur brute, jamais passée par rate()), et un espace disque qui semble stable. Pourtant les utilisateurs se plaignent de lenteurs. Ton travail : interpréter correctement chaque métrique avant de conclure.