diff --git a/monitoring/README.md b/monitoring/README.md index 585f234..9f5bc14 100644 --- a/monitoring/README.md +++ b/monitoring/README.md @@ -99,32 +99,28 @@ State (`cve_exporter_state`-Volume) -- daher kommt die Spalte Bei Stack-Aenderungen `cve/images.txt` nachziehen, sonst scannt die Pipeline an der Realitaet vorbei. -### Bekanntes Problem: Alarm-Zustellung ist stummgeschaltet +### Alarm-Zustellung (frueher stummgeschaltet — seit gitops#51 wieder scharf) -**Die CVE-Regeln laufen, die Alarme werden aber bewusst nicht zugestellt.** -In `alertmanager.yml` routet `room="security"` derzeit auf den Null-Receiver. +**Stand 2026-08-15: Alarme werden zugestellt.** `alertmanager.yml` hat nur noch die +Default-Route auf den `matrix`-Receiver; die frueher hier beschriebene +`room="security"`-Route auf den Null-Receiver existiert nicht mehr. Alarme **ohne** +`room`-Label (u.a. die `axion-basics`- und `axion-backup`-Gruppen) laufen ueber +diese Default-Route. -Grund: `TrivyCriticalVuln` und `TrivyHighVuln` erzeugen eine Alarm-Instanz -**pro CVE pro Image**. Beim ersten Scan-Durchlauf waren das bei 14 von 29 -Images bereits 59 CRITICAL und 445 HIGH. Da `group_by: [alertname, instance]` -alle in *eine* Gruppe legt und `matrix-alerts.py` **eine Matrix-Nachricht pro -Alarm** schickt, wird daraus ein Nachrichten-Schwall. Verschaerfend: -`save_state()` steht in `do_POST` hinter der Sende-Schleife -- bricht ein Send -ab (Synapse rate-limitet nach ~10 Nachrichten mit 429), wird der State nicht -gespeichert, der Receiver antwortet 502 und Alertmanager wiederholt die -komplette Gruppe. Die Fingerprint-Deduplizierung ist beim Retry noch leer, -also wiederholt sich das. +Historie, damit der Grund der damaligen Stummschaltung nicht verlorengeht: die +CVE-Regeln erzeugten je eine Alarm-Instanz **pro CVE pro Image** (beim ersten Lauf +59 CRITICAL + 445 HIGH), `matrix-alerts.py` schickte eine Nachricht pro Alarm, +Synapse rate-limitete nach ~10 Nachrichten mit 429, und weil `save_state()` hinter +der Sende-Schleife stand, wiederholte Alertmanager die komplette Gruppe mit noch +leerer Deduplizierung. Behoben durch Aggregation auf `count by (target, severity)` +(eine Instanz je Image statt je CVE); Details im Dashboard `cve-overview`. +Vollstaendige Historie: gitops#51 / AAR 2026-08-01. -Zum Scharfschalten sind **beide** Punkte noetig: - -1. Zustellung buendeln -- entweder `matrix-alerts.py` auf eine Sammelnachricht - pro Webhook-Batch umbauen (alle fuenf Pflichtfelder je CVE als eine Zeile), - oder die Regeln auf `count by (target, severity)` aggregieren und die - CVE-Details im Dashboard lassen. -2. `save_state()` inkrementell nach jedem erfolgreichen Send, plus - 429-Behandlung mit `Retry-After`. - -Danach die `room="security"`-Route aus `alertmanager.yml` entfernen. +**Zustellfehler sind seit 2026-08-15 selbst ueberwacht:** Prometheus scrapt +Alertmanager (`operating_alertmanager`) und `AlertDeliveryFailing` schlaegt an, +wenn `alertmanager_notifications_failed_total` steigt. Vorher war Alertmanager zwar +Alarm-Ziel, aber kein Scrape-Target — eine reissende Alarmkette haette sich also +selbst nicht melden koennen. ### Kleinere offene Punkte der Pipeline diff --git a/monitoring/prometheus/alerts.yml b/monitoring/prometheus/alerts.yml index 9d26d2c..942f6b0 100644 --- a/monitoring/prometheus/alerts.yml +++ b/monitoring/prometheus/alerts.yml @@ -147,3 +147,15 @@ groups: severity: critical annotations: summary: "Ein Backup-/Probe-CronJob fehlt im Cluster — Sicherung oder Wiederherstellungs-Nachweis laeuft nicht mehr" + + # Die Alarmkette meldet ihr eigenes Reissen. Ironie inklusive: schlaegt die + # Zustellung komplett fehl, kommt auch dieser Alarm nicht an - er ist dann + # aber in Prometheus/Grafana sichtbar, statt dass gar nichts existiert. + # Teilausfaelle (ein Receiver von mehreren, Rate-Limit 429) meldet er sauber. + - alert: AlertDeliveryFailing + expr: increase(alertmanager_notifications_failed_total[15m]) > 0 + labels: + severity: critical + annotations: + summary: "Alertmanager konnte Benachrichtigungen nicht zustellen ({{ $labels.integration }}) — Alarme laufen ins Leere" + diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml index 2d5f72c..35f7583 100644 --- a/monitoring/prometheus/prometheus.yml +++ b/monitoring/prometheus/prometheus.yml @@ -26,6 +26,14 @@ scrape_configs: static_configs: - targets: ["cadvisor:8080"] + # Alertmanager-Eigenmetriken. Ohne diesen Job sind ZUSTELLfehler unsichtbar: + # Prometheus kennt alertmanager zwar als Alarm-Ziel (oben unter alerting:), + # scrapt ihn aber nicht - eine still reissende Alarmkette waere also genau das, + # was niemand meldet. Liefert u.a. alertmanager_notifications_failed_total. + - job_name: "operating_alertmanager" + static_configs: + - targets: ["alertmanager:9093"] + - job_name: "operating_traefik" metrics_path: "/metrics" static_configs: