재해 복구 — 최악의 상황에 대비하는 DR 전략
RPO와 RTO로 재해 복구 목표를 정의하고, 백업·복구부터 파일럿 라이트·웜 스탠바이·액티브-액티브까지 비용과 복구 속도의 DR 티어를 비교하며, GitOps로 매니페스트를 Velero로 동적 상태와 볼륨을 백업해 다른 클러스터로 복구하는 실전 전략과 DR 리허설의 중요성을 정리합니다.
지난 글까지 클러스터를 안정적이고 효율적으로 운영하는 법을 다뤘다. 하지만 아무리 잘 운영해도 재해는 온다. 클라우드 리전 전체가 다운되고, 누군가 운영 네임스페이스를 통째로 지우고, 데이터가 손상되고, 랜섬웨어가 침투한다. 재해 복구(Disaster Recovery, DR)는 “그런 일은 없을 것”이 아니라 “그런 일이 일어났을 때 얼마나 빨리, 얼마나 온전히 되살릴 수 있는가”를 미리 설계하는 일이다.
DR을 정의하는 두 숫자 — RPO와 RTO
DR 논의는 두 개의 숫자로 시작한다. 이 둘을 정하지 않으면 어떤 DR 전략도 과하거나 부족하다.
RPO(Recovery Point Objective)는 “얼마만큼의 데이터 손실을 감내할 수 있는가”다. 마지막 백업 시점부터 장애 시점 사이의 데이터는 잃는다. 1시간마다 백업하면 RPO는 최대 1시간 — 즉 최악의 경우 1시간 치 데이터를 잃을 각오를 한다는 뜻이다. RPO를 줄이려면 백업을 더 자주 해야 한다.
RTO(Recovery Time Objective)는 “얼마나 빨리 복구해야 하는가”다. 장애 발생부터 서비스 재개까지 허용되는 시간이다. RTO를 줄이려면 복구가 더 자동화되고 더 준비돼 있어야 한다.
이 두 숫자는 비용과 직결된다. RPO·RTO를 0에 가깝게 만들수록 돈이 많이 든다. 그래서 DR 설계의 첫 단계는 “기술”이 아니라 “비즈니스 결정”이다 — 이 서비스가 1시간 멈추면 얼마를 잃는가? 그 답이 적정 RPO·RTO를, 그리고 다음의 DR 티어를 결정한다.
DR 티어 — 비용과 속도의 사다리
RPO·RTO 요구에 따라 DR 전략은 사다리처럼 나뉜다. 위 그림의 네 단계가 대표적이다.
백업·복구는 가장 단순하고 저렴하다. 스냅샷을 떠 보관했다가 재해 시 새 클러스터를 만들어 복구한다. 평상시 비용은 백업 스토리지뿐이지만, 복구에 시간~일이 걸린다(RTO 큼). 파일럿 라이트(pilot light)는 핵심 요소(데이터베이스 등)만 대기 리전에 상시 켜두고 나머지는 재해 시 띄운다. 웜 스탠바이(warm standby)는 축소판 클러스터를 항상 돌려두다가 전환 시 확장한다 — 비용이 오르지만 RTO가 분 단위로 줄어든다. 액티브-액티브는 두 리전에서 동시에 운영하며 한쪽이 죽어도 무중단으로 넘어간다 — RTO가 0에 가깝지만 가장 비싸다.
대부분의 서비스는 백업·복구나 파일럿 라이트로 충분하고, 결제·금융처럼 중단 비용이 극단적으로 큰 일부만 액티브-액티브를 정당화한다. 과한 DR은 그 자체로 낭비다.
무엇을 백업해야 하는가 — 두 축
쿠버네티스 DR에서 “백업”은 한 가지가 아니다. 되살려야 할 것이 두 축으로 나뉜다.
첫째는 선언적 상태(매니페스트)다. Deployment, Service, ConfigMap 같은 객체 정의다. 앞선 GitOps 글에서 다뤘듯 이것들이 Git에 있다면 별도 백업이 거의 필요 없다 — 새 클러스터에 Git을 다시 적용하면 워크로드가 재현된다. 이것이 GitOps가 DR 전략이기도 한 이유다.
둘째는 동적 상태와 데이터다. Git에 없는 것들 — PersistentVolume에 담긴 실제 데이터, 동적으로 발급된 Secret, 컨트롤러가 만든 객체의 런타임 상태 등이다. 이것은 GitOps로 재현되지 않으므로 별도로 백업해야 한다. 앞 글의 etcd 스냅샷이 한 방법이고, 더 흔히 쓰이는 도구가 Velero다.
Velero — 리소스와 볼륨을 함께 백업
Velero는 쿠버네티스 리소스와 PersistentVolume 데이터를 함께 백업해 오브젝트 스토리지(S3, GCS 등)에 저장하고, 같은 또는 다른 클러스터로 복구하는 도구다. etcd 스냅샷이 “클러스터 전체를 한 덩어리로” 다룬다면, Velero는 네임스페이스·라벨 단위로 골라 백업·복구할 수 있어 운영에 유연하다.
# 특정 네임스페이스를 매일 백업하는 스케줄 (볼륨 포함)
velero schedule create app-daily \
--schedule="0 2 * * *" \
--include-namespaces app \
--ttl 720h0m0s
# 재해 시: 백업으로부터 복구 (다른 클러스터에서도 가능)
velero restore create --from-backup app-daily-20260614020000
복구 대상이 다른 클러스터일 수 있다는 점이 DR의 핵심이다. 원본 리전이 통째로 사라져도, 오브젝트 스토리지가 다른 리전에 있다면 새 리전에 클러스터를 만들고 Velero로 복구할 수 있다. 그래서 백업 저장소는 반드시 원본과 다른 장애 도메인(리전)에 두어야 한다 — etcd 백업에서 강조한 “격리 보관”과 같은 원리다.
실무 구성은 두 축을 합친다. 매니페스트는 GitOps로, 동적 상태와 볼륨은 Velero로. 이 둘이 함께 있어야 클러스터를 온전히 되살릴 수 있다.
DR 계획은 리허설로만 증명된다
etcd 백업 글에서 했던 말이 DR에서는 더 무겁다. 한 번도 실행해보지 않은 DR 계획은 계획이 아니라 희망이다. 백업이 실제로 복구되는지, 복구된 클러스터가 정말 서비스 가능한지, 그리고 RTO 목표 안에 들어오는지는 리허설로만 확인된다.
게임데이(GameDay) — 의도적으로 장애를 일으켜 복구 절차를 처음부터 끝까지 돌려보는 훈련 — 를 정기적으로 한다. 여기서 런북의 빠진 단계, 잘못된 권한, 예상보다 긴 복구 시간 같은 문제가 드러난다. 그리고 이 훈련은 진짜 재해 때 당황하지 않을 근육 기억을 만든다.
정리 — 그리고 다음
재해 복구는 RPO(데이터 손실 허용)와 RTO(복구 시간 허용)라는 비즈니스 결정에서 출발한다. 그 요구에 맞춰 백업·복구부터 액티브-액티브까지 비용과 속도의 티어를 고른다. 쿠버네티스에서는 매니페스트를 GitOps로, 동적 상태와 볼륨을 Velero(또는 etcd 스냅샷)로 백업하며, 저장소는 다른 장애 도메인에 둔다. 그리고 이 모든 것은 정기 리허설로만 증명된다.
지금까지 운영, 비용, 재해까지 클러스터 차원의 큰 그림을 그렸다. 이제 시야를 다시 좁혀, 실제 장애가 눈앞에 닥쳤을 때 무엇부터 봐야 하는지 — 체계적인 진단 방법론을 다룬다. 다음 글은 트러블슈팅이다.
지난 글: 비용 최적화 — 쿠버네티스 자원 낭비 줄이기
다음 글: 트러블슈팅 방법론 — 장애를 체계적으로 진단하기
읽어주셔서 감사합니다. 😊