메인 콘텐츠로 건너뛰기

재해 복구 및 RTO/RPO 가이드

이 문서는 EKB AWS/EKS 인프라의 재해 복구 (DR) 전략, 복구 시간 목표 (RTO), 복구 지점 목표 (RPO)를 설명합니다. 내장된 HA 기능, 액티브 백업 시스템, 복구 절차 및 알려진_gap을 다룹니다.

정보

배포 지침은 Terragrunt 배포 가이드를 참조하세요.


아키텍처 및 고가용성 요약​

인프라 구성 요소​

구성 요소구현HA 모델
컴퓨팅EKS (Kubernetes 1.33) + Karpenter멀티 AZ 노드, Spot + 온디맨드
Pod 자동 스케일링KEDACPU/메모리 기반, 최소 2개 복제본
인그레스 / SSLALB + ACM멀티 AZ, 헬스 체크 라우팅
캐시ElastiCache Redis (조건부)자동 페일오버가 포함된 멀티 AZ
메시지 큐Amazon MQ / RabbitMQ (조건부)단일 인스턴스 또는 액티브/스탠바이
데이터베이스 (셀프호스팅)CloudNativePG HA 클러스터 + PgBouncer프라이머리 + 복제본, 자동 페일오버
데이터베이스 (클라우드)Supabase Cloud매니지드, 제공자에 의한 크로스 리전
관측 가능성SigNoz + k8s-infra (조건부)클러스터 내, 단일 장애 지점 없음
IaC 상태S3 (버전 관리) + DynamoDB 잠금암호화, 버전 관리
퍼시스턴트 볼륨EBS (EBS CSI Driver 경유)AWS Data Lifecycle Manager를 통한 스냅샷

현재 HA 기능​

기능복구 시간데이터 손실상태
AZ 장애 (Pod)0–5분없음활성
Pod 장애 / 크래시0–2분없음활성
ALB 헴스 체크 재라우팅0–1분없음활성
Redis Multi-AZ 페일오버< 1분없음활성 (활성화 시)
Karpenter 노드 교체0–10분없음활성
EBS 스냅샷 복원15–30분최대 24시간활성
CloudNativePG PITR 복원15–60분WAL 지연만큼활성 (활성화 시)
전체 인프라 재생성30–60분없음 (IaC)Terragrunt를 통해

RTO / RPO 목표​

시나리오RTO 목표RPO 목표현재 기능
단일 Pod 장애< 2분0충족 (KEDA 최소 복제본)
단일 노드 장애< 10분0충족 (Karpenter 교체)
AZ 장애< 5분0충족 (멀티 AZ 분산)
Redis 장애< 1분0충족 (멀티 AZ 페일오버)
Postgres 프라이머리 장애< 5분0–초 단위 WAL 지연충족 (CNPG 자동 페일오버)
EBS 볼륨 손실15–30분< 24시간부분적 — DLM 스냅샷 일간
전체 리전 장애> 60분백업 빈도에 따라현재 자동화되지 않음

백업 시스템​

1. Terraform / Terragrunt 상태 — S3​

백업 대상: 모든 인프라 상태 (EKS, 네트워킹, IAM, Helm 릴리스).

구현:

  • 환경별 S3 버킷: ekb-terraform-state-<env-name> (terragrunt/environments/<env-name>/state/를 통해 부트스트랩)
  • 버전 관리 활성화 — 이전 상태 버전을 모두 복원 가능
  • 서버 측 암호화 (AES-256)
  • 상태 잠금을 위한 DynamoDB 테이블

복구: S3에서 이전 상태 버전으로 롤백한 후 terragrunt apply를 다시 실행합니다.

RPO: 모든 terragrunt apply 커밋 — 지속적.


2. EBS 퍼시스턴트 볼륨 — AWS Data Lifecycle Manager​

백업 대상: Pod에 연결된 EBS 볼륨 (Automator PostgreSQL, Supabase MinIO, 모든 상태형 워크로드).

구현: 환경 태그를 대상으로 하는 AWS Data Lifecycle Manager (DLM) 정책.

# Tag EBS volumes with your environment name, then create a DLM policy:
# - Resource: EBS volumes
# - Target tag: Environment=<your-env-name>
# - Schedule: Daily at 02:00 UTC
# - Retention: 7 snapshots

복구:

# 1. Identify the snapshot to restore
aws ec2 describe-snapshots --filters "Name=tag:Environment,Values=<your-env-name>"

# 2. Create a volume from the snapshot
aws ec2 create-volume \
--snapshot-id snap-xxxxxxxxxxxxxxxxx \
--availability-zone <your-az> \
--volume-type gp3

