Saltar al contenido principal
Este documento describe la estrategia de recuperación ante desastres (DR), el Objetivo de Tiempo de Recuperación (RTO) y el Objetivo de Punto de Recuperación (RPO) para la infraestructura EKB AWS/EKS. Cubre las capacidades HA integradas, los sistemas de respaldo activos, los procedimientos de recuperación y las brechas conocidas.
Para instrucciones de despliegue, consulte la Guía de Despliegue con Terragrunt.

Resumen de Arquitectura y Alta Disponibilidad

Componentes de Infraestructura

ComponenteImplementaciónModelo HA
CómputoEKS (Kubernetes 1.33) + KarpenterNodos multi-AZ, Spot + bajo demanda
Autoescalado de podsKEDABasado en CPU/Memoria, mínimo 2 réplicas
Ingreso / SSLALB + ACMMulti-AZ, enrutamiento por health-check
CachéElastiCache Redis (condicional)Multi-AZ con failover automático
Cola de mensajesAmazon MQ / RabbitMQ (condicional)Instancia individual o activo/en espera
Base de datos (autoalojado)Clúster HA CloudNativePG + PgBouncerPrimario + réplicas, failover automático
Base de datos (nube)Supabase CloudAdministrado, multi-región por el proveedor
ObservabilidadSigNoz + k8s-infra (condicional)Dentro del clúster, sin punto único de falla
Estado IaCS3 (versionado) + DynamoDB lockCifrado, versionado
Volúmenes persistentesEBS (vía EBS CSI Driver)Snapshots vía AWS Data Lifecycle Manager

Capacidades HA Actuales

CapacidadTiempo de RecuperaciónPérdida de DatosEstado
Fallo de AZ (pods)0–5 minNingunaActivo
Fallo / crash de pod0–2 minNingunaActivo
Re-enrutamiento por health-check ALB0–1 minNingunaActivo
Failover Multi-AZ de Redis< 1 minNingunaActivo (cuando está habilitado)
Sustitución de nodos Karpenter0–10 minNingunaActivo
Restauración de snapshot EBS15–30 minHasta 24 hActivo
Restauración PITR de CloudNativePG15–60 minHasta el retraso WALActivo (cuando está habilitado)
Recreación completa de infraestructura30–60 minNinguna (IaC)Vía Terragrunt

Objetivos RTO / RPO

EscenarioObjetivo RTOObjetivo RPOCapacidad Actual
Fallo de un solo pod< 2 min0Cumplido (réplicas mínimas KEDA)
Fallo de un solo nodo< 10 min0Cumplido (sustitución Karpenter)
Fallo de AZ< 5 min0Cumplido (distribución multi-AZ)
Fallo de Redis< 1 min0Cumplido (failover multi-AZ)
Fallo del primario de Postgres< 5 min0–segundos de retraso WALCumplido (failover automático CNPG)
Pérdida de volumen EBS15–30 min< 24 hParcial — snapshots DLM diarios
Fallo de región completa> 60 minDepende de la frecuencia de respaldoNo automatizado actualmente

Sistemas de Respaldo

1. Estado de Terraform / Terragrunt — S3

Qué se respalda: Todo el estado de infraestructura (EKS, red, IAM, releases de Helm). Implementación:
  • Bucket S3 por entorno: ekb-terraform-state-<env-name> (inicializado vía terragrunt/environments/<env-name>/state/)
  • Versionado habilitado — cualquier versión anterior del estado puede ser restaurada
  • Cifrado del lado del servidor (AES-256)
  • Tabla DynamoDB para bloqueo de estado
Recuperación: Revertir a cualquier versión anterior del estado en S3, luego volver a ejecutar terragrunt apply. RPO: Cada commit de terragrunt apply — continuo.

2. Volúmenes Persistentes EBS — AWS Data Lifecycle Manager

Qué se respalda: Volúmenes EBS adjuntos a pods (PostgreSQL de Automator, MinIO de Supabase, cualquier carga de trabajo con estado). Implementación: Política de AWS Data Lifecycle Manager (DLM) dirigida a etiquetas de entorno.
# Etiquete los volúmenes EBS con el nombre de su entorno, luego cree una política DLM:
# - Recurso: Volúmenes EBS
# - Etiqueta objetivo: Environment=<your-env-name>
# - Horario: Diario a las 02:00 UTC
# - Retención: 7 snapshots
Recuperación:
# 1. Identificar el snapshot a restaurar
aws ec2 describe-snapshots --filters "Name=tag:Environment,Values=<your-env-name>"
 
# 2. Crear un volumen a partir del snapshot
aws ec2 create-volume \
  --snapshot-id snap-xxxxxxxxxxxxxxxxx \
  --availability-zone <your-az> \
  --volume-type gp3
 
