RousselTMLEARNING

Observabilité

Prometheus : alerter avec Alertmanager (règles, routage, silences)

Mettre en place l'alerting Prometheus : règles d'alerte, Alertmanager, routage, regroupement, inhibition, silences, récepteurs Slack/e-mail et tests avec promtool et amtool.

1. Comprendre l'alerting Prometheus #

Deux composants, deux responsabilités.

Détecter ou notifier ? #

Prometheus évalue des expressions PromQL à intervalle régulier. Quand une expression renvoie des séries, une alerte passe à l'état pending puis firing après la durée for. Prometheus n'envoie pas d'e-mail lui-même : il transmet les alertes à Alertmanager, qui s'occupe de dédupliquer, regrouper, router et notifier.

Chaîne d'alerte : Prometheus, Alertmanager et récepteurs
Plusieurs Prometheus peuvent alimenter un même Alertmanager.
FonctionPrometheusAlertmanager
Évaluation des règles✅—
Déduplication / regroupement—✅
Routage et notification—✅
Silences et inhibitions—✅

2. Écrire des règles d'alerte #

Fichiers de règles et bonnes expressions.

Un fichier de règles #

# /etc/prometheus/rules/node.rules.yml
groups:
  - name: node-alerts
    interval: 30s
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 2m
        labels: { severity: critical }
        annotations:
          summary: "{{ $labels.instance }} est injoignable"
          description: "Le job {{ $labels.job }} ne répond plus depuis plus de 2 minutes."

      - alert: HighCpuUsage
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 10m
        labels: { severity: warning }
        annotations:
          summary: "CPU > 85 % sur {{ $labels.instance }} ({{ $value | printf \"%.0f\" }} %)"

      - alert: DiskWillFillIn4Hours
        expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[1h], 4*3600) < 0
        for: 30m
        labels: { severity: warning }
        annotations:
          summary: "Le disque {{ $labels.mountpoint }} de {{ $labels.instance }} sera plein dans 4 h" 
# prometheus.yml
rule_files:
  - /etc/prometheus/rules/*.rules.yml
alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager:9093"]

Valider et tester les règles #

promtool check config /etc/prometheus/prometheus.yml
promtool check rules /etc/prometheus/rules/node.rules.yml
curl -X POST http://localhost:9090/-/reload       # nécessite --web.enable-lifecycle

# Tests unitaires de règles
cat > tests/node.test.yml <<'EOF'
rule_files: [../rules/node.rules.yml]
evaluation_interval: 1m
tests:
  - interval: 1m
    input_series:
      - series: 'up{job="node", instance="web1"}'
        values: '1 1 0 0 0 0'
    alert_rule_test:
      - eval_time: 5m
        alertname: InstanceDown
        exp_alerts:
          - exp_labels: { severity: critical, job: node, instance: web1 }
EOF
promtool test rules tests/node.test.yml
Bonne Pratique : Toujours utiliser for: : sans durée, une métrique qui oscille une seule fois déclenche une alerte inutile (alert fatigue).

3. Configurer Alertmanager #

Routage, regroupement et récepteurs.

Installation avec Docker Compose #

# docker-compose.yml (extrait)
  alertmanager:
    image: prom/alertmanager:latest
    ports: ["9093:9093"]
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
    command: ["--config.file=/etc/alertmanager/alertmanager.yml", "--storage.path=/alertmanager"]

Arbre de routage #

# alertmanager.yml
global:
  resolve_timeout: 5m
  smtp_smarthost: smtp.lab:587
  smtp_from: alertes@lab.local

route:
  receiver: equipe-ops
  group_by: [alertname, cluster]
  group_wait: 30s        # attendre avant le 1er envoi pour regrouper
  group_interval: 5m     # délai entre deux notifications d'un même groupe
  repeat_interval: 4h    # rappel si l'alerte persiste
  routes:
    - matchers: [severity="critical"]
      receiver: astreinte
      continue: true
    - matchers: [team="dba"]
      receiver: equipe-dba

receivers:
  - name: equipe-ops
    slack_configs:
      - api_url_file: /etc/alertmanager/slack_url
        channel: "#ops"
        send_resolved: true
        title: "[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}"
        text: "{{ range .Alerts }}• {{ .Annotations.summary }}\n{{ end }}"
  - name: astreinte
    pagerduty_configs:
      - routing_key_file: /etc/alertmanager/pd_key
  - name: equipe-dba
    email_configs:
      - to: dba@lab.local

inhibit_rules:
  - source_matchers: [severity="critical"]
    target_matchers: [severity="warning"]
    equal: [alertname, instance]
À savoir : Une inhibition supprime les alertes de moindre gravité quand une alerte plus grave existe déjà pour la même cible : inutile de recevoir « CPU élevé » quand l'hôte est déjà « injoignable ».

Valider la configuration et simuler une alerte #

amtool check-config alertmanager.yml
amtool config routes show --config.file=alertmanager.yml
amtool config routes test --config.file=alertmanager.yml severity=critical team=dba

# Envoyer une alerte de test sans attendre Prometheus
curl -XPOST http://localhost:9093/api/v2/alerts -H 'Content-Type: application/json' -d '[
  {"labels":{"alertname":"TestAlerte","severity":"warning","instance":"web1"},
   "annotations":{"summary":"Ceci est un test"}}]'

4. Exploiter au quotidien #

Silences, état et API.

Silences #

Arbre de routage et test avec amtool
Une alerte critique pour l'équipe DBA est notifiée aux deux récepteurs grâce à continue: true.
# Silence de 2 h pendant une maintenance
amtool silence add instance="web1" alertname="HighCpuUsage" --duration=2h --comment="mise à jour kernel" --author=martin --alertmanager.url=http://localhost:9093
amtool silence query
amtool silence expire <ID>
amtool alert query severity=critical

Métriques d'alerte à superviser #

# Dans Prometheus : alertes actives et état d'Alertmanager
ALERTS{alertstate="firing"}
count by (severity) (ALERTS{alertstate="firing"})
alertmanager_notifications_failed_total
rate(alertmanager_notifications_total[5m])
Erreur Courante : Ne supervisez jamais Alertmanager uniquement avec lui-même : mettez en place une alerte « Watchdog » (expr: vector(1)) qui doit toujours être active et surveillée par un service externe (dead man's switch).

Articles liés

Prometheus : visualiser ses métriques (UI, Grafana et dashboards)

Visualiser les données Prometheus : interface web, graphes PromQL, connexion à Grafana, dashboards RED et USE…

Prometheus dans le monde Kubernetes (Operator, ServiceMonitor, kube-prometheus-stack)

Superviser Kubernetes avec Prometheus : service discovery, kube-prometheus-stack, Prometheus Operator, Servic…

Bonnes pratiques Prometheus : métriques, cardinalité, règles et exploitation

Bonnes pratiques Prometheus : nommage des métriques, labels et cardinalité, intervalles de scrape, recording …

Pour aller plus loin