# 3. Update the PersistentVolume in Kubernetes to reference the new volume ID
kubectl patch pv <pv-name> -p '{"spec":{"awsElasticBlockStore":{"volumeID":"<new-vol-id>"}}}'

RPO: 최대 24시간 (일간 스냅샷). DLM 스케줄 빈도를 늘려 줄일 수 있습니다.


3. CloudNativePG (HA Supabase DB) — Barman Cloud 백업​

적용 대상: ENABLE_CNPG=true 및 ENABLE_HA_SUPABASE_DB=true인 환경.

백업 대상: S3 또는 MinIO로의 지속적인 WAL (Write-Ahead Log) 스트리밍과 CNPG ScheduledBackup CRD를 통한 예약된 전체 기본 백업을 포함하는 CloudNativePG Postgres 클러스터 (ha-supabase-db).

구현 (values/ha-supabase-db.yaml에서 구성):

postgres:
backup:
enabled: true # toggle barman-cloud backups
# barmanObjectStore points to S3 bucket or MinIO endpoint
# IRSA / service account must have s3:PutObject, s3:GetObject, s3:ListBucket
retentionPolicy: "30d" # keep backups for 30 days
compression: gzip

백업 상태 확인:

# List all backups for the cluster
kubectl get backup -n ha-supabase-db

# Check a specific backup
kubectl describe backup <backup-name> -n ha-supabase-db

# Trigger an on-demand backup
kubectl cnpg backup ha-supabase-db -n ha-supabase-db

지점 복구 (PITR):

# Create a new CNPG Cluster restoring from a backup
# (in a new namespace or after removing the 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" # target point in time
externalClusters:
- name: ha-supabase-db
barmanObjectStore:
# same S3/MinIO config as the source cluster
serverName: ha-supabase-db

RPO: WAL가 활성화된 클러스터의 경우 거의 제로 (WAL 업로드 간격으로 제한되는 초 단위 지연).


4. ElastiCache Redis — Multi-AZ 복제​

적용 대상: ENABLE_AWS_SERVICES=true인 환경.

Redis는 기본 데이터 저장소가 아니며, 일시적인 캐시 및 세션 데이터를 보유합니다. DR 초점은 백업/복원보다는 빠른 페일오버에 있습니다.

구현:

  • 자동 페일오버가 포함된 Multi-AZ 활성화 -静态 저장소 및 전송 중 암호화
  • 프라이머리 노드 장애 시 복제본이 자동 승격 (< 1분)

RPO: Redis 데이터는 설계적으로 ephemeral합니다. 페일오버 후 캐시 미스는 예상되며, 애플리케이션이 데이터베이스에서 다시 채웁니다.


5. Amazon MQ (RabbitMQ) — 메시지 큐​

적용 대상: ENABLE_AWS_SERVICES=true인 환경.

구현:

  • 단일 인스턴스 (기본값) 또는 액티브/스탠바이 배포
  • 브로커 재시작 중 전송 중인 메시지가 손실될 수 있으므로, 소비자를 멱등성 있게 설계
  • 관리 UI는 포트 15671 (SSL)에서 사용 가능

RPO: 단일 인스턴스 — 장애 시점에 전송 중인 메시지가 손실될 수 있습니다. 이 위험을 줄이려면 액티브/스탠바이 배포 모드를 사용하세요.


자동 복구 메커니즘​

Karpenter — 노드 프로비저닝 및 복구​

  • 통합: WhenEmptyOrUnderutilized — 유휴 노드가 자동으로 종료됨
  • Spot 중단 처리: SQS 중단 이벤트를 수신; 종료 전에 Spot 노드를 드레인하고 교체
  • 노드 드리프트: 오래된 AMI 또는 구성을 사용하는 노드가 enable_drift = true일 때 자동으로 교체됨
  • 복구 시간: 새 노드가 0–10분 내에 프로비저닝됨

KEDA — Pod 자동 스케일링​

  • 최소 복제본: 모든 서비스 (Web, API, Celery, Automator)에 2개 — 단일 장애 지점 방지
  • CPU 임계값: 60–70%에서 스케일 아웃 트리거
  • 메모리 임계값: 80%에서 스케일 아웃 트리거
  • 스케일 다운 안정화: 30초 — 플래핑 방지
  • 복구 시간: 장애 Pod가 0–2분 내에 다시 스케줄링됨

Kubernetes Pod 안티어피니티​

모든 상태 비저장 서비스는 Pod를 노드와 AZ에 분산하기 위해 kubernetes.io/hostname에 대한 preferredDuringSchedulingIgnoredDuringExecution 안티어피니티를 사용합니다.

affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values: ["web", "fastapi-backend", "celery-worker", "automator"]
topologyKey: kubernetes.io/hostname

복구 절차​

