Aller au contenu principal

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é (409 backup_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}/verify contrôle taille, SHA-256 et étiquette GCM. GET /api/v1/backup-plans renvoie 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 (409 backup_retention_active) ; POST /api/v1/backups/retention/enforce supprime les artefacts expirés.
  • Tests de restauration périodiques : POST /api/v1/backups/{id}/restore-tests restaure 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/consistency compare les lignes de la base, les objets stockés et le registre des artefacts, liste les orphelins et, avec reconcile, marque les lignes manquantes et met les objets orphelins en quarantaine.

Moteurs par composant​

ComposantMéthode (module navin_manager.backup.engines)
PostgreSQLSauvegarde 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 agentsTables 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).
etcdetcdctl snapshot save, etcdutl snapshot restore dans un nouveau répertoire, nouveau membre.
OpenSearchInstantané vers un dépôt de type système de fichiers (path.repo), restauration dans un nouvel index.
OpikPlan 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.
TemporalCopie de la persistance (API de sauvegarde SQLite pour le serveur de développement ; en production les bases Temporal sont dans PostgreSQL).
ArtefactsDispositions 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, ACArchive chiffrée dont la clé est remise une fois au dépositaire et jamais stockée avec l'archive (backup.secrets_archive).
Preuves d'auditBucket 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​

  1. POST /api/v1/restores/plan : étapes et contrôle de compatibilité (même version majeure par composant).
  2. POST /api/v1/restores/{id}/dry-run : empreinte, déchiffrement et compatibilité contrôlés, approbateurs déjà enregistrés.
  3. POST /api/v1/restores/{id}/approve par deux personnes autres que le demandeur.
  4. POST /api/v1/restores/{id}/execute (permission restore:execute, distincte de backup: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.py les 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_postgres passe l'ancien primaire en lecture seule, écrit son standby.signal et l'arrête avant la promotion : un client qui désactive default_transaction_read_only ne 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 mysqldump et clickhouse sur l'hôte (ou les chemins passés dans tools) ; 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 barmanObjectStore inté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.