Ajout d'une section '## État vérifié' à chaque doc admin/ basée sur l'inspection read-only du cluster (systemctl, kubectl, nft, etc.). Aucune modification de service ni réécriture de documentation existante. Co-Authored-By: Hermes <hermes@funk.lab>
11 KiB
AlertManager Webhook — Pont Prometheus → Hermes
Service Python sur storage-01 qui reçoit les alertes Prometheus via AlertManager
et les transmet au profil monitor de Hermes pour analyse IA.
Architecture et flux
Prometheus (k8s, namespace monitoring)
│ Seuil dépassé (CPU, RAM, disk, pod crash...)
▼
AlertManager (k8s, namespace monitoring)
│ POST http://192.168.10.1:9093/webhook
│ Content-Type: application/json
▼
alertmanager-webhook.service (storage-01, port 9093)
│ Répond 200 immédiatement
│ Lance ask-agent en thread daemon
▼
ask-agent monitor "Alertes Prometheus reçues à HH:MM:SS : ..."
│ POST http://127.0.0.1:4000/v1/chat/completions
▼
LiteLLM Proxy (:4000)
│ modèle : qwen3-1.7b-monitor
▼
llama-server-monitor (gpu-01:1237, CPU 14 threads)
│ Répond dans les logs du service
▼
journalctl -u alertmanager-webhook
"ask-agent response: SERVICE SAIN — aucune action requise"
Point clé : le webhook répond HTTP 200 immédiatement, avant d'appeler ask-agent.
ask-agent tourne en arrière-plan (~20-60s) — AlertManager ne reste pas bloqué en attente.
Fonctionnement du webhook.py
1. Réception de l'alerte
AlertManager envoie un payload JSON de cette forme :
{
"alerts": [
{
"status": "firing",
"labels": {
"alertname": "NodeHighCPU",
"severity": "warning",
"instance": "192.168.10.1:9100"
},
"annotations": {
"summary": "CPU élevé sur storage-01",
"description": "CPU > 90% depuis 5 minutes (valeur : 93.2%)"
}
}
]
}
2. Formatage du message
Chaque alerte est formatée en texte lisible :
[FIRING] NodeHighCPU — severity=warning instance=192.168.10.1:9100
CPU élevé sur storage-01
CPU > 90% depuis 5 minutes (valeur : 93.2%)
Le message final envoyé à Hermes :
Alertes Prometheus reçues à 21:35:03 :
[FIRING] NodeHighCPU — severity=warning instance=192.168.10.1:9100
...
Analyse ces alertes : sont-elles critiques ? Quelles actions recommandes-tu ?
3. Exécution asynchrone
# HTTP 200 envoyé immédiatement → AlertManager libéré
self.send_response(200)
self.end_headers()
self.wfile.write(b"ok")
# ask-agent lancé en thread daemon
threading.Thread(target=run_agent, daemon=True).start()
ask-agent est lancé avec NO_COLOR=1 et TERM=dumb pour éviter les codes
ANSI dans les logs.
4. Réponse Hermes dans les logs
La réponse du modèle monitor apparaît dans journalctl ~20-60s après l'alerte :
INFO ask-agent response: SERVICE SAIN — CPU revenue à 45% après pic temporaire.
Aucune action requise. Surveiller sur 30 min.
Service systemd
# État
sudo systemctl status alertmanager-webhook
# Logs en direct
sudo journalctl -u alertmanager-webhook -f
# Logs récents
sudo journalctl -u alertmanager-webhook -n 50 --no-pager
# Redémarrer
sudo systemctl restart alertmanager-webhook
Le service tourne sous l'utilisateur alertmanager-webhook avec des permissions minimales.
Tester le webhook
Test curl manuel
# Depuis le poste perso ou storage-01
curl -s -X POST http://192.168.10.1:9093/webhook \
-H "Content-Type: application/json" \
-d '{
"alerts": [{
"status": "firing",
"labels": {
"alertname": "TestAlert",
"severity": "warning",
"instance": "storage-01:9100"
},
"annotations": {
"summary": "Test alerte manuelle",
"description": "Vérification du pipeline webhook → Hermes"
}
}]
}'
# Réponse attendue : ok
# Suivre la réponse Hermes
ssh storage-01 "sudo journalctl -u alertmanager-webhook -f"
# Attendre ~30-60s → la réponse ask-agent apparaît
Vérifier la connexion AlertManager → webhook
# Alertes actives dans AlertManager
curl -s http://alertmanager.lab.local/api/v2/alerts | python3 -m json.tool
# Récepteurs configurés dans AlertManager
curl -s http://alertmanager.lab.local/api/v2/receivers | python3 -m json.tool
# Statut du webhook dans AlertManager (UI)
# http://alertmanager.lab.local/#/status → section "receivers"
Déclencher une vraie alerte
# Forcer une alerte Watchdog à passer par hermes-monitor (test de bout en bout)
# En modifiant temporairement la route dans values.yaml (à faire sur branche test)
# Ou créer un fichier flag d'alerte manuellement dans Prometheus
# (déconseillé en prod)
Configuration AlertManager
Le webhook est enregistré dans k8s/infra/monitoring/values.yaml comme receiver AlertManager :
alertmanager:
config:
route:
receiver: 'null' # receiver par défaut (Watchdog)
routes:
- matchers:
- alertname = "Watchdog"
receiver: 'null'
- receiver: 'hermes-monitor' # toutes les autres alertes → Hermes
receivers:
- name: 'null'
- name: 'hermes-monitor'
webhook_configs:
- url: 'http://192.168.10.1:9093/webhook'
send_resolved: true # envoie aussi les alertes résolues
send_resolved: true — quand une alerte passe de firing à resolved, AlertManager
envoie un nouveau payload avec "status": "resolved" — Hermes est informé de la résolution.
Déploiement et mise à jour
Fichiers
| Fichier | Emplacement | Rôle |
|---|---|---|
webhook.py |
ansible/roles/alertmanager_webhook/files/webhook.py |
Code source (versionné) |
webhook.py (déployé) |
/opt/alertmanager-webhook/webhook.py (storage-01) |
Instance active |
| Rôle Ansible | ansible/roles/alertmanager_webhook/ |
Déploiement, service systemd |
Redéployer après modification
# Depuis le poste perso
scp ansible/roles/alertmanager_webhook/files/webhook.py \
storage-01:/tmp/webhook.py
ssh storage-01 "sudo cp /tmp/webhook.py /opt/alertmanager-webhook/webhook.py \
&& sudo systemctl restart alertmanager-webhook \
&& sudo systemctl status alertmanager-webhook --no-pager"
Ou via Ansible (une fois le rôle hermes_user en place) :
cd /mnt/nvme0n1/nvme0n1p3/Projets/lab
.venv/bin/ansible-playbook -i ansible/inventory.yml ansible/playbooks/site.yml \
--tags alertmanager_webhook
Modifier le message envoyé à Hermes
Le prompt est construit dans webhook.py, fonction do_POST :
message = "\n".join(lines) + "\n\nAnalyse ces alertes : sont-elles critiques ? Quelles actions recommandes-tu ?"
Pour personnaliser l'instruction donnée à Hermes, modifier cette ligne et redéployer.
Ajouter un filtre d'alertes
Pour que certaines alertes n'arrivent pas à Hermes (trop bruyantes),
ajouter une route spécifique avant hermes-monitor dans values.yaml :
routes:
- matchers:
- alertname = "Watchdog"
receiver: 'null'
- matchers:
- severity = "info" # silencer les alertes info
receiver: 'null'
- receiver: 'hermes-monitor' # tout le reste → Hermes
git push → ArgoCD applique en ~3 minutes.
Dépannage
BrokenPipeError dans les logs
Symptôme : BrokenPipeError: [Errno 32] Broken pipe dans journalctl.
Cause : ancienne version du webhook qui envoyait le HTTP 200 après ask-agent
(bloquant ~54s → AlertManager fermait la connexion avant).
Solution : vérifier que le webhook.py déployé correspond bien à la version actuelle
(200 envoyé immédiatement, ask-agent en thread).
ssh storage-01 "grep -n 'send_response\|threading' /opt/alertmanager-webhook/webhook.py"
# Doit afficher send_response AVANT threading.Thread
Codes ANSI dans les logs (output illisible)
Symptôme : ask-agent response: 790G'*%G+>,<... (caractères parasites).
Cause : ask-agent utilise des couleurs terminal capturées brutes par subprocess.
Solution : vérifier que NO_COLOR=1 est passé à subprocess :
ssh storage-01 "grep 'NO_COLOR' /opt/alertmanager-webhook/webhook.py"
# Doit afficher : "NO_COLOR": "1"
Pas de réponse Hermes dans les logs (timeout)
ask-agent monitor a expiré après 120s. Causes possibles :
# LiteLLM répond ?
ssh storage-01 "curl -s http://localhost:4000/health \
-H 'Authorization: Bearer lm-studio'"
# llama-server-monitor tourne ?
ssh gpu-01 "systemctl status llama-server-monitor --no-pager"
# Logs ask-agent (stderr capturé)
ssh storage-01 "sudo journalctl -u alertmanager-webhook -n 30 --no-pager" \
| grep -E "stderr|error|timeout"
Le webhook ne reçoit pas les alertes AlertManager
# 1. Le service écoute sur le bon port ?
ssh storage-01 "ss -tlnp | grep 9093"
# 2. nftables autorise le pod CIDR ?
ssh storage-01 "sudo nft list ruleset | grep 9093"
# Doit contenir : 10.42.0.0/16
# 3. AlertManager atteint storage-01 ?
kubectl logs -n monitoring \
alertmanager-kube-prometheus-stack-alertmanager-0 \
| grep -i webhook | tail -20
Hermes répond mais l'analyse est mauvaise
Le profil monitor utilise Qwen3-1.7B (petit modèle CPU). Pour des analyses
plus poussées, modifier ask-agent pour utiliser brain (Claude Sonnet) sur les
alertes critiques — ou ajuster le SOUL.md du profil monitor.
# SOUL.md du profil monitor
ssh storage-01 "cat /srv/data/hermes/profiles/monitor/SOUL.md"
Points d'attention
| Sujet | Détail |
|---|---|
| Réponse asynchrone | Hermes répond dans les logs 20-60s après l'alerte — pas de retour vers AlertManager |
| Alertes résolues | send_resolved: true — Hermes reçoit aussi les résolutions, utile pour confirmer le retour à la normale |
| Port 9093 | nftables doit autoriser 10.42.0.0/16 (pod CIDR) ET 192.168.10.0/24 sur ce port |
| Modèle monitor | Qwen3-1.7B CPU (~21 tok/s) — rapide mais limité. Convient pour des verdicts courts (OK/WARNING/ERROR) |
| Pas de stockage | Les analyses Hermes ne sont pas persistées — elles apparaissent uniquement dans journalctl |
| Watchdog | L'alerte Watchdog (heartbeat interne Prometheus) est routée vers null — ne pas la router vers Hermes (spam toutes les minutes) |
État vérifié — 2026-06-05
- alertmanager-webhook.service : Actif (running) depuis 3 jours, PID 1431 (python3)
- Logs critiques : Erreurs répétées dans
ask-agent stderr(dernière à 2026-06-04 17:32:51) - Configuration : Fichiers YAML (/etc/alertmanager-webhook/) vides ou absents (sortie vide sur
cat) - Opérationnel : Forwarding d'alertes vers
ask-agent monitor(1 alerte active détectée le 2026-06-04) - Divergence : Aucun fichier de configuration trouvé malgré le service actif — risque de non-fonctionnement des règles d'alerte