시나리오 1: AZ 장애​

예상 동작: Karpenter가 나머지 AZ에 교체 노드를 프로비저닝하고; KEDA가 Pod를 다시 스케일링하고; ALB가 건강하지 않은 대상으로의 라우팅을 중지합니다.

검증:

kubectl get nodes -o wide # confirm nodes are in healthy AZs
kubectl get pods -A -o wide # confirm pods are running
kubectl get ingress # confirm ALB is routing correctly
정보

일반적인 상황에서는 수동 개입이 필요하지 않습니다.


시나리오 2: Postgres 프라이머리 노드 장애 (CloudNativePG)​

CloudNativePG가 자동으로 복제본을 프라이머리로 승격합니다.

# Monitor failover
kubectl get cluster ha-supabase-db -n ha-supabase-db -w

# Confirm new primary
kubectl cnpg status ha-supabase-db -n ha-supabase-db

# Check PgBouncer pooler is pointing to new primary
kubectl get svc -n ha-supabase-db | grep pooler

애플리케이션이 PgBouncer를 통해 재연결됩니다 — 연결 문자열 변경이 필요하지 않습니다.


시나리오 3: 스냅샷에서 EBS 볼륨 복원​

# 1. Find snapshots for the environment
aws ec2 describe-snapshots \
--filters "Name=tag:Environment,Values=<your-env-name>" \
--query 'Snapshots[*].[SnapshotId,StartTime,VolumeSize]' \
--output table

# 2. Create a new volume from the chosen snapshot
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. Scale down the affected workload
kubectl scale deployment <workload> --replicas=0

# 4. Update the PV to reference the new EBS volume, then scale back up
kubectl patch pv <pv-name> -p '{"spec":{"csi":{"volumeHandle":"<new-volume-id>"}}}'
kubectl scale deployment <workload> --replicas=2

시나리오 4: 전체 인프라 재생성​

치명적 장애 후 또는 리전을 재구축할 때 사용합니다.

# 1. Bootstrap state bucket (if it doesn't exist)
cd terragrunt/environments/<your-env-name>/state
terragrunt apply

# 2. Recreate the EKS cluster and core infrastructure
cd terragrunt/environments/<your-env-name>
terragrunt apply

# 3. Deploy services in order (see Terragrunt Deployment Guide § 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: 전체 클러스터의 경우 30–60분; EBS/CNPG 데이터를 복원해야 하는 경우 60–120분.


시나리오 5: Terragrunt 상태 롤백​

# List state versions in S3
aws s3api list-object-versions \
--bucket ekb-terraform-state-<your-env-name> \
--prefix <state-key>

# Restore a specific version
aws s3api get-object \
--bucket ekb-terraform-state-<your-env-name> \
--key <state-key> \
--version-id <version-id> \
terraform.tfstate

# Re-import or apply with the restored state

관측 가능성 및 알림 (SigNoz)​

ENABLE_SIGNOZ=true일 때, SigNoz가 monitoring 네임스페이스에 배포되어 다음을 제공합니다:

  • 모든 EKB 서비스에 대한 분산 추적
  • k8s-infra DaemonSet 에이전트를 통한 클러스터 메트릭 (CPU, 메모리, Pod 상태)
  • 모든 Pod에서의 로그 집계
  • 알림 — SigNoz에서 알림 규칙을 구성하여 Pod 크래시 루프, 높은 오류율 또는 노드 압력을 통보

DR 목적으로, SigNoz 대시보드는 사고 후 진단 및 복구 확인을 위한 주요 도구입니다. SigNoz 데이터 자체는 EBS PV에 저장되며 EBS 스냅샷 정책의 적용을 받습니다.


##_gap 및 권장 사항

gap위험권장 사항
크로스 리전 복제 없음전체 리전 장애 = 연장된 RTOCNPG 백업에 대한 RDS 크로스 리전 읽기 복제본 또는 S3 크로스 리전 복제를 고려하세요
EBS 스냅샷이 일간EBS 기반 워크로드의 최대 24시간 데이터 손실중요 볼륨의 DLM 빈도를 시간당으로 증가하세요
RabbitMQ 단일 인스턴스 (기본값)브로커 장애 시 전송 중 메시지 손실프로덕션에서는 ACTIVE_STANDBY_MULTI_AZ 배포 모드로 전환하세요
자동화된 DR 훈련 없음복구 절차가 필요할 때까지 테스트되지 않음분기별 복구 훈련을 예약하세요; 스테이징 환경에서 CNPG PITR 복원을 테스트하세요
동일 클러스터의 SigNoz클러스터 장애 시 관측 가능성 손실별도의 경량 모니터링 엔드포인트 또는 CloudWatch 폴백 알림을 고려하세요