ajoute la supervision : règles d'alerte Prometheus, relais ntfy, Uptime Kuma

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-07 21:20:01 +02:00
parent d21c6ef544
commit aa31b6112f
12 changed files with 432 additions and 0 deletions

View file

@ -239,3 +239,36 @@ Une image de VM, ce n'est pas juste un système d'exploitation : c'est tout ce d
**Suite**
Étape 7 : supervision (Prometheus, Grafana, Uptime Kuma) et alertes, accessibles par tunnel SSH en attendant un nom de domaine.
## 2026-10-07 — Étape 7 : supervision et alertes
**Fait**
- Prometheus, Alertmanager, Grafana, node_exporter, cAdvisor, openstack-exporter, libvirt/mysqld/memcached-exporters étaient déjà déployés par Kolla depuis l'étape 5 (`enable_prometheus`/`enable_grafana: "yes"`), tous liés uniquement à `10.10.0.1` — jamais exposés sur `eno1` (déjà vérifié par nmap à l'étape 5, re-confirmé ici).
- Rôle Ansible `supervision` + playbook `ansible/supervision.yml` : vérifie la présence et les permissions (`600`) de `/root/.alertes-webhook` sans jamais afficher son contenu, déploie le relais Alertmanager → ntfy (`/usr/local/sbin/alertmanager-ntfy.py`, service systemd, `127.0.0.1:9099` uniquement), et Uptime Kuma (conteneur Docker, `127.0.0.1:3001`, volume nommé).
- `kolla/config/prometheus/alertes.rules` : 4 règles (`DisqueSature` > 80 %, `MemoireSaturee` > 90 %, `ServiceOpenStackArrete` via les métriques `openstack_nova_agent_state`/`openstack_neutron_agent_state`, `SauvegardeAncienne` > 26 h).
- `kolla/config/prometheus/prometheus-alertmanager.yml` : remplace le gabarit Kolla par défaut (receveur sans destination) par un webhook vers le relais local. Déposé via le mécanisme standard de Kolla (`node_custom_config/prometheus/...`), pas de template Jinja Kolla à casser.
- Collecteur "textfile" activé sur node_exporter (`prometheus_node_exporter_cmdline_extras`, `prometheus_node_exporter_extra_volumes` dans `globals.yml`) : `sauvegarde-dedibackup.sh` y écrit, de façon atomique, l'horodatage de la dernière sauvegarde réussie à chaque exécution.
**Problèmes rencontrés et solution**
- **Oubli répété (2 fois) : modifier un fichier du dépôt (`globals.yml`, le script de sauvegarde) sans le repousser sur le serveur avant de relancer Kolla.** Dans les deux cas, `kolla-ansible reconfigure` a tourné sans erreur mais sur l'ancienne configuration — aucun message ne le signale. Corrigé en relançant le playbook Ansible concerné avant `reconfigure`. Noté dans `docs/runbooks/supervision.md` comme piège à ne pas refaire.
- Mesure du mot de passe Alertmanager/Prometheus pour les tests `curl` : évité `python3-yaml` (absent du Python système) au profit d'un simple `awk` sur le format `clef: valeur` de `passwords.yml` ; jamais affiché, seulement sa longueur vérifiée une fois pour confirmer qu'il avait bien été lu.
**Critère vérifié**
- Alerte de test injectée via l'API d'Alertmanager (`POST /api/v2/alerts`), sans toucher à rien de réel sur le serveur. **Confirmé par Adam : notification ntfy bien reçue.** Testé aussi en contournant Alertmanager (requête directe au relais) : `HTTP 200`.
- Métrique de sauvegarde vérifiée de bout en bout : fichier textfile → `node_exporter` (`node_textfile_scrape_error 0`) → Prometheus (`/api/v1/query` renvoie la valeur).
- Règles d'alerte confirmées chargées dans Prometheus (`/api/v1/rules` : les 4 règles listées).
**Dette assumée, à trancher avec Adam**
Pas d'alerte « serveur injoignable » : toute la chaîne de supervision tourne sur le serveur qu'elle surveille, donc si le serveur tombe complètement, personne n'est prévenu par ce mécanisme. L'architecture d'origine (CLAUDE.md) prévoyait une sonde hors du serveur (Hetzner CX23) ; ce déploiement n'a qu'un seul serveur. Documenté dans `docs/runbooks/supervision.md`, pas construit : décision à prendre par Adam (qui commande et paie lui-même toute ressource supplémentaire).
**Comprendre**
La bonne nouvelle de cette étape, c'est que Kolla avait déjà fait le plus gros : Prometheus, Grafana et une demi-douzaine d'exportateurs tournaient depuis l'étape 5 sans qu'on ait rien demandé de spécial, juste en activant deux options. Le travail réel a surtout été de les relier à une vraie notification (Alertmanager ne sait parler qu'un format webhook générique, pas le format de ntfy, d'où le petit relais) et d'ajouter une alerte qui n'existe dans aucun exportateur standard : l'âge de la dernière sauvegarde. Le collecteur « textfile » de node_exporter est fait exactement pour ça — transformer n'importe quel script maison en métrique Prometheus, juste en écrivant un fichier texte à un endroit précis. La vraie leçon de l'étape, à retenir pour la suite : modifier un fichier dans le dépôt ne change rien tant qu'il n'est pas repoussé sur le serveur — une évidence une fois dite, mais qui s'oublie vite quand on va vite.
**Suite**
Étape 8 : portail Laravel (Blade, Vite, MariaDB/Redis pour l'app, modèles, connexion prof/élève, salle d'attente). Le dossier `design/` doit exister : à vérifier avant de commencer.

