TL;DR — Résumé Rapide

Configurez Prometheus avec Node Exporter pour surveiller vos serveurs Linux. PromQL, règles d'alerte, Alertmanager, stockage et sécurité en production.

Prometheus est la référence de facto pour la surveillance d’infrastructure open-source. Combiné à Node Exporter, il offre une visibilité approfondie sur chaque serveur Linux de votre parc — utilisation CPU, pression mémoire, saturation disque, débit réseau et moyennes de charge — tout cela est interrogeable avec un puissant langage d’expression et alertable via Alertmanager. Ce guide couvre l’installation complète jusqu’à un stack de surveillance prêt pour la production.

Prérequis

  • Ubuntu 22.04 ou Debian 12 (identique sur RHEL/Rocky en remplaçant apt par dnf)
  • Accès root ou sudo
  • Ports 9090 (Prometheus), 9100 (Node Exporter) et 9093 (Alertmanager) ouverts dans le pare-feu
  • Familiarité de base avec systemd et YAML

Vue d’Ensemble de l’Architecture

Prometheus utilise un modèle pull : il collecte des endpoints HTTP appelés targets à un intervalle configurable et stocke les données de séries temporelles localement dans une base de données colonnaire (TSDB).

┌─────────────────────────────────────────────────────────┐
│                   Serveur Linux                          │
│                                                          │
│   Node Exporter :9100  ←  Prometheus :9090  →  Grafana  │
│         ↑                      ↓                         │
│   /proc /sys              TSDB sur disque                │
│                                ↓                         │
│                          Alertmanager :9093              │
│                          (email/Slack/PD)                │
└─────────────────────────────────────────────────────────┘

Concepts clés :

  • Scrape — Prometheus récupère /metrics de chaque target au scrape_interval
  • TSDB — Base de données de séries temporelles locale ; chaque métrique est un float64 avec timestamp et labels
  • PromQL — Langage de requête pour trancher, agréger et calculer des taux sur les séries temporelles
  • Alertmanager — Processus séparé qui reçoit les alertes de Prometheus et achemine les notifications

Étape 1 : Installer Prometheus

Créer l’utilisateur système et les répertoires

sudo useradd --system --no-create-home --shell /bin/false prometheus

sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus /var/lib/prometheus

Télécharger et installer le binaire

PROM_VERSION="2.51.2"
cd /tmp
wget "https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz"
tar xzf prometheus-${PROM_VERSION}.linux-amd64.tar.gz
cd prometheus-${PROM_VERSION}.linux-amd64

sudo cp prometheus promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool
sudo cp -r consoles console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus/consoles /etc/prometheus/console_libraries

Écrire prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    environment: "production"

