Un veilleur hors de Prometheus, pour que son silence cesse de ressembler au bon fonctionnement (#39)
Helm Charts / Detect changed charts (push) Successful in 10s
Helm Charts / Library charts tool (push) Skipped
Helm Charts / Application charts grafana (push) Skipped
Helm Charts / Application charts hashicorp-vault (push) Skipped
Helm Charts / Application charts minio (push) Skipped
Helm Charts / Application charts pgbouncer (push) Skipped
Helm Charts / Application charts pgcat (push) Skipped
Helm Charts / Application charts redis (push) Skipped
Helm Charts / Application charts chart (push) Skipped
Helm Charts / Application charts crowdsec (push) Skipped
Helm Charts / Application charts prometheus (push) Failing after 50s

Un CronJob toutes les 5 minutes interroge Prometheus depuis dehors et pousse
lui-même sur Telegram. Il couvre les trois morts, dont celle qui est arrivée :
répondre parfaitement en n'enregistrant rien.

Éprouvé en vrai sur le cluster : 187 s entre la panne armée et le message
accepté par Telegram, mesuré deux fois. Contre 4620 minutes de silence réel.

Ferme #36.

Co-Authored-By: Claude Opus 5 <[email protected]>
Co-authored-by: Gabriel Radureau <[email protected]>
This commit was merged in pull request #39.
This commit is contained in:
2026-09-07 10:55:16 +02:00
committed by arcodange
co-authored by Claude Opus 5
parent 249ff00d3a
commit dc48d48c1b
6 changed files with 905 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
# Le veilleur — le guetteur qui vit HORS du chemin d'alerte de Prometheus.
#
# arcodange-org/tools#36 : du 2026-09-04 02:41 au 2026-09-07 07:37, Prometheus
# n'a rien enregistré (WAL en lecture seule) et RIEN N'A PRÉVENU — les 11 règles
# d'alerte vivent dans le Prometheus en panne, et sans échantillon frais une
# règle ne se déclenche pas : elle se tait.
#
# ⚠ C'est pour ça que ce guetteur n'est PAS une règle Prometheus de plus. Il
# interroge Prometheus depuis l'extérieur et pousse LUI-MÊME sur Telegram, sans
# passer par Alertmanager. Le déplacer dans `serverFiles.alerting_rules.yml`
# reconstruirait exactement le silence qu'il existe pour supprimer.
#
# NB: ce chart prometheus est en mode `tool.kind: SubChart`, donc les templates
# helm-chart*.yaml ne rendent rien ; ce fichier, lui, est rendu tel quel et
# appliqué par ArgoCD (app `prometheus`, destination namespace `tools`), comme
# vault-telegram.yaml.
#
# La propriété gardée, et son arithmétique :
# « si Prometheus cesse d'enregistrer, une notification arrive en ≤ 12 min »
# seuil de fraîcheur 180 s (3 × `scrape_interval: 1m`)
# + période du CronJob 300 s (*/5 — le pire cas est de le manquer d'un rien)
# + tolérance au roulement 180 s (2 × 90 s : un redéploiement de Prometheus ne
# doit pas réveiller le fondateur)
# + exécution ~5 s
# = 665 s, soit 11 min 5 s au pire. En face : 4 620 minutes de silence réel.
apiVersion: v1
kind: ConfigMap
metadata:
name: veilleur-prometheus
namespace: tools
data:
veilleur.py: |
{{ .Files.Get "veilleur/veilleur.py" | indent 4 }}
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: veilleur-prometheus
namespace: tools
spec:
schedule: "*/5 * * * *"
# Un guetteur qui se double dérange deux fois pour une seule panne.
concurrencyPolicy: Forbid
# Si le contrôleur a pris du retard (nœud saturé), on saute le tour plutôt que
# d'en rejouer une pile d'un coup.
startingDeadlineSeconds: 120
successfulJobsHistoryLimit: 1
# ⚠ On garde les échecs : un Job `Failed` qui reste dans le cluster EST
# l'auto-plainte du veilleur quand il n'a pas pu joindre Telegram.
failedJobsHistoryLimit: 5
jobTemplate:
spec:
# 3 observations × 90 s + marge.
activeDeadlineSeconds: 420
# ⚠ Pas de reprise : une reprise renverrait le même message Telegram. Le
# tour suivant (5 min) est la reprise.
backoffLimit: 0
template:
metadata:
labels:
app.kubernetes.io/name: veilleur-prometheus
spec:
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 65534
runAsGroup: 65534
containers:
- name: veilleur
image: python:3.13-alpine
imagePullPolicy: IfNotPresent
command: ["python3", "/veilleur/veilleur.py"]
env:
# Le jeton et le salon viennent du MÊME Secret que celui
# d'Alertmanager (`alertmanager-telegram`, synchronisé depuis
# Vault kvv2/prospection/telegram par le VaultStaticSecret de
# templates/vault-telegram.yaml). Un second chemin de secret
# serait un second chemin à réparer.
- name: BOT_TOKEN
valueFrom:
secretKeyRef:
name: alertmanager-telegram
key: BOT_TOKEN
- name: CHAT_ID
valueFrom:
secretKeyRef:
name: alertmanager-telegram
key: CHAT_ID
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 96Mi
volumeMounts:
- name: veilleur
mountPath: /veilleur
readOnly: true
volumes:
- name: veilleur
configMap:
name: veilleur-prometheus