# 3. Actualizar el PersistentVolume en Kubernetes para referenciar el nuevo ID de volumen
kubectl patch pv <pv-name> -p '{"spec":{"awsElasticBlockStore":{"volumeID":"<new-vol-id>"}}}'
RPO: Hasta 24 horas (snapshots diarios). Reducir aumentando la frecuencia del horario DLM.

3. CloudNativePG (DB HA de Supabase) — Respaldos Barman Cloud

Aplica a: Entornos con ENABLE_CNPG=true y ENABLE_HA_SUPABASE_DB=true. Qué se respalda: El clúster Postgres de CloudNativePG (ha-supabase-db), incluyendo streaming continuo de WAL (Write-Ahead Log) a S3 o MinIO, y respaldos base completos programados vía el CRD ScheduledBackup de CNPG. Implementación (configurado en values/ha-supabase-db.yaml):
postgres:
  backup:
    enabled: true                    # activar respaldos barman-cloud
    # barmanObjectStore apunta al bucket S3 o endpoint MinIO
    # IRSA / service account debe tener s3:PutObject, s3:GetObject, s3:ListBucket
    retentionPolicy: "30d"           # mantener respaldos por 30 días
    compression: gzip
Verificar estado del respaldo:
# Listar todos los respaldos del clúster
kubectl get backup -n ha-supabase-db
 
# Verificar un respaldo específico
kubectl describe backup <backup-name> -n ha-supabase-db
 
# Activar un respaldo bajo demanda
kubectl cnpg backup ha-supabase-db -n ha-supabase-db
Recuperación a punto en el tiempo (PITR):
# Crear un nuevo CNPG Cluster restaurando desde un respaldo
# (en un nuevo namespace o después de eliminar el 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"  # punto en el tiempo objetivo
  externalClusters:
    - name: ha-supabase-db
      barmanObjectStore:
        # misma configuración S3/MinIO que el clúster fuente
        serverName: ha-supabase-db
RPO: Casi cero para clústeres con WAL habilitado (segundos de retraso, limitados por el intervalo de carga WAL).

4. ElastiCache Redis — Replicación Multi-AZ

Aplica a: Entornos con ENABLE_AWS_SERVICES=true. Redis no es un almacén de datos primario — almacena caché transitoria y datos de sesión. El enfoque DR está en un failover rápido en lugar de respaldo/restauración. Implementación:
  • Multi-AZ habilitado con failover automático
  • Cifrado en reposo y en tránsito
  • Un fallo del nodo primario promueve una réplica automáticamente (< 1 min)
RPO: Los datos de Redis son efímeros por diseño. Las fallas de caché después del failover son esperadas; la aplicación repuebla desde la base de datos.

