Files

242 lines
13 KiB
Markdown

# backup / restore 기준
## 목적
이 문서는 K3s 및 일반 Kubernetes 인프라에서
- 무엇을 백업해야 하는지
- 어떤 도구/방식으로 백업할지 (Velero / CSI snapshot / pgBackRest / WAL-G / CNPG Barman)
- RPO / RTO를 어떻게 선언할지
- 복구 단위와 절차를 어떻게 표준화할지
- restore drill을 어떻게 운영할지
를 먼저 고정한다.
이 문서의 목표는 다음과 같다.
- "PVC가 있으니 백업도 된 것"이라는 착각을 제거한다
- "K3s etcd snapshot이 있으니 DB/PVC도 복구된다"는 오해를 제거한다
- 선언형 원본, 제어 평면, 상태 저장소를 서로 다른 백업 대상으로 구분한다
- 컴포넌트별 복구 전략과 도구를 먼저 정하고 YAML을 쓰게 한다
- 실제 장애 시 복구 절차를 재현 가능하게 만든다
## 공식 의미
- K3s etcd snapshot은 **클러스터 API 상태**(namespaces, secrets encryption key, RBAC, CRD instance 등)만 백업한다. **PVC의 데이터 내용은 백업하지 않는다.**
- K3s snapshot에는 cluster CA 인증서/개인키와 secrets encryption 관련 데이터가 포함될 수 있다.
- 새 호스트로 K3s snapshot을 복구할 때는 snapshot 당시 사용한 server token이 필요하다.
- Velero는 CNCF 표준 K8s 백업 도구로 `Backup` / `Schedule` / `Restore` CRD와 object storage 백엔드(S3 / MinIO / GCS / Azure Blob)를 사용한다.
- Velero file-level backup: File System Backup (FSB, kopia/restic) — 모든 CSI/비-CSI 볼륨의 파일 내용을 복제.
- Velero volume-level backup: CSI snapshot — CSI driver가 지원하는 경우 블록 수준 snapshot.
- VolumeSnapshotClass의 `deletionPolicy: Retain`이면 VolumeSnapshot 삭제 후에도 VolumeSnapshotContent(클라우드 snapshot)는 남는다.
- PostgreSQL의 기본 physical backup 도구로는 `pg_basebackup`(standalone) 외에 **pgBackRest** 또는 **WAL-G**가 사실상 표준이다. CloudNativePG operator는 내장으로 **Barman Cloud**를 사용한다.
- `pg_dump`는 logical export이며 정기 production 전체 백업의 기본 도구로는 보통 적합하지 않다.
- MinIO `mc mirror`는 현재 객체만 동기화하며 버전 이력/전체 메타데이터 보존에는 적합하지 않다.
- MinIO bucket replication은 versioning을 전제로 하고, DR 상황에서 `resync`를 지원한다.
## RPO / RTO 선언
모든 백업 대상은 아래 세 줄을 runbook에 먼저 적는다.
- **RPO (Recovery Point Objective)**: 허용 가능한 데이터 손실 시간
- **RTO (Recovery Time Objective)**: 허용 가능한 복구 시간
- **Retention**: 백업 보존 기간
이 세 값이 비어 있으면 도구/스케줄을 선택할 수 없다.
기본 tier 예시:
| Tier | RPO | RTO | Retention | 대표 도구 |
|---|---|---|---|---|
| gold | 5분 | 30분 | 30일 | CNPG continuous WAL + CSI snap 매일 |
| silver | 1시간 | 2시간 | 14일 | Velero hourly + CSI snap |
| bronze | 24시간 | 24시간 | 90일 | Velero daily FSB |
| archive | 24시간 | 72시간 | 7년 | Velero weekly → Glacier / cold bucket |
## 기본 규칙
### 1. 백업 대상은 세 층으로 분리
1. **선언형 원본 (Git)**: Kustomize base/overlay, Helm values, Argo CD Application, 운영 문서/runbook, 스크립트
2. **제어 평면 (K8s API state)**: K3s etcd snapshot / Velero API object backup
3. **상태 저장 데이터 (data plane)**: PVC / VolumeSnapshot, PostgreSQL 물리 백업, Vault raft snapshot, MinIO object data
이 셋을 하나의 방식으로 뭉뚱그리지 않는다. 특히 **K3s etcd snapshot은 (3)을 커버하지 않는다.**
### 2. Git은 배포 원본 백업이지 런타임 상태 백업이 아니다
Git/Kustomize는 source of truth지만 runtime DB state, Vault secret state, MinIO object data, K3s cluster membership state를 복원해 주지 않는다. Git 백업만으로 운영 복구가 된다고 판단하지 않는다.
### 3. K3s etcd snapshot은 제어 평면 전용 백업
K3s etcd snapshot은 API server의 선언 상태만 백업한다. PVC 안의 파일 내용은 포함하지 않는다.
기본:
- scheduled etcd snapshot 사용 (예: 6시간마다)
- local retention + S3/off-node retention 병행
- snapshot에는 secrets encryption key와 CA private key가 포함될 수 있으므로 민감 정보로 취급
- 저장 위치 암호화, 접근 통제, 보존 기간 통제, chain of custody 확인
- 새 호스트 복구용 server token을 별도 위치에 보관 (같은 곳에 두면 동시 유출 위험)
### 4. 상태 저장 데이터 백업은 Velero가 표준
Kubernetes 수준에서 PVC / 네임스페이스 / CRD를 함께 백업/복구하려면 **Velero**를 기본 도구로 둔다.
기본 구성:
- `BackupStorageLocation`: off-cluster S3 또는 cluster 외부 MinIO (같은 cluster 안 MinIO에 백업하지 않는다)
- `VolumeSnapshotLocation`: CSI driver 대응
- `Schedule` CRD로 cron 기반 정기 백업
- selector(`labelSelector`, `includedNamespaces`)로 tier별 스케줄 분리
- TTL로 retention 관리
### 5. Velero FSB(kopia/restic) vs CSI snapshot 선택
- **CSI snapshot**: 볼륨 수준 crash-consistent, 빠름, CSI driver 지원 필요. DB처럼 큰 볼륨에 적합. 클라우드 snapshot cost 고려.
- **File System Backup (FSB, kopia/restic)**: 파일 수준, 모든 볼륨에서 동작, 암호화/중복제거, 느림. local-path / hostPath / 비-CSI 볼륨에 적합.
운영 기본:
- CSI snapshot이 가능한 볼륨은 CSI snapshot 우선
- 크지 않은 설정/아카이브 볼륨은 FSB 허용
- DB 볼륨은 CSI snapshot이어도 app-consistent hook(pre/post backup) 필요
### 6. 오프-클러스터 백업 저장소 필수
백업을 **같은 K8s 클러스터 안**의 MinIO/S3에 두지 않는다. cluster 장애 = 백업 동시 소실이다.
기본:
- 별도 리전/별도 account의 S3-호환 object storage
- bucket versioning 활성화
- object-lock / WORM (규제 필요 시)
- 접근은 IRSA / Workload Identity / 최소권한 IAM
### 7. VolumeSnapshotClass `deletionPolicy`는 정책에 맞춘다
운영 gold tier 데이터의 VolumeSnapshotClass는 `deletionPolicy: Retain`을 기본으로 둔다.
이렇게 하면 K8s에서 VolumeSnapshot object가 지워져도 CSI driver의 실제 snapshot(VolumeSnapshotContent)은 남아서 사고 복구 여지를 준다.
### 8. PostgreSQL은 logical / physical / continuous를 구분
- `pg_dump` — logical export. 선택적 export, schema 비교, 마이그레이션 준비용. 프로덕션 전체 복구 기본값으로 두지 않는다.
- `pg_basebackup` — standalone base backup. 소규모/단순 케이스에 적합하지만 WAL archiving을 직접 구성해야 한다.
- **pgBackRest / WAL-G** — 프로덕션 표준. incremental / differential backup, parallel restore, retention, PITR, S3 업로드를 내장.
- **CloudNativePG (CNPG)** — K8s-native Postgres operator. 내장 **Barman Cloud**로 object storage에 WAL + base backup을 지속 업로드. `Backup` / `ScheduledBackup` CRD 제공.
### 9. K8s 위 Postgres 운영 기본은 CloudNativePG
2026 기준 K8s 상에서 Postgres를 운영한다면 **CloudNativePG (CNPG)**를 기본 후보로 둔다 (CNCF sandbox).
이유:
- `Cluster` CRD로 primary + standby 자동 관리, failover, rolling upgrade
- `backup` 섹션에서 Barman Cloud 기반 continuous archiving을 선언만 하면 동작
- `Backup` (on-demand), `ScheduledBackup` (cron), PITR restore가 `Cluster.spec.bootstrap.recovery`로 표준화
- Prometheus `PodMonitor` 내장
대안:
- **Zalando postgres-operator** — 오래된 생태계, Spilo 기반
- **Crunchy PGO** — 상용 지원 강점, pgBackRest 내장
manual StatefulSet + sidecar는 1000개 서비스 규모에서는 권장하지 않는다.
### 10. Keycloak DB는 애플리케이션과 분리된 DB 전략을 따른다
Keycloak이 외부 PostgreSQL을 사용하면 Keycloak 복구는 애플리케이션 Pod 복구보다 DB 백업 전략에 크게 의존한다. Keycloak server manifest만 백업해서는 충분하지 않다.
### 11. Vault는 storage mode에 따라 백업 방식을 다르게 본다
- integrated storage (raft) → `vault operator raft snapshot save` 기본
- external storage (Consul 등) → 해당 백엔드 백업 전략
- dev mode → 운영 대상 아님
Vault snapshot 복구 테스트는 격리된 네트워크/환경에서 수행한다 (live credential revoke, 원치 않는 cluster 간 통신, 데이터 일관성 훼손 방지).
### 12. MinIO는 PVC snapshot만으로 충분하다고 보지 않는다
object store는 단순 PV 파일 복사 관점보다 object versioning / replication / resync 포함 전략으로 본다.
기본:
- bucket versioning enabled
- 소스/대상 cluster replication configured
- DR 시 `mc replicate resync` 절차 문서화
- `mc mirror`는 현재 객체 동기화 용도로만 제한 (버전 이력 보존 안 됨)
- 스토리지 layer snapshot은 보조 수단
### 13. stateless workload는 데이터보다 재현성을 백업
다음은 기본적으로 런타임 파일 백업 대상이 아니다.
- auth-server, ingress-controller, stateless test-server
- 외부 DB 사용 Keycloak 서버 자체
복구 핵심:
- Git / Kustomize / Helm values
- Config / Secret source (Vault Secrets Operator 기준)
- 이미지 digest
- 운영 문서
### 14. migration-flyway는 산출물이 아닌 migration source를 백업
Flyway Job 자체나 container 파일시스템/PVC는 backup 대상이 아니다. 중요한 것은:
- migration script (Git)
- migration ordering + schema history table 상태 (DB 백업으로 포함)
- Flyway 실행 이력 (CI/CD 로그, Argo Rollout 기록)
### 15. 모든 백업은 "주기 + 보존기간 + 저장 위치 + 암호화 + 무결성 검증 + 복구 테스트"를 갖춘다
파일만 남기고 정책이 없는 것을 백업 전략으로 보지 않는다. 최소 메타데이터:
- Schedule cron 또는 RPO
- Retention TTL
- 저장 위치 (버킷, prefix, 리전)
- 암호화 방식 (SSE-S3 / SSE-KMS / client-side)
- 무결성 검증 (checksum, Velero `backup describe`의 errors)
- 복구 테스트 cadence + 마지막 성공 일자
### 16. restore drill은 표준 운영 절차
복구 가능한지 확인하지 않은 백업은 신뢰하지 않는다.
기본 cadence:
- 제어 평면 (K3s etcd / Velero): 분기별 1회
- DB physical restore + PITR: 월 1회
- Vault raft restore: 분기별 1회
- MinIO replication resync: 반기별 1회
기록 항목:
- 실행 일자
- 실행자
- 대상 snapshot/backup ID
- 실제 RTO / 확인된 RPO
- 발견된 issue
- 다음 drill 예정일
최근 90일 내 성공 기록이 없는 백업은 "신뢰할 수 있는 백업"으로 보지 않는다.
### 17. 복구 단위는 컴포넌트별로 다르게 정의
| 컴포넌트 | 복구 단위 | 기본 도구 |
|---|---|---|
| K3s control plane | cluster snapshot | k3s etcd-snapshot |
| K8s API object (namespace 단위) | Velero Backup | Velero |
| PostgreSQL cluster | DB cluster 전체 + PITR | CNPG Backup / pgBackRest |
| PostgreSQL single database | logical dump | `pg_dump` (보조) |
| Vault | raft snapshot | `vault operator raft snapshot` |
| MinIO | bucket / object / site | mc replication + resync |
| stateless apps | namespace/service redeploy | Argo CD + Git |
| PVC 일반 | VolumeSnapshot / Velero FSB | Velero + CSI |
모든 것을 "서비스 단위" 또는 "PVC 단위" 하나로만 보지 않는다.
### 18. 백업 구성은 Git으로 관리되고 GitOps sync된다
Velero `Schedule`, `BackupStorageLocation`, `VolumeSnapshotClass`, CNPG `ScheduledBackup`은 Argo CD / Flux로 동기화한다. kubectl 수동 편집 금지.
### 19. 백업과 복구는 다른 문서와 연결
다음 문서와 항상 연결한다.
- `storage-pvc.md` (PVC tier ↔ snapshot class)
- `db-and-migration.md` (DB 복구 전략)
- `operations-runbook-upgrade-rollback.md` (장애 시 절차)
- `config-and-secrets.md` (Vault 백업)
## 현재 스택 기본 권장안
- **K3s control plane**: etcd scheduled snapshot (6h) + S3 off-node 보관, server token 별도 안전 보관
- **PostgreSQL**: CloudNativePG + Barman Cloud (continuous WAL + daily base backup), RPO 5분
- **Vault**: integrated storage → raft snapshot 매일, 격리 환경에서 분기 1회 drill
- **MinIO**: bucket versioning + 별도 region으로 replication, mc resync runbook
- **PVC 일반**: Velero Schedule (tier별 분리) + CSI VolumeSnapshot
- **auth-server / ingress-controller / stateless**: Git + Argo CD 재현
- **migration-flyway**: migration source는 Git, DB 상태는 CNPG 백업에 포함
## 프로젝트 기준 요약
- 백업 대상은 선언형 원본 / 제어 평면 / 상태 저장 데이터로 분리
- K3s etcd snapshot은 PVC 데이터를 포함하지 않음 — 별도 Velero 필수
- Velero를 Kubernetes 백업 표준으로, off-cluster 저장소에 보관
- PostgreSQL은 CNPG + Barman Cloud (또는 pgBackRest / WAL-G) — `pg_dump`는 보조
- VolumeSnapshotClass `deletionPolicy`를 tier에 맞게 (운영은 Retain)
- RPO/RTO/Retention을 tier로 선언
- restore drill은 분기/월 단위 표준 cadence + 최근 성공 일자 기록
- 백업 구성은 GitOps로 관리