Sauvegarde, restauration et PRA
Sections 20.5, 20.6, 20.7 et 20.10 de l'addendum du kit. HA, sauvegarde et PRA sont distincts : la HA (paquet
availability) maintient un service dans un site ; une sauvegarde est un artefact chiffré et contrôlé par empreinte sur
le stockage du client ; le PRA bascule la plateforme vers un autre site selon un plan approuvé. Chaque route est
listée dans navin-manager/CONTRACT.md section 20.5.
Sauvegarde
POST /api/v1/backup-targets: fournisseur (s3, azure_blob, gcs, ibm_cos, seaweedfs, filesystem), bucket,secret_ref(une référence, jamais un secret), capacités enregistrées par une qualification ({"supported": true, "verified_at"}).POST /api/v1/backup-plans: périmètre, intervalle, fenêtre,encryption_key_ref, rétention en jours,immutability_required. Un plan immuable sur une cible sans Object Lock ni rétention vérifiés est refusé (409backup_worm_unsupported) : échec fermé.- Les artefacts sont chiffrés en AES-256-GCM ; la clé de données dérive d'une clé de séquestre détenue hors du stockage
des sauvegardes (
NM_BACKUP_KEYS), seule sa référence est stockée. POST /api/v1/backups/{id}/verifycontrôle taille, SHA-256 et étiquette GCM.GET /api/v1/backup-plansrenvoie les plans en retard ou en échec ; chaque alerte est auditée (backup.alert).- Rétention :
DELETE /api/v1/backups/{id}est refusé avant l'expiration (409backup_retention_active) ;POST /api/v1/backups/retention/enforcesupprime les artefacts expirés. - Tests de restauration périodiques :
POST /api/v1/backups/{id}/restore-testsrestaure dans un répertoire isolé, peut injecter une corruption, signe le rapport en Ed25519 et lève une alarme auditée en cas d'échec. - Cohérence croisée :
POST /api/v1/backups/consistencycompare les lignes de la base, les objets stockés et le registre des artefacts, liste les orphelins et, avecreconcile, marque les lignes manquantes et met les objets orphelins en quarantaine.
Moteurs par composant
| Composant | Méthode (module navin_manager.backup.engines) |
|---|---|
| PostgreSQL | Sauvegarde complète pgBackRest, archivage WAL et PITR ; dans Kubernetes la method: plugin de CloudNativePG (deploy/data/postgres/backups.yaml). Un instantané de volume n'est jamais une sauvegarde PostgreSQL. |
| Points de reprise des agents | Tables eai.runs, eai.run_events, eai.checkpoints du plan de contrôle, dans le périmètre de sauvegarde PostgreSQL de la plateforme (AGENT_STATE_TABLES). |
| etcd | etcdctl snapshot save, etcdutl snapshot restore dans un nouveau répertoire, nouveau membre. |
| OpenSearch | Instantané vers un dépôt de type système de fichiers (path.repo), restauration dans un nouvel index. |
| Opik | Plan coordonné (navin_manager.backup.opik.plan) : mise au repos, export logique MySQL, BACKUP DATABASE ClickHouse, RDB Redis, bucket de stockage objet, reprise. Traces : engines.clickhouse_backup et engines.clickhouse_restore (BACKUP et RESTORE DATABASE natifs vers un disque de sauvegarde autorisé, refus si la base existe déjà). État : engines.mysql_dump (--single-transaction, routines, déclencheurs) et engines.mysql_restore. |
| Temporal | Copie de la persistance (API de sauvegarde SQLite pour le serveur de développement ; en production les bases Temporal sont dans PostgreSQL). |
| Artefacts | Dispositions OCI, prompts, skills, plugins, politiques et modèles dans un manifeste d'empreintes signé en Ed25519 (backup.artifacts). Un dépôt de registre OCI est exporté en disposition OCI avec oras, signature cosign comprise (artifacts.oci_export), puis rechargé après vérification du manifeste (artifacts.oci_load) : digest inchangé, cosign verify toujours accepté. |
| Secrets, certificats, AC | Archive chiffrée dont la clé est remise une fois au dépositaire et jamais stockée avec l'archive (backup.secrets_archive). |
| Preuves d'audit | Bucket SeaweedFS ou S3 Object Lock distinct du bucket des sauvegardes, qualifié par backup.worm.qualify. |
Les chaînes d'outils des tests viennent de tools/backup/fetch.sh (etcd 3.6.5, pgBackRest 2.56.0 compilé sans root,
schéma de la CRD Backup, ClickHouse 25.3.3.42 et MySQL 8.4.5 aux versions épinglées du catalogue du manager) et de
tools/oci/fetch.sh (zot, oras, cosign), toutes épinglées par sha256.
Restauration
POST /api/v1/restores/plan: étapes et contrôle de compatibilité (même version majeure par composant).POST /api/v1/restores/{id}/dry-run: empreinte, déchiffrement et compatibilité contrôlés, approbateurs déjà enregistrés.POST /api/v1/restores/{id}/approvepar deux personnes autres que le demandeur.POST /api/v1/restores/{id}/execute(permissionrestore:execute, distincte debackup:manage) : artefact recontrôlé ; en cas d'échec l'instantané de configuration est rétabli (rolled_back). Aucune exécution sans plan approuvé, production comprise.
PRA
POST /api/v1/dr-plans: mode active_passive, warm, cold ou active_active_stateless. L'actif-actif est limité aux couches sans état (portail, passerelles d'API, workers) ; les données gardent un écrivain unique par paire de sites.- Les objectifs RPO et RTO sont fixés par le client avec
PUT /api/v1/dr-plans/{id}/targets, vides par défaut. - Exercices et bascules : demande, approbation par une autre personne, clôture avec le RPO et le RTO mesurés pendant
l'exercice. L'exercice de bascule PostgreSQL de
tests/test_recovery_postgres_real.pyles mesure sur une exécution réelle. - Graphe de reprise (
recovery.dag) : étapes exécutées en processus locaux dans l'ordre des dépendances, avec contrôles de santé. - DNS et répartiteur de charge : modèles déclarés avec contrôles de santé (
/dr-plans/{id}/traffic,/switch-plan) ; le manager ne les applique jamais, le fournisseur du client le fait. - Reconstruction du manager (
recovery.rebuild) : paquet hors ligne vérifié, export de la base restauré dans une nouvelle base, migrations, contrôle de la chaîne d'audit, manifestes copiés ; aucun appel à l'éditeur. - Licence (
recovery.licence) : le vérificateur du plan de contrôle s'exécute hors ligne ; la licence du groupe d'installation reste valide dans l'installation restaurée du même groupe. - Réconciliation (
recovery.reconcile) : clés d'idempotence et reçus externes, aucun double paiement après bascule. - Isolement (fencing) :
navin_manager.recovery.fencing.fence_postgrespasse l'ancien primaire en lecture seule, écrit sonstandby.signalet l'arrête avant la promotion : un client qui désactivedefault_transaction_read_onlyne peut plus y écrire. Aucune route de l'API n'appelle encore ce module : seuls ses tests le font.
Limites
- Les exécutions MySQL et ClickHouse du plan Opik nécessitent
mysqldumpetclickhousesur l'hôte (ou les chemins passés danstools) ; sans eux le plan marque ces étapes bloquées. - La sauvegarde et le rechargement d'un Harbor réel (projets, comptes robots, réplication) nécessitent Docker ou un cluster : Harbor n'est livré qu'en images de conteneurs.
- Le plugin Barman Cloud de CloudNativePG exige l'opérateur 1.26 ou plus ; avec la version épinglée 1.25.0 la section
barmanObjectStoreintégrée de cluster.yaml reste active. - Les changements DNS et répartiteur nécessitent le DNS et le répartiteur du client ; l'exécution Velero nécessite un cluster.