Passer au contenu principal
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.
Pour les instructions de déploiement, consultez le Guide de déploiement Terragrunt.

Résumé de l’architecture et de la haute disponibilité

Composants de l’infrastructure

ComposantImplémentationModèle HA
CalculEKS (Kubernetes 1.33) + KarpenterNœuds multi-AZ, Spot + À la demande
Auto-escalade des podsKEDABasée sur CPU/Mémoire, min 2 répliques
Ingress / SSLALB + ACMMulti-AZ, routage avec vérification d’intégrité
CacheElastiCache Redis (conditionnel)Multi-AZ avec basculement automatique
File d’attente de messagesAmazon MQ / RabbitMQ (conditionnel)Instance unique ou actif/secondaire
Base de données (auto-hébergée)Cluster HA CloudNativePG + PgBouncerPrincipal + répliques, basculement automatique
Base de données (cloud)Supabase CloudGéré, multi-région par fournisseur
ObservabilitéSigNoz + k8s-infra (conditionnel)In-cluster, pas de point unique de défaillance
État IaCS3 (versionné) + verrou DynamoDBChiffré, versionné
Volumes persistantsEBS (via EBS CSI Driver)Snapshots via AWS Data Lifecycle Manager

Capacités HA actuelles

CapacitéTemps de récupérationPerte de donnéesStatut
Défaillance AZ (pods)0–5 minAucuneActif
Défaillance/crash du pod0–2 minAucuneActif
Reroutage de vérification d’intégrité ALB0–1 minAucuneActif
Basculement Redis Multi-AZ< 1 minAucuneActif (si activé)
Remplacement de nœud Karpenter0–10 minAucuneActif
Restauration depuis snapshot EBS15–30 minJusqu’à 24 hActif
Restauration PITR CloudNativePG15–60 minJusqu’au retard WALActif (si activé)
Récréation complète de l’infrastructure30–60 minAucune (IaC)Via Terragrunt

Objectifs RTO / RPO

ScénarioObjectif RTOObjectif RPOCapacité actuelle
Défaillance d’un seul pod< 2 min0Atteint (min replicas KEDA)
Défaillance d’un seul nœud< 10 min0Atteint (remplacement Karpenter)
Défaillance AZ< 5 min0Atteint (répartition Multi-AZ)
Défaillance Redis< 1 min0Atteint (basculement Multi-AZ)
Défaillance du principal Postgres< 5 min0–secondes retard WALAtteint (basculement automatique CNPG)
Perte de volume EBS15–30 min< 24 hPartiel — snapshots DLM quotidiens
Défaillance complète de la région> 60 minDépend de la fréquence de sauvegardeActuellement non automatisé

Systèmes de sauvegarde

1. État Terraform / Terragrunt — S3

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

LacuneRisqueRecommandation
Pas de réplication multi-régionDé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 quotidiensJusqu’à 24 h de perte de données pour les workloads sauvegardés par EBSAugmentez la fréquence DLM à horaire pour les volumes critiques
RabbitMQ instance unique (par défaut)Messages en vol perdus sur défaillance du brokerPassez au mode de déploiement ACTIVE_STANDBY_MULTI_AZ pour la production
Aucun exercice automatisé de DRProcédures de récupération non testées jusqu’à ce qu’elles soient nécessairesPlanifiez des exercices de récupération trimestriels ; testez la restauration CNPG PITR dans un environnement de staging
SigNoz sur le même clusterObservabilité perdue lors de la défaillance du clusterEnvisagez un endpoint de monitoring léger séparé ou des alertes de secours CloudWatch