- Authors
- Name
- 들어가며
- Velero 아키텍처와 동작 원리
- 설치 및 초기 설정
- 스케줄 백업 전략과 RTO/RPO 설계
- CSI 스냅샷 연동 심화
- 크로스 클러스터 마이그레이션
- 멀티 리전 DR 전략
- 백업 도구 비교: Velero vs Kasten K10 vs etcd 백업
- 백업 전/후 훅(Hook) 활용
- 모니터링과 알림 체계
- 트러블슈팅 가이드
- 운영 주의사항과 모범 사례
- DR 복구 훈련 체크리스트
- 마치며
- 참고자료

들어가며
Kubernetes 클러스터를 프로덕션에서 운영하다 보면 "만약 이 클러스터가 통째로 날아가면 어떻게 되는가?"라는 질문에 직면하게 됩니다. etcd 장애, 클라우드 리전 장애, 잘못된 Helm 릴리스 롤백, 실수로 인한 네임스페이스 삭제 등 데이터 손실을 유발하는 시나리오는 생각보다 다양합니다.
Velero(구 Heptio Ark)는 VMware(현 Broadcom)가 주도하는 오픈소스 프로젝트로, Kubernetes 리소스와 퍼시스턴트 볼륨(PV)을 백업하고 복원하는 사실상의 표준 도구입니다. Velero를 활용하면 네임스페이스 단위 백업, CSI 볼륨 스냅샷, 크로스 클러스터 마이그레이션, 스케줄 기반 자동 백업 등을 구현할 수 있습니다.
이 글에서는 Velero의 아키텍처부터 설치, 스케줄 백업 설정, CSI 스냅샷 연동, 멀티 리전 DR 전략, 크로스 클러스터 마이그레이션, 그리고 실제 장애 사례별 복구 절차까지 운영 현장에서 바로 적용할 수 있는 수준으로 다룹니다.
Velero 아키텍처와 동작 원리
핵심 컴포넌트
Velero는 서버 사이드 컴포넌트와 CLI 클라이언트로 구성됩니다.
- Velero Server (Deployment): 클러스터 내에서 백업/복원 작업을 오케스트레이션하는 컨트롤러입니다. CRD(Custom Resource Definition) 기반으로 동작하며, Backup, Restore, Schedule 등의 리소스를 감시하고 처리합니다.
- Node Agent (DaemonSet): 파일 시스템 백업(FSB)을 담당합니다. 이전에는 Restic이 사용되었으나, Velero 1.12부터 Kopia가 기본 업로더로 채택되어 성능과 안정성이 향상되었습니다.
- BackupStorageLocation (BSL): 백업 데이터가 저장될 오브젝트 스토리지 위치를 정의합니다. AWS S3, GCS, Azure Blob Storage, MinIO 등을 지원합니다.
- VolumeSnapshotLocation (VSL): 볼륨 스냅샷이 생성될 클라우드 프로바이더 리전을 지정합니다.
- Velero CLI: 사용자가 백업/복원/스케줄 명령을 실행하는 커맨드라인 도구입니다.
백업 방식 비교: CSI 스냅샷 vs 파일 시스템 백업
Velero는 퍼시스턴트 볼륨 데이터를 백업하는 두 가지 방식을 제공합니다.
CSI 스냅샷 방식: Kubernetes CSI VolumeSnapshot API를 활용하여 스토리지 프로바이더 수준의 스냅샷을 생성합니다. 블록 레벨 스냅샷이므로 속도가 빠르고 일관성이 높습니다. 다만 CSI 드라이버가 스냅샷을 지원해야 합니다.
파일 시스템 백업(FSB) 방식: Kopia(또는 Restic)를 사용하여 PV 내 파일을 오브젝트 스토리지에 직접 업로드합니다. 스토리지 프로바이더에 무관하게 동작하지만, 파일 레벨 복사이므로 대용량 볼륨에서는 시간이 오래 걸립니다.
| 구분 | CSI 스냅샷 | 파일 시스템 백업(Kopia) |
|---|---|---|
| 속도 | 빠름 (블록 레벨) | 느림 (파일 레벨) |
| 스토리지 의존성 | CSI 드라이버 필수 | 범용 (모든 PV 지원) |
| 일관성 | 크래시 일관성 보장 | 파일 단위 일관성 |
| 크로스 리전 복원 | 제한적 (스냅샷 리전 종속) | 용이 (오브젝트 스토리지 기반) |
| 리소스 부하 | 낮음 | 높음 (CPU/메모리) |
| 증분 백업 | 스토리지 의존 | Kopia 내장 지원 |
백업 흐름 상세
Velero가 백업을 수행하는 순서는 다음과 같습니다.
- 사용자가 Backup CR을 생성하면 Velero 컨트롤러가 감지합니다.
- Kubernetes API를 통해 대상 리소스(Deployment, Service, ConfigMap, Secret, CRD 등)를 조회하고 JSON으로 직렬화합니다.
- 직렬화된 리소스를 tarball로 압축하여 BSL(오브젝트 스토리지)에 업로드합니다.
- PV가 포함된 경우 선택된 방식(CSI 스냅샷 또는 FSB)으로 볼륨 데이터를 백업합니다.
- 백업 메타데이터와 로그를 BSL에 함께 저장합니다.
설치 및 초기 설정
사전 요구사항
# Velero CLI 설치 (최신 안정 버전)
curl -fsSL -o velero-v1.15.0-linux-amd64.tar.gz \
https://github.com/vmware-tanzu/velero/releases/download/v1.15.0/velero-v1.15.0-linux-amd64.tar.gz
tar -xvf velero-v1.15.0-linux-amd64.tar.gz
sudo mv velero-v1.15.0-linux-amd64/velero /usr/local/bin/
# 버전 확인
velero version --client-only
# CSI 스냅샷을 사용할 경우 CRD 설치 확인
kubectl get crd | grep volumesnapshot
# volumesnapshotclasses.snapshot.storage.k8s.io
# volumesnapshotcontents.snapshot.storage.k8s.io
# volumesnapshots.snapshot.storage.k8s.io
AWS S3 기반 설치
가장 많이 사용되는 AWS S3를 대상으로 한 설치 예시입니다.
# S3 버킷 생성
aws s3api create-bucket \
--bucket velero-backup-prod \
--region ap-northeast-2 \
--create-bucket-configuration LocationConstraint=ap-northeast-2
# IAM 자격 증명 파일 생성
cat > credentials-velero <<EOF
[default]
aws_access_key_id=<YOUR_ACCESS_KEY>
aws_secret_access_key=<YOUR_SECRET_KEY>
EOF
# Velero 설치 (CSI 스냅샷 + Node Agent 활성화)
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.11.0 \
--bucket velero-backup-prod \
--backup-location-config region=ap-northeast-2 \
--snapshot-location-config region=ap-northeast-2 \
--secret-file ./credentials-velero \
--use-node-agent \
--features EnableCSI \
--wait
# 설치 확인
kubectl get pods -n velero
# NAME READY STATUS RESTARTS AGE
# node-agent-xxxxx 1/1 Running 0 30s
# node-agent-yyyyy 1/1 Running 0 30s
# velero-xxxxxxxxx-zzzzz 1/1 Running 0 30s
Helm 차트를 활용한 설치
프로덕션 환경에서는 Helm 차트를 활용하여 선언적으로 관리하는 것이 권장됩니다.
# values-velero.yaml
configuration:
backupStorageLocation:
- name: default
provider: aws
bucket: velero-backup-prod
config:
region: ap-northeast-2
volumeSnapshotLocation:
- name: default
provider: aws
config:
region: ap-northeast-2
features: EnableCSI
defaultVolumesToFsBackup: false
credentials:
useSecret: true
secretContents:
cloud: |
[default]
aws_access_key_id=<YOUR_ACCESS_KEY>
aws_secret_access_key=<YOUR_SECRET_KEY>
initContainers:
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-aws:v1.11.0
volumeMounts:
- mountPath: /target
name: plugins
- name: velero-plugin-for-csi
image: velero/velero-plugin-for-csi:v0.8.0
volumeMounts:
- mountPath: /target
name: plugins
deployNodeAgent: true
nodeAgent:
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: '2'
memory: 2Gi
resources:
requests:
cpu: 500m
memory: 256Mi
limits:
cpu: '1'
memory: 1Gi
schedules:
daily-production:
disabled: false
schedule: '0 2 * * *'
useOwnerReferencesInBackup: false
template:
ttl: '168h'
includedNamespaces:
- production
- staging
snapshotVolumes: true
storageLocation: default
volumeSnapshotLocations:
- default
# Helm으로 설치
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update
helm install velero vmware-tanzu/velero \
--namespace velero \
--create-namespace \
-f values-velero.yaml
스케줄 백업 전략과 RTO/RPO 설계
RTO와 RPO 개념 정리
Disaster Recovery 전략의 핵심은 두 가지 지표에 있습니다.
- RPO (Recovery Point Objective): 허용 가능한 최대 데이터 손실량을 시간으로 표현한 것입니다. RPO가 1시간이면 최대 1시간 분량의 데이터 손실을 감수할 수 있다는 의미입니다.
- RTO (Recovery Time Objective): 장애 발생 후 서비스를 정상 상태로 복구하는 데 허용되는 최대 시간입니다.
Velero의 백업 주기가 RPO를 결정하고, 복원 절차의 속도가 RTO를 결정합니다.
워크로드 등급별 백업 전략
| 워크로드 등급 | RPO 목표 | 백업 주기 | 보존 기간 | 백업 방식 |
|---|---|---|---|---|
| Tier 1 (미션 크리티컬) | 1시간 | 매 시간 | 72시간 | CSI 스냅샷 + FSB |
| Tier 2 (업무 핵심) | 4시간 | 6시간마다 | 7일 | CSI 스냅샷 |
| Tier 3 (일반) | 24시간 | 일 1회 | 30일 | FSB |
| Tier 4 (개발/테스트) | 1주 | 주 1회 | 14일 | FSB |
스케줄 백업 YAML 예시
# Tier 1: 미션 크리티컬 워크로드 - 매 시간 백업
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: tier1-hourly-backup
namespace: velero
spec:
schedule: '0 * * * *'
useOwnerReferencesInBackup: false
template:
ttl: 72h0m0s
includedNamespaces:
- payment
- order-service
snapshotVolumes: true
storageLocation: default
volumeSnapshotLocations:
- default
defaultVolumesToFsBackup: false
metadata:
labels:
backup-tier: 'tier1'
environment: 'production'
---
# Tier 3: 일반 워크로드 - 일일 백업
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: tier3-daily-backup
namespace: velero
spec:
schedule: '0 2 * * *'
useOwnerReferencesInBackup: false
template:
ttl: 720h0m0s
includedNamespaces:
- monitoring
- logging
- internal-tools
snapshotVolumes: false
defaultVolumesToFsBackup: true
storageLocation: default
metadata:
labels:
backup-tier: 'tier3'
environment: 'production'
지능형 보존 정책 (GFS 패턴)
Grandfather-Father-Son 패턴을 Velero 스케줄로 구현하여, 단기적으로는 세밀한 복구 지점을 유지하고 장기적으로는 스토리지 비용을 절감할 수 있습니다.
# 시간별 백업 (24시간 보존)
velero schedule create hourly-backup \
--schedule="0 * * * *" \
--ttl 24h0m0s \
--include-namespaces production \
--snapshot-volumes
# 일별 백업 (7일 보존)
velero schedule create daily-backup \
--schedule="0 3 * * *" \
--ttl 168h0m0s \
--include-namespaces production,staging \
--snapshot-volumes
# 주별 백업 (30일 보존)
velero schedule create weekly-backup \
--schedule="0 4 * * 0" \
--ttl 720h0m0s \
--snapshot-volumes
# 월별 백업 (365일 보존)
velero schedule create monthly-backup \
--schedule="0 5 1 * *" \
--ttl 8760h0m0s \
--snapshot-volumes
CSI 스냅샷 연동 심화
CSI 스냅샷 컨트롤러 설치
CSI 스냅샷을 활용하려면 클러스터에 스냅샷 컨트롤러와 CRD가 설치되어 있어야 합니다.
# CSI 스냅샷 CRD 설치
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
# 스냅샷 컨트롤러 설치
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
VolumeSnapshotClass 설정
Velero가 CSI 스냅샷을 사용하려면 VolumeSnapshotClass에 특정 레이블이 필요합니다.
# AWS EBS CSI 드라이버용 VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: ebs-csi-snapclass
labels:
velero.io/csi-volumesnapshot-class: 'true'
driver: ebs.csi.aws.com
deletionPolicy: Retain
parameters:
tagSpecification_1: 'velero-backup=true'
velero.io/csi-volumesnapshot-class: "true" 레이블이 설정된 VolumeSnapshotClass를 Velero가 자동으로 감지하여 CSI 스냅샷 생성에 사용합니다. deletionPolicy를 Retain으로 설정하면 VolumeSnapshot 리소스가 삭제되어도 실제 스냅샷 데이터는 보존됩니다.
CSI 스냅샷 데이터 이동 (Data Mover)
CSI 스냅샷은 기본적으로 스토리지 프로바이더 내에 로컬로 저장됩니다. 크로스 리전 또는 크로스 클라우드 DR을 위해서는 스냅샷 데이터를 오브젝트 스토리지로 이동해야 합니다. Velero 1.12부터 내장 Data Mover가 이 기능을 제공합니다.
apiVersion: velero.io/v1
kind: Backup
metadata:
name: production-with-datamover
namespace: velero
spec:
includedNamespaces:
- production
snapshotMoveData: true
storageLocation: default
datamover: velero
snapshotVolumes: true
snapshotMoveData: true를 지정하면 CSI 스냅샷 생성 후 해당 데이터를 BSL의 오브젝트 스토리지로 복사합니다. 이를 통해 원본 스냅샷이 특정 리전에 종속되는 문제를 해결할 수 있습니다.
크로스 클러스터 마이그레이션
마이그레이션 아키텍처
Velero를 활용한 크로스 클러스터 마이그레이션의 핵심은 소스 클러스터와 타겟 클러스터가 동일한 BSL(오브젝트 스토리지)을 공유하는 것입니다. 소스 클러스터에서 생성한 백업을 타겟 클러스터가 접근하여 복원할 수 있습니다.
마이그레이션 흐름:
- 소스 클러스터에서 마이그레이션 대상 네임스페이스 백업 생성
- 타겟 클러스터에 Velero 설치 (동일 BSL 구성)
- 타겟 클러스터에서 BSL 동기화 후 백업 목록 확인
- 선택한 백업으로부터 복원 수행
- 복원된 리소스 검증 및 DNS/Ingress 전환
마이그레이션 실행 절차
# [소스 클러스터] 마이그레이션 백업 생성
velero backup create migration-app-v2 \
--include-namespaces app-v2 \
--snapshot-volumes \
--snapshot-move-data \
--wait
# 백업 상태 확인
velero backup describe migration-app-v2 --details
# [타겟 클러스터] BSL 동기화 (Velero가 동일 S3를 바라보고 있어야 함)
# 기본적으로 1분 간격 동기화, 즉시 동기화는 아래 명령으로 실행
kubectl -n velero patch backupstoragelocation default \
--type merge \
--patch '{"spec":{"accessMode":"ReadOnly"}}'
# 잠시 후 ReadWrite로 복귀
kubectl -n velero patch backupstoragelocation default \
--type merge \
--patch '{"spec":{"accessMode":"ReadWrite"}}'
# 백업 목록 확인
velero backup get
# [타겟 클러스터] 복원 수행
velero restore create migration-restore \
--from-backup migration-app-v2 \
--namespace-mappings app-v2:app-production \
--wait
# 복원 결과 확인
velero restore describe migration-restore --details
kubectl get pods -n app-production
네임스페이스 매핑과 리소스 필터링
마이그레이션 시 네임스페이스 이름 변경이나 특정 리소스 제외가 필요한 경우가 많습니다.
# 네임스페이스 이름 변경 복원
velero restore create --from-backup my-backup \
--namespace-mappings old-namespace:new-namespace
# 특정 리소스 유형만 복원
velero restore create --from-backup my-backup \
--include-resources deployments,services,configmaps,secrets
# 특정 리소스 유형 제외 복원
velero restore create --from-backup my-backup \
--exclude-resources storageclasses,persistentvolumes
# 레이블 셀렉터로 특정 리소스만 복원
velero restore create --from-backup my-backup \
--selector app=frontend
멀티 리전 DR 전략
멀티 BSL 구성
프로덕션 환경에서는 단일 오브젝트 스토리지에 의존하지 않고, 복수의 BSL을 구성하여 지리적 이중화를 확보해야 합니다.
# Primary BSL - 서울 리전
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: primary-seoul
namespace: velero
spec:
provider: aws
objectStorage:
bucket: velero-backup-ap-northeast-2
prefix: cluster-prod
config:
region: ap-northeast-2
accessMode: ReadWrite
default: true
---
# Secondary BSL - 도쿄 리전 (DR용)
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: secondary-tokyo
namespace: velero
spec:
provider: aws
objectStorage:
bucket: velero-backup-ap-northeast-1
prefix: cluster-prod-dr
config:
region: ap-northeast-1
accessMode: ReadWrite
credential:
name: velero-dr-credentials
key: cloud
# 두 BSL 모두에 백업 생성
velero backup create dr-backup-$(date +%Y%m%d) \
--include-namespaces production \
--snapshot-volumes \
--snapshot-move-data \
--storage-location primary-seoul
# DR 사이트에도 복제 백업
velero backup create dr-backup-$(date +%Y%m%d)-replica \
--include-namespaces production \
--snapshot-move-data \
--storage-location secondary-tokyo
S3 Cross-Region Replication 활용
BSL을 이중화하는 대신 S3 Cross-Region Replication(CRR)을 활용하면 별도 백업 명령 없이도 자동으로 백업 데이터가 다른 리전에 복제됩니다. 이 방식은 운영 오버헤드가 적지만, S3 CRR 비용이 추가로 발생합니다. DR 클러스터에서는 복제된 버킷을 BSL로 지정하여 ReadOnly 모드로 접근합니다.
DR 시나리오별 복구 절차
시나리오 1: 단일 네임스페이스 삭제 복구
# 실수로 삭제된 네임스페이스 확인
kubectl get ns production
# Error from server (NotFound): namespaces "production" not found
# 최신 백업 확인
velero backup get --selector backup-tier=tier1 | head -5
# 네임스페이스 복원
velero restore create ns-recovery-$(date +%s) \
--from-backup tier1-hourly-backup-20260308020000 \
--include-namespaces production \
--wait
# 복원 상태 확인
velero restore describe ns-recovery-$(date +%s) --details
시나리오 2: 클러스터 전체 DR (리전 장애)
- DR 리전에 새 Kubernetes 클러스터 프로비저닝
- Velero 설치 (DR BSL 지정)
- 가장 최근 백업으로부터 전체 복원 수행
- DNS 전환 및 서비스 검증
시나리오 3: 특정 리소스 롤백 (잘못된 배포 복구)
# 잘못된 Deployment만 이전 상태로 복원
velero restore create deployment-rollback \
--from-backup daily-backup-20260307 \
--include-namespaces production \
--include-resources deployments \
--selector app=api-server \
--existing-resource-policy update \
--wait
--existing-resource-policy update 옵션은 복원 시 이미 존재하는 리소스를 백업 시점의 상태로 덮어씁니다. 기본값은 none으로, 기존 리소스가 있으면 건너뜁니다.
백업 도구 비교: Velero vs Kasten K10 vs etcd 백업
Kubernetes 백업 솔루션을 선택할 때 세 가지 접근법의 특성을 이해하는 것이 중요합니다.
| 구분 | Velero | Kasten K10 | etcd 네이티브 백업 |
|---|---|---|---|
| 라이선스 | 오픈소스 (Apache 2.0) | 상용 (무료 5노드 제한) | 오픈소스 |
| 백업 범위 | 네임스페이스/리소스 단위 | 애플리케이션 단위 | 클러스터 전체 (etcd 데이터) |
| UI | CLI 중심 | 웹 대시보드 내장 | CLI (etcdctl) |
| PV 백업 | CSI 스냅샷 + FSB | CSI 스냅샷 + Kanister | 미지원 (별도 구현 필요) |
| 멀티 클러스터 | 공유 BSL로 수동 관리 | 중앙 콘솔로 통합 관리 | 클러스터별 독립 |
| 암호화 | 단일 키 기반 | 봉투 암호화 (마스터 키 + DEK) | 미지원 |
| 복원 세밀도 | 네임스페이스/리소스/레이블 | 애플리케이션/컴포넌트 | 전체 복원만 가능 |
| DB 일관성 백업 | 훅(Hook)으로 구현 | 내장 블루프린트 제공 | etcd만 일관성 보장 |
| 적합한 환경 | 중소규모, 비용 민감 | 대규모 엔터프라이즈 | 컨트롤 플레인 DR |
| 학습 곡선 | 중간 | 낮음 (UI 제공) | 높음 |
선택 가이드:
- etcd 백업: 컨트롤 플레인 DR에는 필수이지만, 애플리케이션 데이터(PV)는 보호하지 못합니다. Velero나 Kasten과 병행하여 사용해야 합니다.
- Velero: 비용 효율적이고 유연합니다. 커뮤니티가 활발하며, CSI 스냅샷과 FSB를 모두 지원하여 대부분의 시나리오를 커버합니다. 멀티 클러스터 관리는 수동으로 해야 합니다.
- Kasten K10: 대규모 엔터프라이즈에서 중앙 관리와 규정 준수(Compliance)가 필요한 경우에 적합합니다. 웹 UI, 중앙 콘솔, 데이터 암호화, 불변성(Immutability) 등의 기능이 내장되어 있으나 라이선스 비용이 높습니다.
백업 전/후 훅(Hook) 활용
데이터베이스처럼 실행 중 파일 시스템 일관성이 보장되지 않는 워크로드는 백업 전에 쿼리 정지(quiesce) 작업이 필요합니다. Velero의 Pre/Post Hook을 활용하면 이를 자동화할 수 있습니다.
apiVersion: velero.io/v1
kind: Backup
metadata:
name: db-consistent-backup
namespace: velero
spec:
includedNamespaces:
- database
snapshotVolumes: true
hooks:
resources:
- name: postgresql-hook
includedNamespaces:
- database
labelSelector:
matchLabels:
app: postgresql
pre:
- exec:
container: postgresql
command:
- /bin/bash
- -c
- 'pg_dump -U postgres -d myapp > /var/lib/postgresql/backup/pre_backup.sql && sync'
onError: Fail
timeout: 120s
post:
- exec:
container: postgresql
command:
- /bin/bash
- -c
- 'rm -f /var/lib/postgresql/backup/pre_backup.sql'
onError: Continue
timeout: 30s
Pre Hook에서 onError를 Fail로 설정하면 훅 실행이 실패할 경우 백업 자체가 중단됩니다. 이렇게 하면 일관성이 보장되지 않는 백업이 생성되는 것을 방지할 수 있습니다.
모니터링과 알림 체계
Prometheus 메트릭 수집
Velero는 기본적으로 Prometheus 메트릭을 노출합니다. ServiceMonitor를 구성하여 백업/복원 상태를 모니터링할 수 있습니다.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: velero
namespace: velero
labels:
app.kubernetes.io/name: velero
spec:
selector:
matchLabels:
app.kubernetes.io/name: velero
namespaceSelector:
matchNames:
- velero
endpoints:
- port: monitoring
interval: 30s
핵심 모니터링 메트릭
- velero_backup_success_total: 성공한 백업 수
- velero_backup_failure_total: 실패한 백업 수
- velero_backup_partial_failure_total: 부분 실패한 백업 수
- velero_backup_duration_seconds: 백업 소요 시간
- velero_restore_success_total: 성공한 복원 수
- velero_backup_items_total: 백업된 리소스 항목 수
Alertmanager 알림 룰 예시
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: velero-alerts
namespace: velero
spec:
groups:
- name: velero.rules
rules:
- alert: VeleroBackupFailure
expr: increase(velero_backup_failure_total[1h]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: 'Velero 백업 실패 감지'
description: '최근 1시간 내 Velero 백업이 실패했습니다. 즉시 확인이 필요합니다.'
- alert: VeleroBackupNotRunning
expr: time() - velero_backup_last_successful_timestamp{schedule!=""} > 86400
for: 10m
labels:
severity: warning
annotations:
summary: 'Velero 스케줄 백업이 24시간 이상 실행되지 않음'
description: '스케줄 {{ $labels.schedule }}의 마지막 성공 백업이 24시간을 초과했습니다.'
- alert: VeleroBackupPartialFailure
expr: increase(velero_backup_partial_failure_total[6h]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: 'Velero 백업 부분 실패 감지'
description: '일부 리소스가 백업에 포함되지 않았습니다. 볼륨 스냅샷 또는 훅 실행 상태를 점검하십시오.'
트러블슈팅 가이드
장애 사례 1: 백업 상태 PartiallyFailed
증상: 백업은 완료되지만 상태가 PartiallyFailed로 표시됩니다.
# 상세 원인 확인
velero backup describe my-backup --details
# 로그에서 구체적 오류 확인
velero backup logs my-backup | grep -i "error\|warning"
주요 원인과 해결:
- VolumeSnapshotLocation 미구성: CSI 스냅샷을 사용하는데 VSL이 올바르게 설정되지 않은 경우 발생합니다. velero snapshot-location get으로 VSL 상태를 확인하고, 클라우드 프로바이더에 맞는 VSL을 생성합니다.
- Node Agent 타임아웃: 대용량 볼륨의 FSB가 기본 타임아웃(240분)을 초과할 때 발생합니다. Node Agent Pod의 리소스를 증가시키거나, --fs-backup-timeout 값을 늘립니다.
- Pod Volume 마운트 오류: Pod가 Running 상태가 아닌 경우 볼륨 백업을 할 수 없습니다. CrashLoopBackOff 상태의 Pod를 먼저 해결해야 합니다.
장애 사례 2: 복원 후 PVC Pending 상태
증상: 복원은 완료되었지만 PVC가 Pending 상태에서 진행되지 않습니다.
원인: StorageClass가 타겟 클러스터에 존재하지 않거나 이름이 다른 경우 발생합니다.
# 복원된 PVC 상태 확인
kubectl get pvc -n restored-namespace
# StorageClass 확인
kubectl get sc
# ConfigMap으로 StorageClass 매핑
kubectl -n velero create configmap change-storage-class-config \
--from-literal=old-storage-class=new-storage-class
# 매핑을 적용한 복원
velero restore create --from-backup my-backup \
--include-namespaces production
Velero는 velero 네임스페이스에 change-storage-class-config라는 ConfigMap이 있으면 자동으로 StorageClass 이름을 매핑합니다.
장애 사례 3: BSL 접근 불가
증상: Velero가 오브젝트 스토리지에 접근하지 못해 백업이 생성되지 않습니다.
# BSL 상태 확인
velero backup-location get
# NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED
# default aws velero-backup-prod/ Unavailable 2026-03-08 00:00:00
# 자격 증명 확인
kubectl -n velero get secret cloud-credentials -o jsonpath='{.data.cloud}' | base64 -d
# BSL 접근 수동 테스트
kubectl -n velero exec deploy/velero -- \
aws s3 ls s3://velero-backup-prod/ --region ap-northeast-2
해결: IAM 자격 증명 만료, 버킷 정책 변경, 네트워크 정책에 의한 아웃바운드 차단 등이 원인일 수 있습니다. IRSA(IAM Roles for Service Accounts)를 사용하면 자격 증명 만료 문제를 근본적으로 해결할 수 있습니다.
장애 사례 4: 버전 불일치 오류
증상: Velero CLI와 서버 버전이 일치하지 않아 명령 실행이 실패합니다.
# 버전 확인
velero version
# Client:
# Version: v1.15.0
# Server:
# Version: v1.14.1
# 서버와 동일한 CLI 버전으로 재설치하거나 서버를 업그레이드합니다.
클라이언트와 서버의 메이저/마이너 버전은 반드시 일치해야 합니다. 패치 버전 차이는 대부분 호환되지만, 공식적으로 동일 버전 사용이 권장됩니다.
운영 주의사항과 모범 사례
반드시 지켜야 할 원칙
정기적인 복원 테스트: 백업이 존재한다는 것과 복원이 된다는 것은 별개의 문제입니다. 최소 월 1회, 테스트 네임스페이스에 실제 복원을 수행하여 백업의 유효성을 검증해야 합니다.
BSL 암호화 활성화: 백업 데이터에는 Secret, ConfigMap 등 민감한 정보가 포함됩니다. 오브젝트 스토리지의 서버 사이드 암호화(SSE)를 반드시 활성화하십시오.
RBAC 최소 권한 적용: Velero ServiceAccount에 과도한 권한을 부여하지 않습니다. 백업 대상 네임스페이스에 대한 읽기 권한과 velero 네임스페이스에 대한 쓰기 권한만 부여합니다.
백업 불변성(Immutability): S3 Object Lock이나 동등한 기능을 활용하여 백업 데이터의 변조 및 삭제를 방지합니다. 랜섬웨어 공격에 대한 방어에 필수적입니다.
Node Agent 리소스 할당: 기본 리소스 설정으로는 대용량 볼륨 백업 시 OOM Kill이 발생할 수 있습니다. 프로덕션에서는 Node Agent의 메모리 limit을 최소 2Gi 이상으로 설정하십시오.
피해야 할 실수
- 단일 BSL 의존: 오브젝트 스토리지 자체에 장애가 발생하면 백업과 복원 모두 불가능합니다. 반드시 이중화 BSL 또는 CRR을 구성합니다.
- TTL 미설정: 보존 기간을 설정하지 않으면 기본 30일이 적용됩니다. 워크로드 중요도에 따라 명시적으로 TTL을 설정해야 합니다.
- 전체 클러스터 백업 남용: 모든 네임스페이스를 하나의 백업에 포함하면 백업 시간이 길어지고 복원 시 불필요한 리소스까지 복원됩니다. 네임스페이스 또는 워크로드 단위로 분리하는 것이 효율적입니다.
- CRD 백업 누락: Custom Resource Definition을 백업에서 제외하면, 해당 CRD에 의존하는 CR(Custom Resource)이 복원 시 생성되지 않습니다.
- 백업 모니터링 미구성: 백업 실패가 감지되지 않으면 DR 상황에서 사용할 수 있는 유효한 백업이 없을 수 있습니다.
DR 복구 훈련 체크리스트
실제 장애 상황에서 당황하지 않으려면 정기적인 DR 복구 훈련이 필수입니다. 아래 체크리스트를 활용하여 분기별 훈련을 수행하십시오.
사전 준비 단계:
- DR 대상 클러스터 및 네임스페이스 목록 확정
- 최신 백업 존재 및 Completed 상태 확인
- DR 사이트 클러스터 가용성 확인
- Velero 서버/클라이언트 버전 일치 확인
- BSL 접근 가능 여부 확인
복원 수행 단계:
- 테스트 네임스페이스 또는 DR 클러스터에 복원 실행
- 복원 상태 Completed 확인 (PartiallyFailed 여부 점검)
- 핵심 Deployment/StatefulSet의 Pod Running 상태 확인
- PVC Bound 상태 및 데이터 무결성 검증
- Service/Ingress 엔드포인트 접근 가능 확인
- 애플리케이션 레벨 Health Check 수행
- 데이터베이스 연결 및 데이터 정합성 검증
사후 검토 단계:
- 복원 소요 시간 기록 (RTO 충족 여부 평가)
- 데이터 손실 범위 측정 (RPO 충족 여부 평가)
- 발견된 문제점 및 개선 사항 문서화
- 백업 스케줄 또는 TTL 조정 필요 여부 검토
- 다음 훈련 일정 확정
마치며
Kubernetes 클러스터의 백업과 복구는 선택이 아닌 필수입니다. "우리 클러스터는 괜찮을 것"이라는 생각은 실제 장애가 발생하는 순간 무너집니다. Velero는 오픈소스임에도 불구하고 CSI 스냅샷, 파일 시스템 백업, 크로스 클러스터 마이그레이션, 스케줄 기반 자동 백업 등 엔터프라이즈 수준의 기능을 제공합니다.
이 글에서 다룬 핵심 사항을 요약하면 다음과 같습니다. 워크로드 중요도에 따라 Tier를 나누고 각 Tier에 맞는 RPO/RTO를 설계하십시오. CSI 스냅샷과 Data Mover를 활용하면 크로스 리전 DR이 가능합니다. 백업이 있다고 안심하지 말고, 정기적으로 복원 테스트를 수행하여 백업의 유효성을 검증하십시오. 모니터링과 알림을 구성하여 백업 실패를 즉시 감지하고 대응할 수 있어야 합니다.
Velero 하나만으로 모든 DR 시나리오를 커버할 수는 없습니다. etcd 네이티브 백업으로 컨트롤 플레인을 보호하고, Velero로 애플리케이션과 데이터를 보호하며, 필요에 따라 Kasten K10과 같은 엔터프라이즈 솔루션을 병행하는 것이 가장 견고한 전략입니다.
참고자료
- Velero 공식 문서 - How Velero Works
- Velero 공식 문서 - Cluster Migration
- Velero 공식 문서 - CSI Support
- Velero 공식 문서 - File System Backup
- Velero 공식 문서 - Troubleshooting
- Velero GitHub Repository
- Kubernetes 공식 문서 - CSI Volume Snapshots
- Broadcom Knowledge Base - Velero Backup Failed or PartiallyFailed
- Veeam Kasten for Kubernetes
- Kubernetes 공식 문서 - Operating etcd clusters