View file

@ -0,0 +1,111 @@
# Runbook — Supervision et alertes
## Ce qui tourne
| Service | Adresse (interne, `10.10.0.1`) | Déployé par |
|---|---|---|
| Prometheus | `:9091` | Kolla (`enable_prometheus: "yes"`) |
| Alertmanager | `:9093` | Kolla |
| Grafana | `:3000` | Kolla |
| node_exporter | `:9100` | Kolla (+ collecteur textfile, rôle `supervision`) |
| openstack-exporter | `:9198` | Kolla |
| cAdvisor, libvirt/mysqld/memcached exporters | ports divers | Kolla |
| Relais Alertmanager → ntfy | `127.0.0.1:9099` | rôle Ansible `supervision` |
| Uptime Kuma | `127.0.0.1:3001` | rôle Ansible `supervision` (conteneur Docker) |
Rien de tout cela n'est exposé sur `eno1` (vérifié : seuls 22/80/443 répondent
depuis Internet). **Tant qu'il n'y a pas de domaine, l'accès se fait par
tunnel SSH.**
## Accéder aux interfaces (tunnel SSH depuis le Mac)
```
ssh -L 3000:10.10.0.1:3000 -L 9091:10.10.0.1:9091 -L 9093:10.10.0.1:9093 -L 3001:127.0.0.1:3001 paillasse
```
Puis dans le navigateur : `http://localhost:3000` (Grafana), `:9091`
(Prometheus), `:9093` (Alertmanager), `:3001` (Uptime Kuma — premier accès :
créer le compte admin toi-même, c'est une étape interactive).
Identifiants Grafana/Prometheus/Alertmanager : utilisateur `admin`, mot de
passe dans `/etc/kolla/passwords.yml` sur le serveur (`grafana_admin_password`,
`prometheus_password`, `prometheus_alertmanager_password`) — jamais affichés
ici, à lire toi-même :
```
sudo grep '^grafana_admin_password:' /etc/kolla/passwords.yml
```
## Alertes en place
Fichier `kolla/config/prometheus/alertes.rules` (poussé par le rôle
`supervision`, chargé par Prometheus) :
| Alerte | Condition | Sévérité |
|---|---|---|
| `DisqueSature` | occupation de `/` > 80 % pendant 5 min | avertissement |
| `MemoireSaturee` | RAM utilisée > 90 % pendant 5 min | avertissement |
| `ServiceOpenStackArrete` | un agent Nova ou Neutron à l'état différent de `up` pendant 2 min | critique |
| `SauvegardeAncienne` | dernière sauvegarde Dedibackup réussie il y a plus de 26 h | critique |
`SauvegardeAncienne` dépend d'une métrique maison
(`syllabus_derniere_sauvegarde_reussie_timestamp`), écrite par
`sauvegarde-dedibackup.sh` dans `/var/lib/node_exporter/textfile/sauvegarde.prom`
à chaque sauvegarde réussie (collecteur "textfile" de node_exporter).
**Limite connue, assumée pour l'instant : pas d'alerte « serveur
injoignable ».** Toute la chaîne (Prometheus, Alertmanager, le relais, ntfy)
tourne sur le même serveur que ce qu'elle surveille : si le serveur tombe
complètement, rien ne peut prévenir personne. C'est exactement pour ça que
CLAUDE.md prévoyait à l'origine une sonde **hors du serveur** (un petit
Hetzner CX23). Dans ce déploiement (un seul serveur Scaleway), ce n'est pas
fait — à décider avec Adam s'il veut un jour un point de supervision externe.
## Le relais Alertmanager → ntfy
Alertmanager ne sait pas parler nativement le format ntfy. Un petit service
Python (`/usr/local/sbin/alertmanager-ntfy.py`, service systemd
`alertmanager-ntfy`, écoute uniquement sur `127.0.0.1:9099`) reçoit le webhook
JSON standard d'Alertmanager et le retraduit en notification ntfy.
- L'URL ntfy (avec le topic) est lue à chaque notification depuis
`/root/.alertes-webhook` (`600 root:root`) — jamais mise en cache, jamais
journalisée, jamais dans Git.
- Configuration Alertmanager : `kolla/config/prometheus/prometheus-alertmanager.yml`
(receveur unique `ntfy`, webhook vers le relais local).
### Déclencher une alerte de test
Sans toucher à rien de réel sur le serveur, via l'API d'Alertmanager :
```
ssh paillasse
sudo bash -c '
PASS=$(awk -F": " "/^prometheus_alertmanager_password:/{print \$2}" /etc/kolla/passwords.yml)
MAINTENANT=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
FIN=$(date -u -d "+5 minutes" +%Y-%m-%dT%H:%M:%S.000Z)
curl -s --user "admin:$PASS" -XPOST http://10.10.0.1:9093/api/v2/alerts -H "Content-Type: application/json" -d "[{
\"labels\": {\"alertname\": \"TestManuel\"},
\"annotations\": {\"description\": \"Test manuel.\"},
\"startsAt\": \"$MAINTENANT\", \"endsAt\": \"$FIN\"
}]"
unset PASS
'
```
**Vérifié le 2026-10-07 : alerte de test reçue par Adam sur ntfy**, par ce
mécanisme et en testant aussi le relais directement
(`curl -XPOST http://127.0.0.1:9099/alertmanager ...`).
## Après tout changement à `kolla/config/prometheus/*` ou `kolla/globals.yml`
```
cd ansible && script -q /dev/null ansible-playbook kolla.yml -i inventory.ini
cd ansible && script -q /dev/null ansible-playbook supervision.yml -i inventory.ini
ssh paillasse "sudo -i bash -c 'export PATH=/opt/kolla-venv/bin:\$PATH; kolla-ansible reconfigure -i /etc/kolla/all-in-one --tags prometheus'"
```
**Piège vécu le 2026-10-07 :** modifier `kolla/globals.yml` ou un fichier de
`kolla/config/` dans le dépôt ne suffit pas : il faut d'abord rejouer
`kolla.yml`/`supervision.yml` pour le copier sur le serveur, **puis**
`kolla-ansible reconfigure`. Oublier la première étape fait tourner
`reconfigure` sur l'ancienne config, sans erreur visible.