Skip to content
Published on

Kubernetes Velero 백업·복구 완전 가이드: 클러스터 DR부터 멀티 리전 마이그레이션까지

Authors
  • Name
    Twitter
Kubernetes Velero Backup

들어가며

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가 백업을 수행하는 순서는 다음과 같습니다.

  1. 사용자가 Backup CR을 생성하면 Velero 컨트롤러가 감지합니다.
  2. Kubernetes API를 통해 대상 리소스(Deployment, Service, ConfigMap, Secret, CRD 등)를 조회하고 JSON으로 직렬화합니다.
  3. 직렬화된 리소스를 tarball로 압축하여 BSL(오브젝트 스토리지)에 업로드합니다.
  4. PV가 포함된 경우 선택된 방식(CSI 스냅샷 또는 FSB)으로 볼륨 데이터를 백업합니다.
  5. 백업 메타데이터와 로그를 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(오브젝트 스토리지)을 공유하는 것입니다. 소스 클러스터에서 생성한 백업을 타겟 클러스터가 접근하여 복원할 수 있습니다.

마이그레이션 흐름:

  1. 소스 클러스터에서 마이그레이션 대상 네임스페이스 백업 생성
  2. 타겟 클러스터에 Velero 설치 (동일 BSL 구성)
  3. 타겟 클러스터에서 BSL 동기화 후 백업 목록 확인
  4. 선택한 백업으로부터 복원 수행
  5. 복원된 리소스 검증 및 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 (리전 장애)

  1. DR 리전에 새 Kubernetes 클러스터 프로비저닝
  2. Velero 설치 (DR BSL 지정)
  3. 가장 최근 백업으로부터 전체 복원 수행
  4. 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 백업 솔루션을 선택할 때 세 가지 접근법의 특성을 이해하는 것이 중요합니다.

구분VeleroKasten K10etcd 네이티브 백업
라이선스오픈소스 (Apache 2.0)상용 (무료 5노드 제한)오픈소스
백업 범위네임스페이스/리소스 단위애플리케이션 단위클러스터 전체 (etcd 데이터)
UICLI 중심웹 대시보드 내장CLI (etcdctl)
PV 백업CSI 스냅샷 + FSBCSI 스냅샷 + 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. 정기적인 복원 테스트: 백업이 존재한다는 것과 복원이 된다는 것은 별개의 문제입니다. 최소 월 1회, 테스트 네임스페이스에 실제 복원을 수행하여 백업의 유효성을 검증해야 합니다.

  2. BSL 암호화 활성화: 백업 데이터에는 Secret, ConfigMap 등 민감한 정보가 포함됩니다. 오브젝트 스토리지의 서버 사이드 암호화(SSE)를 반드시 활성화하십시오.

  3. RBAC 최소 권한 적용: Velero ServiceAccount에 과도한 권한을 부여하지 않습니다. 백업 대상 네임스페이스에 대한 읽기 권한과 velero 네임스페이스에 대한 쓰기 권한만 부여합니다.

  4. 백업 불변성(Immutability): S3 Object Lock이나 동등한 기능을 활용하여 백업 데이터의 변조 및 삭제를 방지합니다. 랜섬웨어 공격에 대한 방어에 필수적입니다.

  5. 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과 같은 엔터프라이즈 솔루션을 병행하는 것이 가장 견고한 전략입니다.

참고자료

  1. Velero 공식 문서 - How Velero Works
  2. Velero 공식 문서 - Cluster Migration
  3. Velero 공식 문서 - CSI Support
  4. Velero 공식 문서 - File System Backup
  5. Velero 공식 문서 - Troubleshooting
  6. Velero GitHub Repository
  7. Kubernetes 공식 문서 - CSI Volume Snapshots
  8. Broadcom Knowledge Base - Velero Backup Failed or PartiallyFailed
  9. Veeam Kasten for Kubernetes
  10. Kubernetes 공식 문서 - Operating etcd clusters