Prometheus n'a rien enregistré pendant 3 jours, et rien ne pouvait le dire #36

Closed
opened 2026-09-07 09:53:10 +02:00 by arcodange · 0 comments
Owner

Ce qui s'est passé, mesuré le 2026-09-07 au matin

Le système de fichiers du volume de tools/prometheus-server est passé en lecture seule. Dernière écriture réussie dans le WAL : 2026-09-04 à 02:41. Remis en service à 07:37 le 2026-09-07.

Trois jours et cinq heures sans un seul échantillon enregistré.

Pendant ces trois jours, Prometheus a continué de scruter ses 23 cibles et de jeter le résultat :

level=ERROR source=scrape.go:1351 msg="Scrape commit failed" component="scrape manager"
  scrape_pool=kubernetes-pods target=http://10.42.0.103:8480/metrics
  err="write to WAL: log samples: write /data/wal/00001672: input/output error"

Des blocs déjà écrits étaient aussi devenus illisibles (open /data/<bloc>/meta.json: input/output error), et la compaction échouait à chaque passage.

Pourquoi personne ne l'a vu

C'est la partie qui compte. Tous les signaux d'un système en bonne santé étaient au vert :

Ce qu'on regarde Ce qu'il disait La vérité
Le pod Running 2/2, 0 redémarrage, 11 jours d'âge il ne stockait rien
Les sondes de vivacité jamais en échec l'API web répondait très bien
Longhorn volume attached, robustesse healthy le bloc allait bien, c'est l'ext4 au-dessus qui était mort
Le nœud pi1 Ready=True, DiskPressure=False un seul volume touché sur les huit
/api/v1/targets 23 cibles, presque toutes up calculé en direct, jamais stocké
Telegram silence le silence était le symptôme

La seule requête qui disait la vérité était count(up) : aucune série, en face de 23 cibles annoncées vivantes. C'est cette contradiction qui a ouvert l'enquête.

Le vrai défaut : les alertes ne peuvent pas parler de leur propre mort

Les 11 règles d'alerte déclarées évaluent des requêtes contre le TSDB qui ne recevait plus rien. Sans échantillon frais, une règle ne se déclenche pas : elle se tait. Et sur Telegram, le silence d'une alerte est indiscernable du bon fonctionnement.

