L’issue s’ouvre déjà remplie avec le titre et l’adresse de cette page.
Vous avez maintenant des métriques dans Prometheus et des dashboards dans Grafana. Mais personne ne regarde les dashboards 24/7. Vous avez besoin d'être notifié automatiquement quand quelque chose ne va pas.
C'est le rôle de l'alerting. Dans ce module, vous allez apprendre à créer des règles d'alerte pertinentes et à configurer Alertmanager pour envoyer les notifications aux bonnes personnes.
Comprendre le cycle de vie vous évitera beaucoup de confusion :
Cycle de vie d'une alerte : INACTIVE passe à PENDING quand la condition devient vraie, PENDING passe à FIRING quand la durée for est atteinte, et une condition redevenue fausse ramène PENDING ou FIRING à INACTIVE.condition vraiefor: atteintcondition faussecondition fausseINACTIVEPENDINGFIRING
Utiliser PascalCase, être descriptif : HighLatencyCheckout
② expr
Condition PromQL
Doit retourner des séries (pas une valeur scalaire)
③ for
Délai anti-faux-positif
Valeurs raccourcies dans ce lab (voir ci-dessous), plus longues en production
④ labels
Métadonnées pour le routing
severity, team, service
⑤ annotations
Texte pour les humains
summary (court), description (détaillé), runbook_url (lien vers la procédure)
Glissez pour voir
Les durées for de ce lab sont volontairement raccourcies : 2 à 5 minutes pour les règles critical, 5 à 10 minutes pour les warning. Elles permettent de voir l'alerte passer de Pending à Firing pendant l'exercice. En production, la leçon Alerting efficace recommande plutôt 5 minutes pour une alerte critical et 15 à 30 minutes pour une warning, afin d'absorber les pics sans réveiller personne. Le nom de l'annotation runbook_url suit la convention de Prometheus et Alertmanager : les receivers peuvent la réutiliser avec {{ .Annotations.runbook_url }}.
Les templates dans les annotations :
Vous pouvez utiliser des variables dans les annotations :
Ces règles d'infrastructure surveillent des causes possibles (processeur, mémoire, disque), pas ce que vit l'utilisateur. HighCPUUsage et HighMemoryUsage sont des alertes de capacité : elles sont en sévérité warning, ne réveillent personne et servent à anticiper une saturation avant qu'elle ne dégrade le service. Le réveil de nuit reste réservé aux symptômes comme la latence ou le taux d'erreur : HighLatency et HighErrorRate, écrites plus bas, sont donc en critical. Dans ce fichier d'infrastructure, seules TargetDown et DiskSpaceLow sont en critical, parce qu'une cible muette ou un disque presque plein appellent une action immédiate.
Créez le fichier 04-alerting/rules/infrastructure.yaml :
groups:
- name: infrastructure
rules:
# ============================================
# Alerte 1 : Un target ne répond plus
# ============================================
- alert: TargetDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Target {{ $labels.job }}/{{ $labels.instance }} is down"
description: |
The target {{ $labels.instance }} in job {{ $labels.job }}
Tester une règle d'alerte, c'est la rejouer sur des séries fabriquées à la main avec promtool test rules, avant qu'elle n'atteigne Prometheus. Une règle qui ne se déclenche jamais ne se voit pas : elle ne produit ni erreur ni notification, et ce silence passe pour de la bonne santé. promtool est l'outil en ligne de commande livré avec Prometheus, et il offre deux contrôles qui répondent à deux questions différentes.
Commande
Question posée
Ce qu'elle ne voit pas
promtool check rules
Le fichier est-il syntaxiquement valide ?
Une expression valide mais fausse, un seuil inversé, un for trop long
promtool test rules
La règle se comporte-t-elle comme prévu sur des données données ?
Les données réelles de votre cluster
Glissez pour voir
Le geste est le même dans d'autres contextes du site : la leçon Exploiter : journaux, alertes, incident et changements teste une règle de quota cloud, et le guide KPIs sécurité DevSecOps teste des règles de mesure de posture. Ici, on l'applique aux règles TargetDown et HighErrorRate que vous venez d'écrire.
Créez un dossier de travail avec le fichier rules.yml. C'est une copie resserrée des règles du lab : expr, for et labels sont identiques, mais les descriptions longues et les annotations value sont retirées ou raccourcies pour garder le test lisible. Seules deux des trois règles seront testées ici ; HighLatency s'appuie sur un histogramme et reste hors de cet exercice.
groups:
- name: demo-app
rules:
- alert: TargetDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Target {{ $labels.job }}/{{ $labels.instance }} is down"
Un fichier de test se compose de trois niveaux : l'en-tête qui désigne les règles, les séries d'entrée que vous fabriquez, puis les vérifications de ce que doit produire la règle à un instant donné. Créez tests.yml à côté de rules.yml.
rule_files liste les fichiers de règles à charger, et evaluation_interval fixe le rythme d'évaluation, ici une minute. Dans chaque test, interval est le pas entre deux valeurs d'une série, et input_series déclare les séries avec leurs étiquettes. La notation '1 1 0 0 0 0 0' donne une valeur par pas : la cible répond aux deux premières minutes, puis tombe. La notation '0+5x20' est un raccourci : on part de 0 et on ajoute 5 à chaque pas, 20 fois, soit 21 valeurs au total départ compris, ce qui fabrique un compteur qui croît de façon régulière.
Chaque entrée d'alert_rule_test pose une question : à eval_time, l'alerte alertname produit-elle exactement les alertes de exp_alerts ? Une alerte attendue se décrit par ses exp_labels et ses exp_annotations. Les deux compteurs du second test avancent à +5 et +95 par minute : les erreurs pèsent donc 5 % du trafic, au-dessus du seuil de 1 %, et l'alerte ne part qu'une fois le for: 5m écoulé, d'où le contraste entre 5m et 15m.
Le test négatif compte autant que le positif. À 3m, la cible est tombée depuis une minute seulement : la condition est vraie, mais le for: 2m n'est pas écoulé, l'alerte est donc encore pending et exp_alerts: [] affirme qu'aucune alerte n'est active. À 5m, la cible est tombée depuis trois minutes et l'alerte est firing. Sans ce test négatif, une règle qui se déclencherait trop tôt, par exemple après la suppression d'un for, passerait inaperçue.
Le binaire promtool est présent dans l'image officielle de Prometheus : il suffit de remplacer son point d'entrée. Le script ci-dessous reprend l'image épinglée par digest de la leçon Prometheus et monte le dossier courant en lecture seule. Si vous avez déjà promtool sur votre poste, lancez directement les deux commandes sans l'enveloppe Docker.
Ce que vous devez voir : la première commande valide la syntaxe et compte les règles chargées, la seconde rejoue les deux scénarios de tests.yml. Dans les deux cas le code de retour est 0, ce qui permet d'en faire une étape de CI qui bloque un déploiement.
Checking rules.yml
SUCCESS: 3 rules found
La sortie de pt test rules tests.yml tient en une seule ligne, sans autre détail tant que tout passe.
Un test qui ne sait jamais échouer ne prouve rien. Modifiez donc volontairement tests.yml et lisez la sortie. Premier cas : attendez severity: warning au lieu de critical pour TargetDown à 5m. La commande sort en code 1 et affiche côte à côte ce que vous attendiez (exp) et ce que la règle a produit (got).
Annotations:{runbook_url="https://runbooks.infra.internal/target-down", summary="Target demo-app/demo-app:8080 is down"}
]
La différence tient en un mot : severity="warning" d'un côté, severity="critical" de l'autre. Le bloc got indique la vérité de la règle, et le bloc exp votre erreur de test.
Second cas : attendez que TargetDown soit firing à 3m, c'est-à-dire avant la fin du for: 2m. Cette fois, got:[] montre que la règle n'a produit aucune alerte à cet instant. C'est exactement ce que le for doit garantir, et le test échoue parce que votre attente était fausse, pas la règle.
Trois pièges ont été mesurés en rejouant ces tests. Le premier : toutes les étiquettes de l'alerte doivent figurer dans exp_labels, y compris celles qui viennent de la série et pas de la règle ; seul alertname est ajouté automatiquement. Le deuxième : job et instance apparaissent dans l'alerte uniquement parce que vous les avez écrites dans input_series, car aucun scrape n'a lieu pendant un test.
Le troisième est le saut de ligne final. Une annotation écrite en bloc | dans YAML se termine par un \n : la description de HighErrorRate produit donc "...\nCurrent error rate: 5.00%\n", et ce dernier \n est nécessaire dans exp_annotations. Notez aussi que HighErrorRateagrège avec sum by (service_name) : l'alerte ne garde que cette étiquette de la série, d'où service_name: api et aucun http_status_code dans exp_labels.
La méthode la plus fiable pour un lab Helm est d'inclure les règles directement dans les values. Les deux fichiers rules.yml et tests.yml créés plus haut ne sont pas lus par le chart : ils servent de référence complète, et vous reportez dans les values les trois règles ci-dessous, suffisantes pour suivre la suite de l'exercice.
Ajoutez les règles dans les values Helm
Éditez 02-prometheus/helm-values/prometheus-minimal.yaml et ajoutez la section serverFiles :
serverFiles:
alerting_rules.yml:
groups:
- name: infrastructure
rules:
- alert: TargetDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Target {{ $labels.job }}/{{ $labels.instance }} is down"
Avant de brancher la moindre notification, vérifiez que Prometheus charge et évalue vos règles. Deux pages de son interface suffisent, et elles répondent à deux questions distinctes : Status → Rules dit si la règle existe et si elle s'évalue sans erreur, Alerts dit si elle se déclenche. Une règle absente de la première page ne se déclenchera jamais, quel que soit l'état du cluster.
Le routing détermine quel receiver reçoit quelle alerte.
route:
receiver: 'default'# Receiver par défaut
group_by: ['alertname'] # Grouper les alertes de même nom
group_wait: 30s# Attendre 30s avant d'envoyer (grouper les alertes)
group_interval: 5m# Intervalle minimum entre groupes
repeat_interval: 4h# Répéter si toujours firing après 4h
routes: # Sous-routes (ordre important !)
- matchers:
- severity="critical"
receiver: 'critical-alerts'# Les critiques vont ici
continue: false# Ne pas continuer aux autres routes
- matchers:
- team="backend"
receiver: 'backend-team'# Les alertes de l'équipe backend vont ici
Une note de syntaxe qui coûte cher en migration : les clés match et match_re,
que l'on croise encore dans beaucoup d'exemples en ligne, sont dépréciées dans
la configuration d'Alertmanager. La forme actuelle est matchers, une liste
d'expressions au format label="valeur" qui accepte aussi !=, =~ et !~.
Une seule clé remplace donc les deux anciennes.
Dans cet exemple, HighLatency porte severity: critical : elle est donc routée vers critical-alerts, et non vers backend-team, bien qu'elle porte aussi team: backend. La première correspondance gagne et continue: falsearrête la recherche : l'ordre des routes est déterminant. Pour que l'équipe backend reçoive aussi ses alertes critiques, ajoutez continue: true à la route critical-alerts.
Comment le routing fonctionne :
Une alerte arrive avec ses labels
Alertmanager parcourt les routesdans l'ordre
Première correspondance (matchers) trouvée → utilise ce receiver
Si continue: true, continue à chercher d'autres correspondances
Si aucune correspondance, utilise le receiver par défaut
Un silence se définit par des matchers de labels et une fenêtre temporelle, jamais par un identifiant d'alerte. C'est ce qui le rend puissant et dangereux à la fois : un matcher trop large étouffe des alertes que vous n'aviez pas prévu de couvrir. Les champs Creator et Comment ne sont pas décoratifs, ce sont eux qui permettent à l'astreinte suivante de savoir si un silence encore actif est légitime ou oublié.
Ce qui se passe : Les alertes HighMemoryUsage ne génèrent plus de notifications, mais sont toujours visibles dans Prometheus et Alertmanager (avec la mention "Silenced").
La colonne de gauche tient en une idée : un silence est une exception tracée et bornée, pas un réglage permanent. Les silences oubliés sont la première cause de panne non détectée dans une équipe qui a pourtant une bonne couverture d'alertes. Prenez l'habitude de relire la liste des silences actifs au début de chaque astreinte.
À faire
À éviter
Documenter la raison du silence
Silencer sans commentaire
Mettre une durée limitée
Silencer indéfiniment
Silencer au plus précis
Silencer tout severity=warning
Vérifier après la maintenance
Oublier de supprimer le silence
Glissez pour voir
Les inhibitions, supprimer le bruit automatiquement
Scénario : Un node entier tombe en panne. Vous recevez :
1 alerte "NodeDown"
10 alertes "PodDown" (pour chaque pod sur ce node)
15 alertes "ServiceUnavailable"
C'est du bruit. Si le node est down, évidemment les pods aussi.
Les inhibitions suppriment automatiquement les alertes redondantes.
inhibit_rules:
# Si un node est down, ne pas alerter sur ses pods
- source_matchers:
- alertname="NodeDown"
target_matchers:
- alertname="PodDown"
equal: ['node'] # L'inhibition s'applique si le label 'node' correspond
# Si un service est down, ne pas alerter sur la latence de ce service
- source_matchers:
- alertname="ServiceDown"
target_matchers:
- alertname="HighLatency"
equal: ['service_name']
Comment ça marche :
source_matchers : l'alerte "parente" qui déclenche l'inhibition
target_matchers : les alertes qui seront supprimées
equal : les labels qui doivent correspondre entre source et target
Comme pour le routing, source_match et target_match sont dépréciés au
profit de source_matchers et target_matchers. Le champ equal est le plus
subtil des trois : sans lui, une seule alerte NodeDown étoufferait les alertes
PodDown de tout le cluster, y compris celles des machines en bonne santé.
Les quatre règles ci-dessous visent un objectif unique : maintenir la confiance dans les alertes. Une alerte que l'équipe ignore par réflexe est pire qu'une alerte absente, parce qu'elle donne l'illusion d'une couverture. Elles se lisent dans l'ordre, chacune réduisant le volume ou augmentant l'utilité de ce qui reste.
Pourquoi ? Les utilisateurs ne se soucient pas de votre CPU. Ils se soucient que le site soit lent.
Ces causes ne sont pas à jeter pour autant : une alerte « CPU > 80 % » ou « Mémoire > 85 % » reste utile en sévérité warning, comme celles écrites plus haut. Elle sert d'alerte de capacité, lue en journée pour anticiper une saturation. Elle devient mauvaise seulement quand elle page quelqu'un la nuit : un processeur à 80 % peut être un fonctionnement normal.
Comparez les deux blocs sur un seul critère : la personne réveillée à trois heures du matin sait-elle quoi taper après avoir lu la notification ? Le champ description porte les commandes de diagnostic, le champ runbook_url porte le lien vers la procédure complète. Le second exemple utilise aussi {{ $labels.instance }} pour nommer la machine concernée, ce qui évite d'avoir à ouvrir Prometheus pour savoir où regarder.
# Mauvais : pas actionnable - que dois-je faire ?
annotations:
summary: "CPU is high"
# Bon : actionnable - je sais quoi vérifier
annotations:
summary: "CPU above 85% on {{ $labels.instance }}"
Une chaîne d'alerting se dégrade silencieusement : un webhook révoqué, un canal Slack archivé, une astreinte qui a changé de main. Rien de tout cela ne produit d'erreur visible tant qu'aucune alerte réelle ne survient. Le test périodique est le seul moyen de détecter ces ruptures avant l'incident.
Rejouez les tests de règles de la section promtool test rules à chaque modification d'une règle
Déclenchez manuellement au moins une fois par mois
Le diagnostic suit toujours le sens du flux : Prometheus évalue, Alertmanager route, le receiver notifie. Déterminez d'abord à quelle étape la chaîne casse, en regardant si l'alerte apparaît dans Prometheus, puis dans Alertmanager. Les trois tableaux ci-dessous correspondent aux trois ruptures possibles.
Commencez par la première ligne : neuf fois sur dix, l'expression PromQL ne renvoie aucune série. Copiez le contenu du champ expr dans l'onglet Graph de Prometheus, sans le reste de la règle. Si la requête ne remonte rien, aucun réglage de for ou de labels ne fera apparaître l'alerte.
Ici, l'alerte existe bien côté Prometheus mais s'arrête en chemin. Le partage se fait sur un seul test : l'alerte est-elle visible dans l'interface Alertmanager ? Si non, le problème est en amont, dans la section alerting de la configuration Prometheus. Si oui, il est dans le routing ou dans le receiver, et les journaux d'Alertmanager le disent explicitement.
Une tempête d'alertes n'est presque jamais un problème de seuils seul : c'est un défaut de regroupement. Une panne unique qui produit quarante notifications signale un group_by mal choisi ou des inhibitions absentes. Traitez ces deux points avant de toucher aux seuils, sous peine de masquer de vrais incidents.
Ces points constituent le socle de l'alerting. Si l'un d'eux reste flou, reprenez la section correspondante : les modules suivants réutilisent ce vocabulaire sans le redéfinir.
Prometheus évalue les règles d'alerte, Alertmanager route et notifie
Une alerte passe par les états : Inactive → Pending → Firing → Resolved
Le routing dirige les alertes vers les bons receivers
Les silences gèrent les maintenances planifiées
Les inhibitions réduisent le bruit automatiquement
Une bonne alerte est actionnable avec un runbook
On réveille sur les symptômes vécus par l'utilisateur (latence,
erreurs) ; les causes (CPU, mémoire) restent des alertes de capacité en
warning, qui préviennent sans réveiller
promtool check rules valide la syntaxe, promtool test rules valide le
comportement d'une règle sur des séries fabriquées, y compris l'absence
d'alerte avant la fin du for
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
8 questions
8 min.
70% requis
Informations
Le chronomètre démarre au clic sur Démarrer
Questions à choix multiples, vrai/faux et réponses courtes
Vous pouvez naviguer entre les questions
Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
⏱️--:--
0 / 8
Vérification
(0/0)
--:--
0%
0Correctes
0À revoir
0:00Temps
-Niveau
Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.