CNCF는 2026년 9월 10일, 백업이 Completed 상태로 종료되었는지만 확인하는 것이 아니라 상태 저장 Kubernetes 애플리케이션의 재해 복구를 테스트하기 위한 세 가지 재현 가능한 장애 시나리오를 기반으로 한 지침을 발표했다. 실험은 랩 저장소에서 노트북으로 실행할 수 있으며, 네 개의 행으로 구성된 알려진 콘텐츠를 사용하는 PostgreSQL 애플리케이션을 이용했다. 이를 통해 일반적인 상태 지표에 의존하지 않고 복구의 실제 결과를 검증할 수 있었다.
이 자료는 CNCF 앰배서더인 Saiyam Pathak과 Saloni Narang이 작성했다. 범위는 Kubernetes 내부 애플리케이션 상태 복구로 한정되며, 컴플라이언스 프레임워크, 제품 비교, 기본 클라우드 또는 데이터센터 인프라 복구는 다루지 않는다. Velero와 CSI Snapshot 인터페이스 같은 도구는 시나리오의 참조 구현으로 등장했으며, 장애 패턴은 동일한 역할을 수행하는 도구에도 적용된다.
완료된 백업은 복구 가능성을 입증하지 않는다
첫 번째 시나리오에서는 Kubernetes 백업 구성 요소를 YAML 형식의 리소스 정의와 영구 스토리지 볼륨 데이터로 분리했다. 랩에서는 클러스터 외부의 S3 호환 오브젝트 스토리지로 데이터를 전송하는 메커니즘과 함께 Velero를 사용했다. DataUpload 객체를 검사한 결과, 47,989,888바이트의 볼륨 데이터가 실제로 외부 저장소로 전송된 것으로 나타났다.
PVC를 포함한 네임스페이스를 삭제한 뒤 복구하자 약 2분 만에 동일한 네 개의 행이 복원되었다. 그러나 CNCF는 스토리지 볼륨 데이터를 보호한다고 해서 데이터베이스 백업이 자동으로 애플리케이션 수준에서 일관성을 갖는 것은 아니라고 경고한다. 애플리케이션에는 flush 또는 quiesce 절차가 필요할 수 있다. 또한 다른 인프라에서 복구할 때는 StorageClass 조정과 팀이 설계하고 테스트해야 하는 기타 변환이 필요할 수 있다.
더 중요한 점은 백업 도구가 리소스를 이미 존재하는 클러스터로 복구할 뿐, 노드, 네트워크, 로드 밸런서 또는 DNS를 생성하지 않는다는 것이다. 따라서 복구 계획은 백업을 수용할 환경을 명확히 정의해야 하며, 필요할 경우 Kubernetes 복구를 Infrastructure as Code 또는 Cluster API에 맡겨야 한다.
Git은 의도를 복원하지만 저장된 상태는 복원하지 않는다
두 번째 시나리오에서는 프로덕션 클러스터를 중단했고, 복구 클러스터는 사전에 존재하며 Git 저장소에 연결된 GitOps 컨트롤러와 공유 저장소에 연결된 백업 도구를 포함하고 있었다. 애플리케이션 동기화는 성공했고 StatefulSet은 실행 중이었으며 대시보드도 정상 상태를 표시했다. 그러나 데이터베이스를 조회하자 relation "attendees" does not exist 오류가 반환되었다.
원인은 Kubernetes나 GitOps의 장애가 아니었다. 저장소에는 정의만 포함되어 있었기 때문에 컨트롤러는 StatefulSet, Service 및 비어 있는 새 스토리지 볼륨을 다시 생성했다. 실제로 Git은 선언된 상태 또는 팀의 의도를 저장하는 반면, 백업은 실제 데이터를 저장한다. 어느 하나만으로는 애플리케이션 전체를 복구할 수 없다.
랩의 복구 방법은 동기화가 생성한 빈 애플리케이션을 제거한 뒤 백업 저장소에서 애플리케이션과 볼륨을 복구하고, 마지막으로 데이터를 예상 콘텐츠와 비교하는 방식이었다. 프로덕션 중단부터 검증된 데이터가 표시되기까지의 전체 과정은 실제 실험에서 4분, 재시험에서는 2분이 조금 안 걸렸다. CNCF는 이 수치가 프로그래밍된 부분만 포함하며, 사고 발견, 의사결정, 트래픽 전환 및 원래 환경으로의 복귀는 포함하지 않는다고 설명한다.
개별 스냅샷은 실제로 존재하지 않았던 복구 지점을 만들 수 있다
세 번째 시나리오에서는 서로 연결된 두 개의 스토리지 볼륨을 사용하는 애플리케이션을 테스트했다. 하나는 주문용이고 다른 하나는 결제용이었다. 랩은 초당 5회 비율로 일치하는 쌍을 기록했으며, 각 결제가 하나의 주문과 대응해야 한다는 조건을 적용했다. 5초 간격으로 두 개의 개별 스냅샷을 생성하자 각 스냅샷은 단독으로는 준비가 완료되고 정상인 것처럼 보였다. 그러나 복구 결과 마지막으로 기록된 주문은 108352건인 반면 결제는 108377건으로, 일치하는 주문이 없는 결제가 25건 존재했다.
이 결과는 개별 스토리지 작업이 각각 성공했다고 해서 여러 스토리지 볼륨으로 구성된 애플리케이션의 일관성이 보장되는 것은 아님을 보여 준다. 두 스냅샷을 함께 사용하면 실제로는 존재하지 않았던 특정 시점을 나타낼 수 있다. 자료는 백업 도구가 많은 PVC를 하나씩 처리하는 프로덕션 환경에서는 차이가 더 커질 수 있다고 설명한다.
Kubernetes 1.36에서 GA 상태가 된 VolumeGroupSnapshot은 하나의 레이블로 스토리지 볼륨을 식별하고 CSI를 통해 일관된 복구 지점을 요청하는 메커니즘을 제공한다. 조정된 실험에서는 주문과 결제의 마지막 번호가 109169로 일치했으며 두 항목의 관계 검증도 성공했다. 그러나 지원 여부는 드라이버에 따라 달라진다. 일반 VolumeSnapshots 지원만으로는 그룹 스냅샷 지원이 입증되지 않으며, 랩을 위해 조사한 주요 클라우드 드라이버 대부분은 2026년 중반까지 이를 구현하지 않았다. 또한 CRD, 스냅샷 기능 및 관련 플러그인을 명시적으로 활성화해야 한다.
복구 테스트는 무엇을 측정해야 하는가?
- 단순히 Pod를 삭제하고 재생성을 관찰하는 것이 아니라, 이전에 실행된 적 없는 깨끗한 대상에 전체 애플리케이션을 복구한다.
- 리소스 상태나 대시보드 색상만 확인하지 말고 예상 콘텐츠를 사용해 데이터와 사용자 접근 경로를 검증한다.
- 전체 과정을 시계로 측정하며, 실제 복구 시간에는 탐지, 의사결정, 트래픽 전환, 경우에 따라 원래 환경으로의 복귀가 포함된다는 점을 인식한다.
- 프로덕션 클러스터와 복구 클러스터처럼 독립적인 두 장애 영역을 사용하고, 백업 저장소는 두 영역 모두의 외부에 둔다.
편집적 해석: 도구와 복구 순서 사이의 간극
이 실험이 강조하는 실질적인 변화는 성공 기준을 “백업이 완료되었다”에서 “올바른 데이터가 복구되었고 접근할 수 있다”로 옮기는 것이다. 더 넓은 제약은 기본 Kubernetes가 데이터, 애플리케이션, 클러스터, 트래픽 및 ID를 조정하기 위한 공통 계약을 정의하지 않으며, 전체 애플리케이션 복구 단위와 외부 종속성을 설명하는 지속 가능한 표준 리소스도 제공하지 않는다는 점이다. 따라서 각 계층에 성숙한 도구가 제공되더라도 GitOps, 백업, 인프라 및 사용자 경로 사이의 경계는 여전히 팀의 책임으로 남는다. CNCF는 CNCF TAG Operational Resilience의 Cloud Native Business Continuity 이니셔티브가 생태계 격차 분석, 복구 지침 및 참조 아키텍처에 관한 기여를 모으고 있다고 밝혔다.