Mesuré dans prometheus/values.yaml :

  • 0 règle surveille Prometheus lui-même (aucune mention de prometheus_tsdb_*, prometheus_rule_*, lecture seule).
  • 0 témoin toujours-allumé (pas de watchdog, pas de dead man's switch).

Et ajouter une règle « Prometheus va mal » ne corrigerait rien : elle vivrait dans le Prometheus en panne, elle serait muette exactement quand on aurait besoin d'elle. C'est un gate incapable d'échouer — pire qu'un gate absent, parce qu'il rassure.

Ce qu'il faut, donc

Un veilleur extérieur à Prometheus qui transforme le silence en bruit :

  1. Une règle toujours vraie (Veilleur, expr: vector(1)) qui part en continu vers Alertmanager.
  2. Un guetteur hors du chemin d'alerte de Prometheus qui crie quand les pings s'arrêtent — soit un service externe de type dead man's switch, soit, en version homelab, un CronJob qui interroge Prometheus (« quel âge a ton dernier échantillon ? ») et pousse sur Telegram si la réponse est vieille ou absente.

La propriété à garder, formulée pour qu'elle soit sabotable : si Prometheus cesse d'enregistrer, une notification arrive dans les N minutes. Le sabotage qui l'éprouve existe et il est facile : passer le volume en lecture seule, ou couper le pod, et relever le délai réel avant le message. Sans cette démonstration, on aura reconstruit le même silence.

La réparation faite ce matin

Aucune donnée n'a été détruite. Le volume a été détaché puis remonté, ce qui laisse kubelet repasser fsck :

kubectl -n tools scale deploy prometheus-server --replicas=0
# attendre que le volume Longhorn passe à detached
kubectl -n tools scale deploy prometheus-server --replicas=1

Vérifié après coup : montage rw, 0 erreur d'E/S, rejeu du WAL en 14,0 s, up frais à 0,9 s, 23 séries revenues en 60 s, et kadans_jobs_jobs de nouveau à 8 séries.

La cause première du passage en lecture seule n'est pas établie. L'ext4 a détecté une erreur et s'est protégé ; Longhorn n'a jamais signalé la moindre dégradation. Si ça se reproduit, c'est le volume ou le disque sous-jacent qu'il faut regarder, pas Prometheus.

Deux trous mesurés en chemin, à traiter à part

  • Aucune collecte de journaux dans le cluster : ni Loki, ni OpenSearch, ni Fluent, ni Vector, ni Promtail, et aucun namespace pour ça. Quand un pod redémarre, ce qu'il a dit est perdu. Le fondateur nomme OpenSearch dans la pile visée ; elle n'existe pas.
  • Deux cibles restent à terre : kadans-worker-mac (192.168.1.103:9105, « no route to host ») et une de kubernetes-service-endpoints (10.42.1.22:8080).

🤖 Generated with Claude Code

## Ce qui s'est passé, mesuré le 2026-09-07 au matin Le système de fichiers du volume de `tools/prometheus-server` est passé en **lecture seule**. Dernière écriture réussie dans le WAL : **2026-09-04 à 02:41**. Remis en service à **07:37 le 2026-09-07**. **Trois jours et cinq heures sans un seul échantillon enregistré.** Pendant ces trois jours, Prometheus a continué de scruter ses 23 cibles et de jeter le résultat : ``` level=ERROR source=scrape.go:1351 msg="Scrape commit failed" component="scrape manager" scrape_pool=kubernetes-pods target=http://10.42.0.103:8480/metrics err="write to WAL: log samples: write /data/wal/00001672: input/output error" ``` Des blocs déjà écrits étaient aussi devenus illisibles (`open /data/<bloc>/meta.json: input/output error`), et la compaction échouait à chaque passage. ## Pourquoi personne ne l'a vu C'est la partie qui compte. **Tous les signaux d'un système en bonne santé étaient au vert :** | Ce qu'on regarde | Ce qu'il disait | La vérité | |---|---|---| | Le pod | `Running 2/2`, **0 redémarrage**, 11 jours d'âge | il ne stockait rien | | Les sondes de vivacité | jamais en échec | l'API web répondait très bien | | Longhorn | volume `attached`, robustesse **`healthy`** | le bloc allait bien, c'est l'ext4 au-dessus qui était mort | | Le nœud pi1 | `Ready=True`, `DiskPressure=False` | un seul volume touché sur les huit | | `/api/v1/targets` | **23 cibles, presque toutes `up`** | calculé en direct, jamais stocké | | Telegram | **silence** | le silence était le symptôme | La seule requête qui disait la vérité était `count(up)` : **aucune série**, en face de 23 cibles annoncées vivantes. C'est cette contradiction qui a ouvert l'enquête. ## Le vrai défaut : les alertes ne peuvent pas parler de leur propre mort Les 11 règles d'alerte déclarées évaluent des requêtes **contre le TSDB qui ne recevait plus rien**. Sans échantillon frais, une règle ne se déclenche pas : elle se tait. Et sur Telegram, **le silence d'une alerte est indiscernable du bon fonctionnement**. Mesuré dans `prometheus/values.yaml` : - **0 règle surveille Prometheus lui-même** (aucune mention de `prometheus_tsdb_*`, `prometheus_rule_*`, lecture seule). - **0 témoin toujours-allumé** (pas de watchdog, pas de dead man's switch). ⚠ **Et ajouter une règle « Prometheus va mal » ne corrigerait rien** : elle vivrait dans le Prometheus en panne, elle serait muette exactement quand on aurait besoin d'elle. C'est un gate incapable d'échouer — pire qu'un gate absent, parce qu'il rassure. ## Ce qu'il faut, donc Un **veilleur extérieur à Prometheus** qui transforme le silence en bruit : 1. Une règle **toujours vraie** (`Veilleur`, `expr: vector(1)`) qui part en continu vers Alertmanager. 2. Un guetteur **hors du chemin d'alerte de Prometheus** qui crie quand les pings **s'arrêtent** — soit un service externe de type dead man's switch, soit, en version homelab, un `CronJob` qui interroge Prometheus (« quel âge a ton dernier échantillon ? ») et pousse sur Telegram si la réponse est vieille ou absente. La propriété à garder, formulée pour qu'elle soit sabotable : **si Prometheus cesse d'enregistrer, une notification arrive dans les N minutes.** Le sabotage qui l'éprouve existe et il est facile : passer le volume en lecture seule, ou couper le pod, et **relever le délai réel avant le message**. Sans cette démonstration, on aura reconstruit le même silence. ## La réparation faite ce matin Aucune donnée n'a été détruite. Le volume a été détaché puis remonté, ce qui laisse kubelet repasser `fsck` : ```bash kubectl -n tools scale deploy prometheus-server --replicas=0 # attendre que le volume Longhorn passe à detached kubectl -n tools scale deploy prometheus-server --replicas=1 ``` Vérifié après coup : montage `rw`, **0 erreur d'E/S**, rejeu du WAL en 14,0 s, `up` frais à 0,9 s, **23 séries** revenues en 60 s, et `kadans_jobs_jobs` de nouveau à 8 séries. ⚠ **La cause première du passage en lecture seule n'est pas établie.** L'ext4 a détecté une erreur et s'est protégé ; Longhorn n'a jamais signalé la moindre dégradation. Si ça se reproduit, c'est le volume ou le disque sous-jacent qu'il faut regarder, pas Prometheus. ## Deux trous mesurés en chemin, à traiter à part - **Aucune collecte de journaux dans le cluster** : ni Loki, ni OpenSearch, ni Fluent, ni Vector, ni Promtail, et aucun namespace pour ça. Quand un pod redémarre, ce qu'il a dit est perdu. Le fondateur nomme OpenSearch dans la pile visée ; elle n'existe pas. - **Deux cibles restent à terre** : `kadans-worker-mac` (192.168.1.103:9105, « no route to host ») et une de `kubernetes-service-endpoints` (10.42.1.22:8080). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange-org/tools#36