파일 백업만으로 PostgreSQL을 복구하기 어려웠습니다
7월 21일부터 24일까지 백업 구성을 정리했습니다. PostgreSQL 데이터 디렉터리를 복사하는 작업과, 특정 시점으로 복구할 수 있는 데이터베이스 백업은 요구사항이 다릅니다. 실행 중인 DB에는 물리 백업과 그 이후의 WAL이 함께 필요합니다.
볼륨 파일 백업에는 Velero를 사용하고, PostgreSQL에는 CloudNativePG와 Barman Cloud CNPG-I 플러그인을 사용했습니다. 플러그인은 물리 백업과 WAL을 S3 호환 저장소인 Cloudflare R2에 보냅니다. MinIO의 오브젝트는 별도로 mc mirror를 사용해 R2에 복사합니다. 도구별 저장 prefix를 분리해 볼륨 복구, DB 복구, 오브젝트 복구의 입력을 구분했습니다.
예약 백업에는 플러그인과 시간대를 명시합니다
아래는 실제 구성 방식을 이름과 시각을 바꿔 축약한 예제입니다. example-db는 가상의 클러스터이며, 연결할 ObjectStore와 클러스터의 플러그인 설정은 이미 구성되어 있다고 가정합니다.
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: example-db-daily
namespace: example
spec:
cluster:
name: example-db
method: plugin
pluginConfiguration:
name: barman-cloud.cloudnative-pg.io
schedule: "0 0 19 * * *"
immediate: false
target: prefer-standby
backupOwnerReference: selfCloudNativePG의 schedule은 초를 포함하는 여섯 필드이고 UTC로 해석합니다. 예제의 19:00 UTC는 다음 날 04:00 한국 시간입니다. 일반적인 다섯 필드 crontab을 그대로 붙여 넣지 않습니다. prefer-standby는 가능한 경우 복제본에서 백업하도록 선택하지만 복제본의 존재를 보장하는 옵션은 아닙니다.
ObjectStore에는 S3 호환 endpoint, Secret 참조, destinationPath를 설정합니다. 보존 기간은 ObjectStore의 spec.retentionPolicy에서 관리합니다. 이 값은 디스크 전체의 보존 정책이 아니라 해당 DB 백업의 정책입니다. MinIO mirror에서도 원본 삭제가 백업 삭제로 전파되지 않도록 삭제 옵션을 구분했습니다.
completed와 WAL 보관을 따로 확인합니다
kubectl get backups.postgresql.cnpg.io -n example \
-o custom-columns=NAME:.metadata.name,PHASE:.status.phase,END:.status.stoppedAt
kubectl get objectstores.barmancloud.cnpg.io -n example -o yaml첫 번째 조회로 물리 백업 완료 여부와 완료 시각을 확인하고, ObjectStore 상태와 플러그인 로그로 WAL 업로드 실패를 확인합니다. 오래된 completed 하나만 보고 최신 백업도 정상이라고 판단하지 않습니다.
이번 작업에서는 백업 구성과 상태를 점검했습니다. 전체 데이터의 복구 훈련을 완료한 기록은 아니므로, 별도 환경에서 물리 백업과 WAL을 사용한 복원을 검증하는 단계는 구분합니다. 설정 필드의 의미는 Barman Cloud 플러그인 문서를 기준으로 확인합니다.