powerdns : une zone plus recente que sa version servie est rechargee ; zones le voit
PowerDNS servait chez les deux locataires une zone anterieure a son fichier (console absente) : le handler de rechargement avait ete abandonne. Reconciliation a chaque passage (bind-reload-now) et controle dans la sonde zones. Plancher /etc/hosts rejoue sur les deux locataires ; console se resout depuis les edges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fbd4094d3f
commit
ba2020d486
4 changed files with 99 additions and 1 deletions
42
CHANGELOG.md
42
CHANGELOG.md
|
|
@ -1,5 +1,47 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-09-29 (30) — `console` ne se résolvait pas : un plancher périmé et une zone jamais rechargée
|
||||
|
||||
**Constat.** Depuis l'edge de chaque locataire, `console.<domaine>` ne se résolvait pas,
|
||||
alors que l'edge la sert. Les autres expositions se résolvaient.
|
||||
|
||||
**Première cause : le plancher `/etc/hosts` n'avait pas été rejoué.** Il dérive du plan
|
||||
(inventaire + `expose`), mais n'est posé que par le socle (`serveur_debian`). La console a
|
||||
été ajoutée au plan après le dernier passage du socle ; seul `ops-01`, redéployé depuis,
|
||||
la portait. Rejoué seul (`hosts_statiques`, sans `common_packages` et sa mise à jour
|
||||
complète) sur les 26 machines des deux locataires, après simulation : `console` ajoutée,
|
||||
`forge-01` et `forge` retirées (l'ancienne forge des locataires, sortie du plan).
|
||||
|
||||
**Seconde cause, plus grave : PowerDNS servait une zone antérieure à son fichier.** Le
|
||||
fichier de zone, réécrit le 16 septembre, portait `console` ; PowerDNS servait la version
|
||||
chargée à son démarrage (13 septembre chez Chezlepro, 14 chez Technolibre). Le rechargement
|
||||
ne passait que par un handler, et un handler en attente est abandonné quand une tâche échoue
|
||||
plus loin dans le même passage ; aux passages suivants, le fichier ne change plus et rien ne
|
||||
le redemande. La sonde `zones` comptait les zones servies, pas leur fraîcheur : verte.
|
||||
|
||||
- **Rôle `serveur_powerdns`** : à chaque passage, chaque zone (interne et publique) dont le
|
||||
fichier est plus récent que son chargement (`bind-domain-status`) est rechargée
|
||||
(`bind-reload-now`). Ce qui est à jour n'est pas touché.
|
||||
- **Sonde `zones`** : critique si une zone servie est plus ancienne que son fichier
|
||||
au-delà de `serveur_powerdns_sonde_tolerance` (900 s), en nommant les zones. Mise en
|
||||
défaut par ce paramètre : critique.
|
||||
- **Posé sur les trois** (Chezlepro, Technolibre, site) : deux zones rechargées chez chaque
|
||||
locataire ; au site, la zone et une zone inverse réécrites (le DNS public `site-dnspub-01`
|
||||
n'y était pas encore). `zones` au vert partout, « chacune conforme à son fichier ».
|
||||
`console` se résout depuis les deux edges, par le plancher et par PowerDNS.
|
||||
|
||||
**Une erreur de ma part, rattrapée par la garde de syntaxe.** `${#tableau[@]}` dans une sonde
|
||||
ouvre un commentaire Jinja. `test_sondes_syntaxe.py` l'a vu ; mais j'avais enchaîné le
|
||||
déploiement de Technolibre sans attendre le test, et la pose de la sonde y a échoué (la
|
||||
réconciliation, elle, était passée). Corrigé et redéployé ; la configuration publique
|
||||
réécrite pendant ce passage raté ne différait que par des commentaires.
|
||||
|
||||
**Ce qui n'est pas traité ici.** Les machines des locataires interrogent le résolveur du
|
||||
site, qui répond NXDOMAIN pour leurs noms internes : leur résolution repose entièrement sur
|
||||
le plancher. C'est l'état voulu tant que le basculement vers leur résolveur
|
||||
(`client_resolveur_apply`) n'est pas confirmé. Et rien ne signale encore qu'un plancher est
|
||||
en retard sur le plan : il suit le plan au déploiement, pas en continu.
|
||||
|
||||
## 2026-09-29 (29) — `passerelle` fait le trajet d'un visiteur jusqu'à la page de connexion ; fin de la revue des sondes
|
||||
|
||||
Cinquième et dernière des sondes « répond » de la revue (25).
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ serveur_powerdns_zones_inverses: >-
|
|||
# --- Sonde de supervision -----------------------------------------------------------
|
||||
# La zone souveraine et son inverse : deux au minimum.
|
||||
serveur_powerdns_sonde_minimum: 2
|
||||
# Ecart tolere (secondes) entre la date d'un fichier de zone et son chargement par
|
||||
# PowerDNS : le temps qu'un deploiement ecrive puis recharge. Au-dela, la zone servie
|
||||
# n'est pas celle du disque. Mise en defaut PAR PARAMETRE : une valeur tres negative.
|
||||
serveur_powerdns_sonde_tolerance: 900
|
||||
|
||||
# --- ZONES PUBLIQUES : `autorite: primaire-cache` (tasks/zones-publiques.yml) ---------
|
||||
#
|
||||
|
|
|
|||
|
|
@ -133,6 +133,40 @@
|
|||
# en vrai deploiement, la tache s'execute normalement.
|
||||
when: not ansible_check_mode
|
||||
|
||||
# LE FICHIER SUR DISQUE N'EST PAS LA ZONE SERVIE (2026-09-29). Le rechargement passait
|
||||
# seulement par un handler. Or un handler en attente est ABANDONNE si une tache echoue plus
|
||||
# loin dans le meme passage — et aux passages suivants le fichier ne change plus, donc plus
|
||||
# rien ne le redemande. Constate chez les deux locataires : zone reecrite le 16 septembre
|
||||
# (ajout de `console`), PowerDNS la servait telle que chargee le 13 ou le 14. Treize jours
|
||||
# de NXDOMAIN sur un nom que le fichier portait, et aucune sonde ne le voyait.
|
||||
#
|
||||
# On compare donc a chaque passage, zone par zone, la date du fichier a celle ou PowerDNS
|
||||
# l'a chargee, et on recharge ce qui est en retard. Ce qui est juste n'est pas touche.
|
||||
- name: Recharger toute zone dont le fichier est plus recent que la version servie
|
||||
ansible.builtin.shell:
|
||||
executable: /bin/bash
|
||||
cmd: |
|
||||
set -uo pipefail
|
||||
verifier() { # $1 = option d'instance ("" ou --config-name=public), $2 = repertoire
|
||||
local f z charge
|
||||
for f in "$2"/*.zone; do
|
||||
[[ -e "${f}" ]] || continue
|
||||
z=$(basename "${f}" .zone)
|
||||
charge=$(pdns_control $1 bind-domain-status "${z}" 2>/dev/null \
|
||||
| grep -oP 'parsed into memory at \K.*')
|
||||
if [[ -z "${charge}" ]] || (( $(date -r "${f}" +%s) > $(date -d "${charge}" +%s) )); then
|
||||
pdns_control $1 bind-reload-now "${z}" >/dev/null && echo "RECHARGEE ${z}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
verifier "" "{{ serveur_powerdns_zone_directory }}"
|
||||
{% if serveur_powerdns_dns_public_site | length > 0 %}
|
||||
verifier "--config-name=public" "{{ serveur_powerdns_public_zones_dir }}"
|
||||
{% endif %}
|
||||
register: serveur_powerdns_reconciliation
|
||||
changed_when: "'RECHARGEE' in serveur_powerdns_reconciliation.stdout"
|
||||
when: not ansible_check_mode
|
||||
|
||||
# --- Sonde de supervision (docs/supervision-conception.md) --------------------------
|
||||
# Le role qui possede la verite depose sa propre sonde ; le porteur (`client_sante`) la
|
||||
# fait tourner et pousse le verdict, sans savoir ce qu'elle mesure.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
set -uo pipefail
|
||||
|
||||
MINIMUM={{ serveur_powerdns_sonde_minimum }}
|
||||
TOLERANCE={{ serveur_powerdns_sonde_tolerance }}
|
||||
|
||||
systemctl is-active --quiet pdns || { echo "L'autoritatif (pdns) n'est pas actif."; exit 2; }
|
||||
[[ "$(pdns_control rping 2>&1 | head -1)" == "PONG" ]] \
|
||||
|
|
@ -21,4 +22,21 @@ if (( n < MINIMUM )); then
|
|||
echo "L'autoritatif ne sert que ${n} zone(s), moins que ${MINIMUM} — la resolution interne repondra NXDOMAIN.|zones=${n};${MINIMUM};;0;"
|
||||
exit 2
|
||||
fi
|
||||
echo "Autoritatif : ${n} zone(s) servie(s).|zones=${n};${MINIMUM};;0;"
|
||||
# LA ZONE SERVIE EST-ELLE CELLE DU DISQUE ? (2026-09-29) Compter les zones ne dit pas
|
||||
# lesquelles sont a jour : chez les deux locataires, PowerDNS a servi pendant treize jours
|
||||
# une zone anterieure a son fichier — `console` y manquait — et cette sonde restait verte.
|
||||
# `bind-domain-status` donne l'heure de chargement ; on la compare a celle du fichier.
|
||||
retard=()
|
||||
for f in {{ serveur_powerdns_zone_directory }}/*.zone; do
|
||||
[[ -e "${f}" ]] || continue
|
||||
z=$(basename "${f}" .zone)
|
||||
charge=$(pdns_control bind-domain-status "${z}" 2>/dev/null | grep -oP 'parsed into memory at \K.*')
|
||||
if [[ -z "${charge}" ]]; then retard+=("${z}=jamais chargee"); continue; fi
|
||||
ecart=$(( $(date -r "${f}" +%s) - $(date -d "${charge}" +%s) ))
|
||||
(( ecart > TOLERANCE )) && retard+=("${z}=fichier plus recent de $(( ecart / 3600 )) h")
|
||||
done
|
||||
if [[ -n "${retard[*]}" ]]; then # (le compteur de tableau de bash ouvrirait un commentaire Jinja)
|
||||
echo "L'autoritatif sert ${n} zone(s), mais PAS celles du disque : ${retard[*]} — les noms ajoutes depuis repondent NXDOMAIN. Redeployer serveur_powerdns.|zones=${n};${MINIMUM};;0;"
|
||||
exit 2
|
||||
fi
|
||||
echo "Autoritatif : ${n} zone(s) servie(s), chacune conforme a son fichier.|zones=${n};${MINIMUM};;0;"
|
||||
|
|
|
|||
Loading…
Reference in a new issue