Nous partons d’au moins deux passerelles et d’un banc de tests synthétiques ; ajoutez un notificateur digest si vous suivez déjà le modèle webhook décrit dans le guide OpenClaw multi-AZ sur clustervps. Calquez la dérivation de trafic sur le playbook canari multi-AZ, skills et sondes fusionnées, puis alignez les upgrades semver avec roulant 2026.4.x, peer deps et rollback canari pour ne jamais fusionner des fragments incompatibles avec un binaire différent. L’objectif est simple : chaque promotion se lit comme une recette, pas comme une archeologie de fichiers dispersés.
Répertoires de configuration par locataire
Sur chaque nœud, figez un squelette identique : /etc/openclaw/tenants/<tenant>/templates.d/ pour les gabarits (valeurs par défaut communes), workflows/<nom>/.d/ pour les fragments spécifiques à une file ou à un orchestrateur, et gateway.d/ plus doctor.d/ pour ce qui touche aux écouteurs et aux invariants. L’isolation de workflow se matérialise par des labels launchd distincts, des répertoires de données séparés et l’interdiction explicite de partager une base SQLite entre deux classes de jobs : deux workflows qui écrivent la même file finissent toujours par corrompre le merge logique avant même le YAML.
- Parité multi-nœuds : poussez les fragments depuis git (ou rsync depuis un Mac de vérité) puis vérifiez le même arbre avec
shasum -a256sur les passerelles avant toute bascule LB. - Secrets hors dépôt : montez
/var/db/openclaw/secrets/<tenant>en ACL restreintes ; seuls les gabarits référencent des chemins, jamais des valeurs sensibles. - Point de retour : conservez
tenants/<tenant>.prevcomme lien vers le dernier graphe valide pour accélérer le rollback décrit plus bas.
Stratégie de fusion des gabarits
Le merge doit être déterministe : chargez d’abord templates.d/00-base.yaml, puis des correctifs numérotés 10-, 20- jusqu’aux overrides locaux. Exécutez openclaw config lint --tenant <id> sur chaque Mac après synchronisation ; un échec de lint bloque la promotion, pas seulement le démarrage. Tenez un openclaw.lock versionné à côté du dépôt : si openclaw version --json diverge entre nœuds, refusez le merge même si le YAML « semble » compatible.
Versionnez chaque promotion avec un tag git et une entrée d’audit ; si le fournisseur OpenClaw publie des notes sur les limites de reload, recopiez-les dans votre wiki interne en une ligne par capacité (oui/non/partial) afin que l’astreinte n’ait pas à relire les release notes sous pression.
Sélection des nœuds canari et retour arrière
Choisissez un nœud déjà soumis à votre trafic synthétique (webhooks de démo, charge légère de skills) plutôt que la machine la moins utilisée : vous voulez détecter les collisions de fichiers et les fuites FD, pas seulement valider du YAML. Poussez une part LB faible (par ex. 3–5 %), observez latence p95, taux d’erreurs et la sonde fusionnée pendant deux fenêtres de sonde complètes. Augmentez par paliers en reprenant les ratios décrits dans le guide canari multi-AZ cité en introduction.
Rollback : videz d’abord le trafic du nœud fautif, rétablissez le graphe via ln -nfs tenants/<tenant>.prev tenants/<tenant> ou git checkout du tag précédent, relancez uniquement ce hôte, puis rouvrez la part LB quand la santé redevient verte deux fois consécutives. Ne redémarrez pas toute la grappe pour corriger un merge local : vous amplifiez le blast radius sans gagner de signal.
Fusion Doctor et contrôles de santé
L’équilibreur, Kubernetes et vos runbooks doivent converger vers une URL de readiness par passerelle. Agrégez au minimum : JSON openclaw doctor --tenant …, profondeur de file locale, pression APFS, et — si vous avez un notificateur — l’âge du digest webhook pour éviter le bruit des retries. Le digest reste une vue en lecture seule : ne la confondez pas avec une seconde sonde concurrente.
#!/usr/bin/env bash
set -euo pipefail
/usr/local/bin/openclaw doctor --tenant "${TENANT}" --json >/tmp/doctor.json
/usr/bin/curl -fsS --max-time 3 "http://127.0.0.1:9099/v1/webhook-digest" -o /tmp/digest.json || echo '{}' >/tmp/digest.json
/usr/bin/python3 - <<'PY'
import json
d=json.load(open("/tmp/doctor.json"));g=json.load(open("/tmp/digest.json"))
print(json.dumps({"ok":d.get("ok") and g.get("age_sec",999)<120,"doctor":d,"digest":g}))
PY
Exposez "status":"degraded" lorsque Doctor signale un avertissement non bloquant mais que le trafic peut continuer ; réservez HTTP non-200 aux ruptures réelles d’invariant. Tenez un court playbook d’exploitation : 1) comparer les arbres tenants/ entre nœuds, 2) relire openclaw.lock, 3) inspecter la readiness, 4) décider reload partiel ou restart passerelle selon votre tableau des frontières 2026.
Liste d’étapes (minimal reproductible)
- Aligner les Mac. Même build macOS, même
openclaw.lock, même arbretenants/<id>/…sur chaque passerelle. - Merger et linter. Synchronisez fragments + gabarits,
openclaw config lint --tenant <id>partout. - Canari. Basculer une faible part LB vers un nœud étiqueté, valider métriques et readiness agrégée.
- Étendre ou annuler. Monter les ratios si vert stable ; sinon drainer,
.prevou tag git, redémarrage ciblé. - Capitaliser. Noter ce qui a accepté hot reload vs restart dans le runbook interne.
Pour dimensionner la grappe avant d’ajouter un troisième nœud canari, comparez les forfaits Mac clustervps et passez par les pages publiques d’accueil ou d’aide afin d’aligner l’équipe finance et plateforme sur une offre nue-metal cohérente avec vos exigences de parité et de rollback.