5. Amazon MQ (RabbitMQ — Cola de Mensajes

Aplica a: Entornos con ENABLE_AWS_SERVICES=true. Implementación:
  • Despliegue de instancia individual (predeterminado) o activo/en espera
  • Los mensajes en tránsito pueden perderse durante un reinicio del broker; diseñar consumidores idempotentes
  • UI de gestión disponible en el puerto 15671 (SSL)
RPO: Instancia individual — los mensajes en tránsito al momento del fallo pueden perderse. Usar el modo de despliegue activo/en espera para reducir este riesgo.

Mecanismos de Auto-recuperación

Karpenter — Provisionamiento y Recuperación de Nodos

  • Consolidación: WhenEmptyOrUnderutilized — los nodos inactivos se terminan automáticamente
  • Manejo de interrupciones Spot: Escucha eventos de interrupción SQS; drena y sustituye nodos Spot antes de la terminación
  • Deriva de nodos: Los nodos que usan AMIs o configuraciones obsoletas se reemplazan automáticamente cuando enable_drift = true
  • Tiempo de recuperación: Nuevo nodo provisionado en 0–10 minutos

KEDA — Autoescalado de Pods

  • Réplicas mínimas: 2 para todos los servicios (Web, API, Celery, Automator) — previene punto único de falla
  • Umbral de CPU: 60–70% activa la escala ascendente
  • Umbral de memoria: 80% activa la escala ascendente
  • Estabilización de escala descendente: 30 segundos — evita fluctuaciones
  • Tiempo de recuperación: Pods fallidos reprogramados dentro de 0–2 minutos

Anti-afinidad de Pods de Kubernetes

Todos los servicios sin estado usan anti-afinidad preferredDuringSchedulingIgnoredDuringExecution en kubernetes.io/hostname para distribuir pods entre nodos y AZs.
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values: ["web", "fastapi-backend", "celery-worker", "automator"]
        topologyKey: kubernetes.io/hostname

Procedimientos de Recuperación

Escenario 1: Fallo de AZ

Comportamiento esperado: Karpenter provisiona nodos de reemplazo en las AZs restantes; KEDA reprograma pods; ALB deja de enrutar a objetivos no saludables. Verificación:
kubectl get nodes -o wide     # confirmar que los nodos están en AZs saludables
kubectl get pods -A -o wide   # confirmar que los pods se están ejecutando
kubectl get ingress            # confirmar que ALB está enrutando correctamente
No se requiere intervención manual bajo circunstancias normales.

Escenario 2: Fallo del Nodo Primario de Postgres (CloudNativePG)

CloudNativePG promueve automáticamente una réplica a primario.
# Monitorear el failover
kubectl get cluster ha-supabase-db -n ha-supabase-db -w
 
# Confirmar el nuevo primario
kubectl cnpg status ha-supabase-db -n ha-supabase-db
 
# Verificar que el pooler PgBouncer apunta al nuevo primario
kubectl get svc -n ha-supabase-db | grep pooler
Las aplicaciones se reconectan vía PgBouncer — no se necesita cambiar la cadena de conexión.

Escenario 3: Restaurar Volumen EBS desde Snapshot

# 1. Buscar snapshots del entorno
aws ec2 describe-snapshots \
  --filters "Name=tag:Environment,Values=<your-env-name>" \
  --query 'Snapshots[*].[SnapshotId,StartTime,VolumeSize]' \
  --output table
 
# 2. Crear un nuevo volumen a partir del snapshot elegido
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. Reducir las réplicas de la carga de trabajo afectada
kubectl scale deployment <workload> --replicas=0
 
# 4. Actualizar el PV para referenciar el nuevo volumen EBS, luego restaurar las réplicas
kubectl patch pv <pv-name> -p '{"spec":{"csi":{"volumeHandle":"<new-volume-id>"}}}'
kubectl scale deployment <workload> --replicas=2

Escenario 4: Recreación Completa de Infraestructura

Usado después de un fallo catastrófico o al reconstruir una región.
# 1. Inicializar el bucket de estado (si no existe)
cd terragrunt/environments/<your-env-name>/state
terragrunt apply
 
# 2. Recrear el cluster EKS y la infraestructura central
cd terragrunt/environments/<your-env-name>
terragrunt apply
 
# 3. Desplegar servicios en orden (ver Guía de Despliegue con Terragrunt § Fase 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 estimado: 30–60 minutos para el clúster completo; 60–120 minutos si se deben restaurar datos de EBS/CNPG.

Escenario 5: Reversión de Estado de Terragrunt

# Listar versiones de estado en S3
aws s3api list-object-versions \
  --bucket ekb-terraform-state-<your-env-name> \
  --prefix <state-key>
 
# Restaurar una versión específica
aws s3api get-object \
  --bucket ekb-terraform-state-<your-env-name> \
  --key <state-key> \
  --version-id <version-id> \
  terraform.tfstate
 
# Re-importar o aplicar con el estado restaurado

Observabilidad y Alertas (SigNoz)

Cuando ENABLE_SIGNOZ=true, SigNoz se despliega en el namespace monitoring y proporciona:
  • Traza distribuida para todos los servicios de EKB
  • Métricas del clúster vía el agente DaemonSet k8s-infra (CPU, memoria, estado de pods)
  • Agregación de logs de todos los pods
  • Alertas — configure reglas de alerta en SigNoz para notificar sobre bucles de crash de pods, altas tasas de error o presión de nodos
Para fines de DR, los paneles de SigNoz son la herramienta principal para diagnosticar y confirmar la recuperación después de un incidente. Los datos de SigNoz se almacenan en volúmenes EBS PV y están cubiertos por la política de snapshots EBS.

Brechas y Recomendaciones

BrechaRiesgoRecomendación
Sin replicación multi-regiónFallo de región completa = RTO extendidoConsiderar réplica de lectura multi-región RDS o replicación multi-región S3 para respaldos CNPG
Snapshots EBS son diariosHasta 24 h de pérdida de datos para cargas de trabajo con EBSAumentar la frecuencia DLM a horaria para volúmenes críticos
RabbitMQ de instancia individual (predeterminado)Mensajes en tránsito perdidos en fallo del brokerCambiar a modo de despliegue ACTIVE_STANDBY_MULTI_AZ para producción
Sin simulacro DR automatizadoProcedimientos de recuperación sin probar hasta que se necesitenProgramar simulacros trimestrales; probar restauración PITR de CNPG en un entorno de staging
SigNoz en el mismo clústerObservabilidad perdida durante fallo del clústerConsiderar un endpoint de monitoreo ligero separado o alertas de respaldo de CloudWatch