Ce document décrit la stratégie de récupération après sinistre (DR), l’objectif de temps de récupération (RTO) et l’objectif de point de récupération (RPO) pour l’infrastructure AWS/EKS d’EKB. Il couvre les capacités de haute disponibilité intégrées, les systèmes de sauvegarde actifs, les procédures de récupération et les lacunes connues.
Résumé de l’architecture et de la haute disponibilité
Composants de l’infrastructure
| Composant | Implémentation | Modèle HA |
|---|
| Calcul | EKS (Kubernetes 1.33) + Karpenter | Nœuds multi-AZ, Spot + À la demande |
| Auto-escalade des pods | KEDA | Basée sur CPU/Mémoire, min 2 répliques |
| Ingress / SSL | ALB + ACM | Multi-AZ, routage avec vérification d’intégrité |
| Cache | ElastiCache Redis (conditionnel) | Multi-AZ avec basculement automatique |
| File d’attente de messages | Amazon MQ / RabbitMQ (conditionnel) | Instance unique ou actif/secondaire |
| Base de données (auto-hébergée) | Cluster HA CloudNativePG + PgBouncer | Principal + répliques, basculement automatique |
| Base de données (cloud) | Supabase Cloud | Géré, multi-région par fournisseur |
| Observabilité | SigNoz + k8s-infra (conditionnel) | In-cluster, pas de point unique de défaillance |
| État IaC | S3 (versionné) + verrou DynamoDB | Chiffré, versionné |
| Volumes persistants | EBS (via EBS CSI Driver) | Snapshots via AWS Data Lifecycle Manager |
Capacités HA actuelles
| Capacité | Temps de récupération | Perte de données | Statut |
|---|
| Défaillance AZ (pods) | 0–5 min | Aucune | Actif |
| Défaillance/crash du pod | 0–2 min | Aucune | Actif |
| Reroutage de vérification d’intégrité ALB | 0–1 min | Aucune | Actif |
| Basculement Redis Multi-AZ | < 1 min | Aucune | Actif (si activé) |
| Remplacement de nœud Karpenter | 0–10 min | Aucune | Actif |
| Restauration depuis snapshot EBS | 15–30 min | Jusqu’à 24 h | Actif |
| Restauration PITR CloudNativePG | 15–60 min | Jusqu’au retard WAL | Actif (si activé) |
| Récréation complète de l’infrastructure | 30–60 min | Aucune (IaC) | Via Terragrunt |
Objectifs RTO / RPO
| Scénario | Objectif RTO | Objectif RPO | Capacité actuelle |
|---|
| Défaillance d’un seul pod | < 2 min | 0 | Atteint (min replicas KEDA) |
| Défaillance d’un seul nœud | < 10 min | 0 | Atteint (remplacement Karpenter) |
| Défaillance AZ | < 5 min | 0 | Atteint (répartition Multi-AZ) |
| Défaillance Redis | < 1 min | 0 | Atteint (basculement Multi-AZ) |
| Défaillance du principal Postgres | < 5 min | 0–secondes retard WAL | Atteint (basculement automatique CNPG) |
| Perte de volume EBS | 15–30 min | < 24 h | Partiel — snapshots DLM quotidiens |
| Défaillance complète de la région | > 60 min | Dépend de la fréquence de sauvegarde | Actuellement non automatisé |
Systèmes de sauvegarde
Ce qui est sauvegardé : Tout l’état de l’infrastructure (EKS, réseautage, IAM, versions Helm).
Implémentation :
- Bucket S3 par environnement :
ekb-terraform-state-<env-name> (amorcé via terragrunt/environments/<env-name>/state/)
- Versioning activé — toute version d’état précédente peut être restaurée
- Chiffrement côté serveur (AES-256)
- Table DynamoDB pour le verrouillage d’état
Récupération : Restaurez à partir de n’importe quelle version d’état précédente dans S3, puis réexécutez terragrunt apply.
RPO : Chaque commit terragrunt apply — continu.
2. Volumes persistants EBS — AWS Data Lifecycle Manager
Ce qui est sauvegardé : Volumes EBS attachés aux pods (PostgreSQL Automator, MinIO Supabase, tout workload stateful).
Implémentation : Politique AWS Data Lifecycle Manager (DLM) ciblant les tags d’environnement.
# Taggez les volumes EBS avec votre nom d'environnement, puis créez une politique DLM :
# - Ressource : volumes EBS
# - Tag cible : Environment=<your-env-name>
# - Programme : Quotidien à 02:00 UTC
# - Rétention : 7 snapshots
Récupération :
# 1. Identifiez le snapshot à restaurer
aws ec2 describe-snapshots --filters "Name=tag:Environment,Values=<your-env-name>"
# 2. Créez un volume à partir du snapshot
aws ec2 create-volume \
--snapshot-id snap-xxxxxxxxxxxxxxxxx \
--availability-zone <your-az> \
--volume-type gp3
# 3. Mettez à jour le PersistentVolume dans Kubernetes pour référencer le nouvel ID de volume
kubectl patch pv <pv-name> -p '{\"spec\":{\"awsElasticBlockStore\":{\"volumeID\":\"<new-vol-id>\"}}}'
RPO : Jusqu’à 24 heures (snapshots quotidiens). Réduisez en augmentant la fréquence du programme DLM.
3. CloudNativePG (HA Supabase DB) — Sauvegardes Barman Cloud
S’applique à : Les environnements avec ENABLE_CNPG=true et ENABLE_HA_SUPABASE_DB=true.
Ce qui est sauvegardé : Le cluster CloudNativePG Postgres (ha-supabase-db), incluant le streaming WAL continu (Write-Ahead Log) vers S3 ou MinIO, et les sauvegardes de base complètes programmées via la CRD ScheduledBackup de CNPG.
Implémentation (configurée dans values/ha-supabase-db.yaml) :
postgres:
backup:
enabled: true # basculer les sauvegardes barman-cloud
# barmanObjectStore pointe vers un bucket S3 ou un endpoint MinIO
# IRSA / service account doit avoir s3:PutObject, s3:GetObject, s3:ListBucket
retentionPolicy: "30d" # conserver les sauvegardes pendant 30 jours
compression: gzip
Vérifiez le statut de sauvegarde :
# Listez toutes les sauvegardes du cluster
kubectl get backup -n ha-supabase-db
# Vérifiez une sauvegarde spécifique
kubectl describe backup <backup-name> -n ha-supabase-db
# Déclenchez une sauvegarde à la demande
kubectl cnpg backup ha-supabase-db -n ha-supabase-db
Récupération point-in-time (PITR) :
# Créez un nouveau cluster CNPG restauré à partir d'une sauvegarde
# (dans un nouvel espace de noms ou après suppression de l'original)
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: ha-supabase-db-restored
namespace: ha-supabase-db-restore
spec:
instances: 3
bootstrap:
recovery:
source: ha-supabase-db
recoveryTarget:
targetTime: "2026-03-19T03:00:00.000000+00:00" # point cible dans le temps
externalClusters:
- name: ha-supabase-db
barmanObjectStore:
# même configuration S3/MinIO que le cluster source
serverName: ha-supabase-db
RPO : Quasi-zéro pour les clusters activés WAL (secondes de retard, limité par l’intervalle de téléchargement WAL).
4. ElastiCache Redis — Réplication Multi-AZ
S’applique à : Les environnements avec ENABLE_AWS_SERVICES=true.
Redis n’est pas un magasin de données principal — il contient des données de cache transitoires et de session. L’accent de la DR est sur le basculement rapide plutôt que sur la sauvegarde/restauration.
Implémentation :
- Multi-AZ activé avec basculement automatique
- Chiffrement au repos et en transit
- Une défaillance de nœud principal promeut automatiquement une réplique (< 1 min)
RPO : Les données Redis sont éphémères par conception. Les défauts de cache après basculement sont attendus ; l’application réapprovisionne à partir de la base de données.
5. Amazon MQ (RabbitMQ) — File d’attente de messages
S’applique à : Les environnements avec ENABLE_AWS_SERVICES=true.
Implémentation :
- Instance unique (par défaut) ou déploiement actif/secondaire
- Les messages en vol peuvent être perdus lors du redémarrage du broker ; concevez les consommateurs pour être idempotents
- Interface de gestion disponible sur le port 15671 (SSL)
RPO : Instance unique — les messages en vol au moment de la défaillance peuvent être perdus. Utilisez le mode de déploiement actif/secondaire pour réduire ce risque.
Mécanismes de récupération automatique
Karpenter — Approvisionnement et récupération de nœuds
- Consolidation :
WhenEmptyOrUnderutilized — les nœuds inactifs sont automatiquement terminés
- Gestion des interruptions Spot : Écoute les événements d’interruption SQS ; draine et remplace les nœuds Spot avant la résiliation
- Dérive de nœud : Les nœuds utilisant des AMI ou des configurations obsolètes sont automatiquement remplacés lorsque
enable_drift = true
- Temps de récupération : Nouveau nœud approvisionné en 0–10 minutes
KEDA — Auto-escalade des pods
- Répliques minimales : 2 pour tous les services (Web, API, Celery, Automator) — prévient le point unique de défaillance
- Seuil CPU : 60–70% déclenche la montée en charge
- Seuil mémoire : 80% déclenche la montée en charge
- Stabilisation de réduction d’échelle : 30 secondes — évite le battement
- Temps de récupération : Les pods défaillants sont reprogrammés dans 0–2 minutes
Anti-affinité des pods Kubernetes
Tous les services sans état utilisent preferredDuringSchedulingIgnoredDuringExecution anti-affinité sur kubernetes.io/hostname pour répartir les pods entre les nœuds et les AZ.
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values: ["web", "fastapi-backend", "celery-worker", "automator"]
topologyKey: kubernetes.io/hostname
Procédures de récupération
Scénario 1 : Défaillance AZ
Comportement attendu : Karpenter approvisionne les nœuds de remplacement dans les AZ restantes ; KEDA reprogramme les pods ; ALB cesse de router vers les cibles non saines.
Vérification :
kubectl get nodes -o wide # confirmez que les nœuds sont dans des AZ saines
kubectl get pods -A -o wide # confirmez que les pods sont en cours d'exécution
kubectl get ingress # confirmez que ALB route correctement
Aucune intervention manuelle n’est requise dans des circonstances normales.
Scénario 2 : Défaillance du nœud principal Postgres (CloudNativePG)
CloudNativePG promeut automatiquement une réplique en principal.
# Monitorez le basculement
kubectl get cluster ha-supabase-db -n ha-supabase-db -w
# Confirmez le nouveau principal
kubectl cnpg status ha-supabase-db -n ha-supabase-db
# Vérifiez que le pooler PgBouncer pointe vers le nouveau principal
kubectl get svc -n ha-supabase-db | grep pooler
Les applications se reconnectent via PgBouncer — aucune modification de la chaîne de connexion n’est nécessaire.
Scénario 3 : Restaurer un volume EBS à partir d’un snapshot
# 1. Trouvez les snapshots de l'environnement
aws ec2 describe-snapshots \
--filters "Name=tag:Environment,Values=<your-env-name>" \
--query 'Snapshots[*].[SnapshotId,StartTime,VolumeSize]' \
--output table
# 2. Créez un nouveau volume à partir du snapshot choisi
aws ec2 create-volume \
--snapshot-id snap-xxxxxxxxxxxxxxxxx \
--availability-zone <target-az> \
--volume-type gp3 \
--tag-specifications 'ResourceType=volume,Tags=[{Key=Environment,Value=<your-env-name>}]'
# 3. Réduisez le workload affecté
kubectl scale deployment <workload> --replicas=0
# 4. Mettez à jour le PV pour référencer le nouveau volume EBS, puis augmentez à nouveau
kubectl patch pv <pv-name> -p '{\"spec\":{\"csi\":{\"volumeHandle\":\"<new-volume-id>\"}}}'
kubectl scale deployment <workload> --replicas=2
Scénario 4 : Récréation complète de l’infrastructure
Utilisé après une défaillance catastrophique ou lors de la reconstruction d’une région.
# 1. Amorcez le bucket d'état (s'il n'existe pas)
cd terragrunt/environments/<your-env-name>/state
terragrunt apply
# 2. Récréez le cluster EKS et l'infrastructure principale
cd terragrunt/environments/<your-env-name>
terragrunt apply
# 3. Déployez les services dans l'ordre (voir Guide de déploiement Terragrunt § Phase 6)
ENABLE_CNPG=true terragrunt apply --target='helm_release.local[\"cloudnative-pg\"]'
ENABLE_HA_SUPABASE_DB=true terragrunt apply --target='helm_release.local[\"ha-supabase-db\"]'
ENABLE_SUPABASE=true terragrunt apply --target='helm_release.local[\"supabase\"]'
RTO estimé : 30–60 minutes pour le cluster complet ; 60–120 minutes si les données EBS/CNPG doivent être restaurées.
Scénario 5 : Restauration de l’état Terragrunt
# Listez les versions d'état dans S3
aws s3api list-object-versions \
--bucket ekb-terraform-state-<your-env-name> \
--prefix <state-key>
# Restaurez une version spécifique
aws s3api get-object \
--bucket ekb-terraform-state-<your-env-name> \
--key <state-key> \
--version-id <version-id> \
terraform.tfstate
# Réimportez ou appliquez avec l'état restauré
Observabilité et alertes (SigNoz)
Lorsque ENABLE_SIGNOZ=true, SigNoz est déployé dans l’espace de noms monitoring et fournit :
- Traçage distribué pour tous les services EKB
- Métriques de cluster via l’agent DaemonSet k8s-infra (CPU, mémoire, statut des pods)
- Agrégation des journaux de tous les pods
- Alertes — configurez les règles d’alerte dans SigNoz pour être notifié sur les boucles de crash de pods, les taux d’erreur élevés ou la pression des nœuds
Pour les besoins de DR, les tableaux de bord SigNoz sont l’outil principal pour diagnostiquer et confirmer la récupération après un incident. Les données SigNoz elles-mêmes sont stockées sur des PV EBS et sont couvertes par la politique de snapshot EBS.
Lacunes et recommandations
| Lacune | Risque | Recommandation |
|---|
| Pas de réplication multi-région | Défaillance complète de la région = RTO prolongé | Envisagez une réplique de lecture multi-région RDS ou une réplication multi-région S3 pour les sauvegardes CNPG |
| Les snapshots EBS sont quotidiens | Jusqu’à 24 h de perte de données pour les workloads sauvegardés par EBS | Augmentez la fréquence DLM à horaire pour les volumes critiques |
| RabbitMQ instance unique (par défaut) | Messages en vol perdus sur défaillance du broker | Passez au mode de déploiement ACTIVE_STANDBY_MULTI_AZ pour la production |
| Aucun exercice automatisé de DR | Procédures de récupération non testées jusqu’à ce qu’elles soient nécessaires | Planifiez des exercices de récupération trimestriels ; testez la restauration CNPG PITR dans un environnement de staging |
| SigNoz sur le même cluster | Observabilité perdue lors de la défaillance du cluster | Envisagez un endpoint de monitoring léger séparé ou des alertes de secours CloudWatch |