serveur_redis : la sonde qui manquait, et la panne qu elle voit
Redis est le premier des treize roles serveur_* sans supervision declaree. Une seule sonde, parce qu il n y a qu une cause d action : le cache ne sert plus. Elle s atteint par deux chemins — il ne repond pas, ou il repond et n a rien a dire. Le second est le couteux : borne a maxmemory avec allkeys-lru, un Redis plein n echoue JAMAIS, il evicte. Les sessions disparaissent, les gens sont deconnectes au hasard, et le service reste vert. La panne se presente comme un defaut d application. Le compteur d evictions est cumulatif : la sonde en fait un DEBIT, sinon une seule mauvaise journee laisserait le voyant rouge pour toujours. Pas d occupation memoire ni de taux de succes ici — ce sont des series, elles appartiennent a Prometheus. Icinga repond a une seule question. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
parent
f199888f86
commit
050b8b267e
5 changed files with 128 additions and 1 deletions
|
|
@ -76,7 +76,7 @@
|
||||||
| P61 | Schema du plan : il decrit tout ce que les plans contiennent | AFF-033 | ✅ OK | Le schema decrit 47 champ(s) sur 6 registres ; il couvre tout ce que les plans reels contiennent, et la FORME de chaque champ (scalaire / objet / table) corresp |
|
| P61 | Schema du plan : il decrit tout ce que les plans contiennent | AFF-033 | ✅ OK | Le schema decrit 47 champ(s) sur 6 registres ; il couvre tout ce que les plans reels contiennent, et la FORME de chaque champ (scalaire / objet / table) corresp |
|
||||||
| P62 | Schema du plan : il decrit tout ce que le MOTEUR accepte | AFF-033 | ✅ OK | Les 4 validateurs n'acceptent aucun champ que le schema ignore (applications:8, bases_donnees:4, domaines_publics:5, serveurs:3 champ(s) lus par validateur). |
|
| P62 | Schema du plan : il decrit tout ce que le MOTEUR accepte | AFF-033 | ✅ OK | Les 4 validateurs n'acceptent aucun champ que le schema ignore (applications:8, bases_donnees:4, domaines_publics:5, serveurs:3 champ(s) lus par validateur). |
|
||||||
| P63 | cloud-init nait avec la VM et ne lui survit pas | — | ✅ OK | cloud-init est au gabarit (la premiere seconde), absent du socle (pas de va-et-vient), et retire par le durcissement — avec la garde qui verifie que le reseau s |
|
| P63 | cloud-init nait avec la VM et ne lui survit pas | — | ✅ OK | cloud-init est au gabarit (la premiere seconde), absent du socle (pas de va-et-vient), et retire par le durcissement — avec la garde qui verifie que le reseau s |
|
||||||
| P64 | Sondes de supervision : declarees ET deposees | — | ✅ OK | 26 sonde(s) declaree(s) ET deposee(s), chacune avec sa raison et son `ttl` : client_journal/journaux, client_metrique/metriques, client_pki/certificat, serveur_ |
|
| P64 | Sondes de supervision : declarees ET deposees | — | ✅ OK | 27 sonde(s) declaree(s) ET deposee(s), chacune avec sa raison et son `ttl` : client_journal/journaux, client_metrique/metriques, client_pki/certificat, serveur_ |
|
||||||
| P65 | Depots tiers : demandes au cache, jamais en HTTPS direct | — | ✅ OK | 4 depot(s) tiers relaye(s) par le cache, aucun role ne les vise en https:// ecrit en dur. |
|
| P65 | Depots tiers : demandes au cache, jamais en HTTPS direct | — | ✅ OK | 4 depot(s) tiers relaye(s) par le cache, aucun role ne les vise en https:// ecrit en dur. |
|
||||||
| P66 | Clients OIDC : chaque URI vise un nom que le plan expose | — | ✅ OK | 4 client(s) OIDC, toutes leurs URI visent un FQDN que le plan expose (6 exposition(s)). |
|
| P66 | Clients OIDC : chaque URI vise un nom que le plan expose | — | ✅ OK | 4 client(s) OIDC, toutes leurs URI visent un FQDN que le plan expose (6 exposition(s)). |
|
||||||
| P67 | Nom public : le service porte celui du plan, pas celui du role | — | ✅ OK | 6 service(s) expose(s) portent le nom du plan (6 groupe(s) derive(s)). |
|
| P67 | Nom public : le service porte celui du plan, pas celui du role | — | ✅ OK | 6 service(s) expose(s) portent le nom du plan (6 groupe(s) derive(s)). |
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,18 @@ serveur_redis_maxmemory_policy: "allkeys-lru"
|
||||||
|
|
||||||
# Mot de passe OBLIGATOIRE (expose sur le reseau interne). Ansible Vault.
|
# Mot de passe OBLIGATOIRE (expose sur le reseau interne). Ansible Vault.
|
||||||
serveur_redis_password: "{{ vault_redis | default('') }}" # rempli depuis la voute (vault_redis)
|
serveur_redis_password: "{{ vault_redis | default('') }}" # rempli depuis la voute (vault_redis)
|
||||||
|
|
||||||
|
# --- SONDE DE SUPERVISION ------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# COMBIEN D'EVICTIONS ENTRE DEUX PASSAGES AVANT DE CRIER. Le compteur de Redis est
|
||||||
|
# CUMULATIF depuis le demarrage ; la sonde en fait un DEBIT, sinon une seule mauvaise
|
||||||
|
# journee laisserait le voyant rouge pour toujours.
|
||||||
|
#
|
||||||
|
# 500 par quart d'heure : un cache qui travaille evicte un peu, c'est sa nature avec
|
||||||
|
# `allkeys-lru`. Ce seuil vise le moment ou l'eviction cesse d'etre un ajustement pour
|
||||||
|
# devenir une perte — des sessions qui disparaissent plus vite qu'on ne les cree.
|
||||||
|
#
|
||||||
|
# C'EST AUSSI LA MISE EN DEFAUT DE LA SONDE : le poser a 0 rend CRITIQUE des la premiere
|
||||||
|
# eviction, sans rien casser. Une sonde se prouve deux fois — verte sur le sain, rouge
|
||||||
|
# sur le casse — et ce parametre est ce qui rend la seconde preuve REJOUABLE.
|
||||||
|
serveur_redis_sonde_evictions_crit: 500
|
||||||
|
|
|
||||||
24
roles/serveur_redis/meta/supervision.yml
Normal file
24
roles/serveur_redis/meta/supervision.yml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
# Supervision derivee du role. Voir docs/supervision-conception.md.
|
||||||
|
#
|
||||||
|
# UNE SEULE SONDE, ET C'EST LA REGLE « une par CAUSE D'ACTION ». Redis peut cesser de
|
||||||
|
# servir de deux facons, et les deux appellent le meme geste — aller voir Redis :
|
||||||
|
#
|
||||||
|
# 1. IL NE REPOND PAS — service mort, mot de passe rejete, ecoute perdue.
|
||||||
|
# 2. IL REPOND ET N'A RIEN A DIRE — borne a `maxmemory` avec `allkeys-lru`, un Redis
|
||||||
|
# plein n'echoue JAMAIS : il evicte. Les sessions disparaissent, les gens sont
|
||||||
|
# deconnectes au hasard, et le service reste vert.
|
||||||
|
#
|
||||||
|
# LE SECOND CAS EST CELUI QUI MANQUAIT, et c'est le plus couteux. La panne se presente
|
||||||
|
# comme un probleme d'application : « on me deconnecte tout le temps ». Personne ne
|
||||||
|
# regarde le cache, puisqu'il va bien.
|
||||||
|
#
|
||||||
|
# TTL de 5400 s pour un porteur qui passe aux 15 min : trois passages manques avant la
|
||||||
|
# peremption. Le silence alerte autant que l'echec.
|
||||||
|
sondes:
|
||||||
|
- nom: cache
|
||||||
|
ttl: 5400
|
||||||
|
raison: 'Le cache repond-il, et sert-il encore ? Un Redis borne ne tombe pas quand il
|
||||||
|
est plein — il evicte. Les sessions se perdent une a une, les gens sont deconnectes
|
||||||
|
au hasard, et le service reste vert : la panne se presente comme un defaut
|
||||||
|
d''application.'
|
||||||
|
|
@ -36,3 +36,21 @@
|
||||||
name: "{{ serveur_redis_service }}"
|
name: "{{ serveur_redis_service }}"
|
||||||
enabled: true
|
enabled: true
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
|
# LE ROLE QUI POSSEDE LA VERITE DEPOSE SA PROPRE SONDE. `client_sante` la fait tourner et
|
||||||
|
# pousse le resultat ; il n'a pas a savoir ce qu'elle mesure, ni ou vit le mot de passe.
|
||||||
|
- name: Assurer le repertoire des sondes de supervision
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/local/lib/setops/sondes
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Deposer la sonde « cache »
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: sonde-cache.sh.j2
|
||||||
|
dest: /usr/local/lib/setops/sondes/cache.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0750"
|
||||||
|
|
|
||||||
70
roles/serveur_redis/templates/sonde-cache.sh.j2
Normal file
70
roles/serveur_redis/templates/sonde-cache.sh.j2
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# GENERE par Set-OPS (role serveur_redis). Ne pas editer a la main.
|
||||||
|
#
|
||||||
|
# SONDE « cache » — le cache repond-il, et sert-il encore a quelque chose ?
|
||||||
|
#
|
||||||
|
# Contrat : docs/supervision-conception.md (API des greffons Nagios) — une ligne, 0/1/2.
|
||||||
|
# Mise en defaut PAR PARAMETRE : `serveur_redis_sonde_evictions_crit` (seuil impossible).
|
||||||
|
#
|
||||||
|
# UNE SEULE SONDE, PARCE QU'IL N'Y A QU'UNE CAUSE D'ACTION : « le cache ne sert plus ».
|
||||||
|
# Elle s'atteint par deux chemins, et le verdict appelle le meme geste — aller voir Redis.
|
||||||
|
#
|
||||||
|
# 1. IL NE REPOND PAS. Service mort, mot de passe rejete, ecoute perdue.
|
||||||
|
# 2. IL REPOND ET N'A RIEN A DIRE. Borne a `maxmemory` avec `allkeys-lru`, un Redis
|
||||||
|
# plein n'echoue jamais : il EVICTE. Les sessions disparaissent, les gens sont
|
||||||
|
# deconnectes au hasard, et le service reste vert. C'est la panne la plus trompeuse
|
||||||
|
# de ce composant — elle se presente comme un probleme d'application.
|
||||||
|
#
|
||||||
|
# CE QU'ON NE MESURE PAS ICI, ET C'EST LA DOCTRINE : l'occupation memoire, le taux de
|
||||||
|
# succes du cache, la latence. Ce sont des SERIES ; elles appartiennent a Prometheus.
|
||||||
|
# Icinga repond a une seule question — est-ce casse ?
|
||||||
|
#
|
||||||
|
# LE PORTEUR TOURNE EN root ; `redis-cli` lit le mot de passe dans la configuration que
|
||||||
|
# le role a posee, jamais dans un argument de ligne de commande (il serait visible dans
|
||||||
|
# `ps` de toute la machine).
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
CONF={{ serveur_redis_config }}
|
||||||
|
CRIT={{ serveur_redis_sonde_evictions_crit }}
|
||||||
|
SERVICE={{ serveur_redis_service }}
|
||||||
|
|
||||||
|
systemctl is-active --quiet "${SERVICE}" || { echo "Redis n'est pas actif."; exit 2; }
|
||||||
|
|
||||||
|
mdp=$(grep -oP '(?<=^requirepass ).*' "${CONF}" 2>/dev/null)
|
||||||
|
cli=(redis-cli --no-auth-warning)
|
||||||
|
[[ -n "${mdp}" ]] && cli+=(-a "${mdp}")
|
||||||
|
|
||||||
|
# UN `PING`, PAS UN `connect()`. Le port peut repondre alors que l'authentification
|
||||||
|
# echoue : le client obtient une connexion et rien d'autre. `PING` traverse l'auth.
|
||||||
|
pong=$("${cli[@]}" ping 2>&1)
|
||||||
|
[[ "${pong}" == "PONG" ]] || { echo "Redis ne repond pas a PING : ${pong:0:70}"; exit 2; }
|
||||||
|
|
||||||
|
lire() { "${cli[@]}" info "$1" 2>/dev/null | grep -oP "(?<=^$2:)[0-9]+" | tr -d '\r'; }
|
||||||
|
|
||||||
|
evictions=$(lire stats evicted_keys)
|
||||||
|
[[ "${evictions}" =~ ^[0-9]+$ ]] || { echo "Redis vivant, compteur d'evictions illisible."; exit 1; }
|
||||||
|
|
||||||
|
# LE COMPTEUR EST CUMULATIF DEPUIS LE DEMARRAGE — on mesure donc un DEBIT, pas un total,
|
||||||
|
# sinon la sonde vire au rouge pour toujours apres une seule mauvaise journee.
|
||||||
|
etat=/var/lib/setops/sonde-redis-evictions
|
||||||
|
prec=$(cat "${etat}" 2>/dev/null || echo "")
|
||||||
|
mkdir -p "$(dirname "${etat}")" && echo "${evictions}" > "${etat}"
|
||||||
|
|
||||||
|
memoire=$(lire memory used_memory)
|
||||||
|
plafond=$("${cli[@]}" config get maxmemory 2>/dev/null | tail -1 | tr -d '\r')
|
||||||
|
perf="evictions=${evictions}c memoire=${memoire:-0}B;;;0;${plafond:-0}"
|
||||||
|
|
||||||
|
if [[ "${prec}" =~ ^[0-9]+$ ]] && (( evictions >= prec )); then
|
||||||
|
depuis=$(( evictions - prec ))
|
||||||
|
if (( depuis >= CRIT )); then
|
||||||
|
echo "Redis evicte : ${depuis} cles depuis le dernier passage — des sessions se perdent en silence.|${perf}"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
echo "Cache sain — ${depuis} eviction(s) depuis le dernier passage.|${perf}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Premier passage, ou compteur remis a zero par un redemarrage : on ne juge pas un debit
|
||||||
|
# qu'on ne peut pas calculer. Vert, et on le DIT — un « inconnu » muet serait pire.
|
||||||
|
echo "Cache sain — premier releve, debit d'eviction mesurable au prochain passage.|${perf}"
|
||||||
|
exit 0
|
||||||
Loading…
Reference in a new issue