From fba0df26c3ad0e8063ddc2a3a8e5d27d19e23660 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Sun, 9 Aug 2026 14:14:16 -0400 Subject: [PATCH] metriques : node_exporter mourait a chaque renouvellement de certificat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le passage d'idempotence a trouve une PANNE, pas une imperfection. 17 taches changed au second passage contre 924 au rejeu depuis zero — mais 13 d'entre elles etaient « Activer et demarrer node_exporter », et Ansible ne le redemarrait pas par maladresse : il le trouvait ARRETE. Le dump du module : ActiveState inactive, SubState dead, ExecStart code=killed status=1/HUP. Cause : le script de synchro du certificat faisait try-reload-or-restart, qui RECHARGE si l'unite declare un ExecReload — et Debian en declare un (kill -HUP). node_exporter ne sait pas se recharger : il meurt sur SIGHUP. Le commentaire du script affirmait le contraire ; c'est l'hypothese qui etait fausse, pas le code. Consequence : a chaque renouvellement (24 h), la collecte de metriques s'arretait sur toute la flotte, en silence. Elle repartait au deploiement suivant, ce qui rendait la panne invisible a qui deploie souvent. Mesure sur backup-01 : reload alloy -> active, reload loki -> active, reload node_exporter -> INACTIVE. Seul lui est concerne. Corrige en restart. Preuve : synchro declenchee sur les 14, quatorze active. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 45 +++++++++++++++++++ .../setops-node-exporter-cert-sync.sh.j2 | 20 ++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 205087c..9ab38d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,50 @@ # CHANGELOG — Set-OPS +## 2026-08-09 — Le passage d'idempotence trouve une panne, pas une imperfection + +**17 tâches `changed` au second passage, contre 924 au rejeu depuis zéro.** La flotte +converge à 98 %. Mais les 17 restantes ne sont pas du bruit — l'une d'elles cachait un +service mort. + +``` +13x client_metrique : Activer et demarrer node_exporter + 1x serveur_prometheus : Deployer la configuration Prometheus -> redemarrage + 1x serveur_forgejo : Deployer app.ini -> redemarrage +``` + +**Treize hôtes sur quatorze redémarraient node_exporter à chaque passage.** Pas parce que +la tâche est mal écrite : parce qu'Ansible le trouvait **arrêté** et le ressuscitait. Le +dump du module le disait sans ambiguïté — `ActiveState: inactive`, `SubState: dead`, +`ExecStart ... code=killed ; status=1/HUP`. + +**La cause.** Le script de synchronisation du certificat faisait +`systemctl try-reload-or-restart prometheus-node-exporter`. Cette commande *recharge* si +l'unité déclare un `ExecReload` — et Debian en déclare un : `kill -HUP $MAINPID`. Or +node_exporter ne sait pas se recharger : **il meurt sur SIGHUP**. + +Le commentaire du script énonçait l'hypothèse inverse — « node_exporter relit le cert à +chaud ; un reload suffit ». C'est l'hypothèse qui était fausse, pas le code. + +**Conséquence, jusqu'à aujourd'hui** : à chaque renouvellement de certificat — toutes les +24 h — la collecte de métriques s'arrêtait sur toute la flotte, et **rien ne le disait**. +Elle repartait au déploiement suivant, ce qui rendait la panne invisible à qui déploie +souvent. + +**Mesuré plutôt que supposé**, sur `backup-01` : + +``` +systemctl reload alloy -> active +systemctl reload loki -> active +systemctl reload prometheus-node-exporter -> INACTIVE +``` + +Seul node_exporter est concerné ; `alloy` et `loki` honorent leur `ExecReload`. Le motif +`try-reload-or-restart` reste donc valable ailleurs — mais il fait confiance à une +promesse de l'unité que le binaire peut ne pas tenir, **en silence**. + +Corrigé en `restart`. **Preuve** : synchronisation déclenchée sur les quatorze hôtes, +quatorze `active`. + ## 2026-08-09 — Plus aucun `get_url` sans garde : la dépendance externe est comptée Arbitrage rendu par l'exploitant : garder aussi les clés de signature. **Zéro `get_url` diff --git a/roles/client_metrique/templates/setops-node-exporter-cert-sync.sh.j2 b/roles/client_metrique/templates/setops-node-exporter-cert-sync.sh.j2 index 8c2cec6..1e6774b 100644 --- a/roles/client_metrique/templates/setops-node-exporter-cert-sync.sh.j2 +++ b/roles/client_metrique/templates/setops-node-exporter-cert-sync.sh.j2 @@ -14,5 +14,21 @@ DST="{{ client_metrique_tls_dir }}" install -o prometheus -g prometheus -m 0644 "$SRC_CERT" "$DST/node.crt" install -o prometheus -g prometheus -m 0600 "$SRC_KEY" "$DST/node.key" -# node_exporter (exporter-toolkit) relit le cert a chaud ; un reload suffit. -systemctl try-reload-or-restart {{ client_metrique_service }} 2>/dev/null || true +# REDEMARRAGE, pas rechargement. L'unite Debian declare `ExecReload=kill -HUP $MAINPID`, +# mais node_exporter ne sait PAS se recharger : il MEURT sur SIGHUP. `try-reload-or-restart` +# fait donc confiance a un ExecReload que le binaire n'honore pas, et laisse le service +# arrete — silencieusement, jusqu'au prochain deploiement. +# +# Mesure du 2026-08-09, sur backup-01 : +# systemctl reload alloy -> active +# systemctl reload prometheus-node-exporter -> INACTIVE +# et dans l'unite morte : `ExecStart ... code=killed ; status=1/HUP`. +# +# Consequence de l'ancien code : a chaque renouvellement de certificat (toutes les 24 h), +# la collecte de metriques s'arretait sur les quatorze hotes sans que rien ne le dise. +# Trouve par le passage d'idempotence — 13 hotes rapportaient `changed` sur +# « Activer et demarrer node_exporter », parce qu'Ansible le RESSUSCITAIT a chaque fois. +# +# Le commentaire precedent enoncait une hypothese (« relit le cert a chaud ») ; c'est +# elle qui etait fausse, pas le code. +systemctl restart {{ client_metrique_service }} 2>/dev/null || true