rule_files:
  - /etc/prometheus/rules/*.yml

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["localhost:9093"]

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

  - job_name: "node"
    static_configs:
      - targets: ["localhost:9100"]
    labels:
      instance: "web-01"
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
promtool check config /etc/prometheus/prometheus.yml

Créer l’unité systemd

[Unit]
Description=Système de Surveillance Prometheus
After=network.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention.time=30d \
  --web.listen-address=0.0.0.0:9090 \
  --web.enable-lifecycle

Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/prometheus

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus

Étape 2 : Installer Node Exporter

Node Exporter expose les métriques matérielles et OS depuis /proc et /sys sur le port 9100.

NODE_VERSION="1.7.0"
cd /tmp
wget "https://github.com/prometheus/node_exporter/releases/download/v${NODE_VERSION}/node_exporter-${NODE_VERSION}.linux-amd64.tar.gz"
tar xzf node_exporter-${NODE_VERSION}.linux-amd64.tar.gz

sudo useradd --system --no-create-home --shell /bin/false node_exporter
sudo cp node_exporter-${NODE_VERSION}.linux-amd64/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
[Unit]
Description=Prometheus Node Exporter
After=network.target

[Service]
Type=simple
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter \
  --collector.systemd \
  --collector.processes

Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
curl -s http://localhost:9100/metrics | head -20

Métriques Clés de Node Exporter

MétriqueDescription
node_cpu_seconds_totalTemps CPU par mode (user, system, idle) — utiliser avec rate()
node_memory_MemAvailable_bytesMémoire disponible (inclut le cache récupérable)
node_memory_MemTotal_bytesMémoire physique totale
node_filesystem_avail_bytesEspace disque libre
node_network_receive_bytes_totalOctets reçus par interface — utiliser avec rate()
node_load1 / node_load5 / node_load15Moyennes de charge système
node_disk_io_time_seconds_totalTemps en I/O — utiliser rate() pour la saturation

Bases de PromQL

Ouvrez l’interface Prometheus sur http://votre-serveur:9090 pour expérimenter.

Utilisation CPU en pourcentage

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

Utilisation mémoire en pourcentage

(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

Utilisation disque en pourcentage

(1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes)) * 100

Principales fonctions PromQL

FonctionRôle
rate()Taux par seconde en moyenne sur un intervalle
increase()Augmentation totale sur un intervalle
histogram_quantile()Latence P99 depuis une métrique histogramme
avg by()Moyenne sur une dimension
topk()Les N séries les plus élevées par valeur
predict_linear()Prévoit la valeur dans N secondes

Règles d’Alerte

# /etc/prometheus/rules/alerts.yml
groups:
  - name: node_alerts
    interval: 30s
    rules:

      - alert: HauteCPU
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Haute utilisation CPU sur {{ $labels.instance }}"
          description: "Utilisation CPU de {{ $value | printf \"%.1f\" }}% depuis plus de 5 minutes."

      - alert: EspaceDisqueFaible
        expr: (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes) * 100 < 15
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Espace disque faible sur {{ $labels.instance }}"
          description: "Partition {{ $labels.mountpoint }} a {{ $value | printf \"%.1f\" }}% libre."

      - alert: InstanceHorsLigne
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} hors ligne"
          description: "{{ $labels.job }}/{{ $labels.instance }} est inaccessible depuis 1 minute."

      - alert: HauteUtilisationMemoire
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Haute utilisation mémoire sur {{ $labels.instance }}"
          description: "Utilisation mémoire de {{ $value | printf \"%.1f\" }}%."
sudo mkdir -p /etc/prometheus/rules
sudo chown -R prometheus:prometheus /etc/prometheus/rules
promtool check rules /etc/prometheus/rules/alerts.yml
sudo systemctl reload prometheus

Configuration d’Alertmanager

Installer Alertmanager

AM_VERSION="0.27.0"
cd /tmp
wget "https://github.com/prometheus/alertmanager/releases/download/v${AM_VERSION}/alertmanager-${AM_VERSION}.linux-amd64.tar.gz"
tar xzf alertmanager-${AM_VERSION}.linux-amd64.tar.gz

sudo useradd --system --no-create-home --shell /bin/false alertmanager
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo cp alertmanager-${AM_VERSION}.linux-amd64/alertmanager /usr/local/bin/
sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager /etc/alertmanager /var/lib/alertmanager

Configurer les routes de notification

# /etc/alertmanager/alertmanager.yml
global:
  slack_api_url: "https://hooks.slack.com/services/VOTRE/WEBHOOK/ICI"

route:
  group_by: ["alertname", "instance"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: "equipe-ops"
  routes:
    - match:
        severity: critical
      receiver: "pagerduty"

receivers:
  - name: "equipe-ops"
    slack_configs:
      - channel: "#alertes"
        send_resolved: true

  - name: "pagerduty"
    pagerduty_configs:
      - routing_key: "VOTRE_CLE_PAGERDUTY"
        send_resolved: true

inhibit_rules:
  - source_match:
      severity: critical
    target_match:
      severity: warning
    equal: ["alertname", "instance"]
sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager

Règles d’Enregistrement

Les règles d’enregistrement pré-calculent des expressions PromQL coûteuses et stockent le résultat comme une nouvelle métrique, accélérant les tableaux de bord sur des flottes de nombreux serveurs.

# /etc/prometheus/rules/recording.yml
groups:
  - name: node_recording
    interval: 1m
    rules:
      - record: instance:node_cpu_usage:percent
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

      - record: instance:node_memory_usage:percent
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

      - record: instance:node_filesystem_usage:percent
        expr: (1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes)) * 100

Ajustement du Stockage

Le TSDB de Prometheus compresse efficacement les données — environ 1-2 octets par échantillon. Un serveur collectant 1 000 métriques toutes les 15 secondes accumule environ 2 Go par mois.

# Indicateurs dans l'ExecStart du service prometheus :
--storage.tsdb.retention.time=90d
--storage.tsdb.retention.size=20GB
--storage.tsdb.wal-compression
du -sh /var/lib/prometheus/

Sécurité

Authentification basique

# /etc/prometheus/web.yml
basic_auth_users:
  admin: "$2y$10$votre-hash-bcrypt-ici"

Proxy inverse avec nginx

server {
    listen 443 ssl;
    server_name prometheus.exemple.com;
    ssl_certificate /etc/letsencrypt/live/prometheus.exemple.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/prometheus.exemple.com/privkey.pem;
    auth_basic "Prometheus";
    auth_basic_user_file /etc/nginx/.prometheus-htpasswd;
    location / {
        proxy_pass http://127.0.0.1:9090;
    }
}

Règles de pare-feu

sudo ufw deny 9090
sudo ufw deny 9093
sudo ufw allow from 10.0.0.5 to any port 9100

Tableau Comparatif

FonctionnalitéPrometheusZabbixNagiosDatadogNetdata
ModèlePull (scrape)Push/PullPullPush (agent)Push
StockageTSDB localPostgreSQL/MySQLFichiers platsSaaS cloudBDD propre
Langage de requêtePromQL (puissant)Custom + SQLAucunDogStatsDCustom
Tableaux de bordGrafana (externe)IntégréNon natifIntégréIntégré
CoûtGratuit / open-sourceGratuit (enterprise payant)Gratuit (enterprise payant)SaaSGratuit (cloud payant)
Courbe d’apprentissageModérée (PromQL)ÉlevéeÉlevéeFaibleTrès faible

Recette de Stack de Production

Serveur Prometheus (2 vCPU / 4 Go RAM) :
  - /var/lib/prometheus → volume de données séparé (100 Go+)
  - Rétention : 30j temps OU 20 Go taille

Node Exporter (sur chaque serveur) :
  - Service systemd, port 9100
  - Pare-feu : autoriser 9100 uniquement depuis l'IP de Prometheus

Alertmanager :
  - Slack pour les warnings, PagerDuty pour les critical
  - Règles d'inhibition : supprimer les warnings quand critical est actif

Grafana (recommandé) :
  - docker run -d -p 3000:3000 grafana/grafana
  - Importer le dashboard ID 1860 (Node Exporter Full)

Pièges et Cas Limites

rate() nécessite au moins deux échantillons. Si un compteur se réinitialise (redémarrage de processus), rate() le gère correctement. Utilisez rate() pour les règles d’alerte, pas irate().

Explosion de cardinalité. N’utilisez jamais des labels à haute cardinalité comme user_id ou request_url. Chaque combinaison unique crée une série temporelle séparée.

La clause for prévient les fausses alertes. Une alerte avec for: 5m doit se déclencher continuellement pendant 5 minutes avant d’envoyer une notification.

Les règles d’enregistrement n’ont pas de données historiques. Après l’ajout d’une règle d’enregistrement, la nouvelle métrique n’existe qu’à partir de ce moment.

Le timeout de scrape doit être inférieur à l’intervalle. Si scrape_timeout dépasse scrape_interval, Prometheus enregistrera des erreurs.


Résumé

  • Prometheus utilise un modèle pull — il collecte les endpoints /metrics à un intervalle configurable
  • Node Exporter expose les métriques matérielles et OS sur le port 9100
  • PromQL avec rate(), increase() et histogram_quantile() forme la base des requêtes utiles
  • Écrivez des règles d’alerte avec une clause for pour éviter les fausses alertes ; acheminez via Alertmanager
  • Les règles d’enregistrement pré-calculent les agrégations coûteuses — critiques pour les tableaux de bord multi-nœuds
  • Ajustez la rétention de stockage avec --storage.tsdb.retention.time ou --storage.tsdb.retention.size
  • Placez toujours Prometheus derrière un proxy inverse avec TLS et restreignez l’accès direct aux ports

Articles Connexes