Velero를 이용한 EKS 클러스터 Cross-Account 백업 및 복구 가이드

Jerry·2025년 8월 14일
0

EKS 작업 내역

목록 보기
3/3

Why

회사 서비스가 종료되어 EKS 클러스터를 삭제해야 하는데 그전에 혹시 모를 복구 작업이 필요할까 싶어 기존 클러스터를 백업하고 싶었다. 물론 쿠버네티스는 이미 설정 파일을 깃으로 보관하니 VM과 다르게 굳이 백업이 필요한가 싶다. 헬름으로 애플리케이션을 배포하면 헬름 파일만 있으면 간단하게 어디서나 설치할 수 있다.

하지만 깃으로 저장되지 않은 수동 리소스가 있을 수 있고 Velero 등 전용 백업 도구를 사용하면 백업 및 복구 작업이 간단한 명령어로 가능하니 좀 더 수월하다. 그리고 PV까지 백업이 가능하다고 한다. (이건 테스트 해 보지는 않았다.)

그래서 이번에 Velero를 설치, 테스트 했는데, 잘되어 정리할 겸 공유한다.

사실은 이전에 Velero와 유사한 Kasten 이라는 솔루션을 판매한 적이 있는데, 그때도 많이 들었던 질문이었다. 쿠버네티스 환경에 백업 솔루션이 왜 필요하냐고. 그때는 쉽게 공감이 안 갔는데, 이제는 이해가 된다. 서비스 종료라는 특별한 경험을 하니 필요성이 명확해졌다.

Velero는 오픈소스로 도구로 현재는 VMware에 인수되었다.

Velero 구성

서비스 종료로 특정 AWS 계정을 삭제할 예정이다. 따라서 해당 EKS 클러스터를 다른 계정으로 백업해야 한다. Source 계정의 클러스터 설정을 Target 계정의 S3로 백업하고 Target 계정에서 해당 S3를 이용해서 복원한다.

Velero 설치

s3 버킷을 서로 다른 계정에서 공유하니 Cross-Account 설정이 까다롭다.

설치 관련 참조 - https://github.com/vmware-tanzu/velero-plugin-for-aws#setup

Process

1. 필요한 도구 설치

# Velero CLI 설치 (macOS)
brew install velero

2. IAM Policy, Role, IRSA 설정

  • 양쪽 계정에서 모두 설정해야 한다.
  • 서로 다른 계정 간 s3 버킷 공유을 위한 설정이 필요하다.

S3 버킷 공유 설정을 위한 IAM Policy를 생성한다.

${BUCKET}, ${ACCOUNT_ID}, ${PROFILE} 등의 변수는 각자 환경에 맞게 설정한다.

cat > velero-policy.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeVolumes",
                "ec2:DescribeSnapshots",
                "ec2:CreateTags",
                "ec2:CreateVolume",
                "ec2:CreateSnapshot",
                "ec2:DeleteSnapshot"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObject",
                "s3:PutObjectTagging",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}"
            ]
        }
    ]
}
EOF

aws iam create-policy \
    --policy-name VeleroBackupPolicy \
    --policy-document "file://${POLICY_FILE}" \
    --profile $PROFILE

IAM Role을 생성하고 IRSA 연결을 위한 OIDC Provider ID, Service Account velero를 연결한다. Velero 설치 시 기본 네임스페이스 velero, Service Account velero 이다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/${OIDC_PROVIDER_ID}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.ap-northeast-2.amazonaws.com/id/${OIDC_PROVIDER_ID}:sub": "system:serviceaccount:velero:velero",
          "oidc.eks.ap-northeast-2.amazonaws.com/id/${OIDC_PROVIDER_ID}:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}

aws iam create-role \
    --role-name VeleroBackupRole \
    --assume-role-policy-document "file://${ROLE_FILE}" \
    --profile $PROFILE

aws iam attach-role-policy \
    --role-name VeleroBackupRole \
    --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/VeleroBackupPolicy \
    --profile $PROFILE

3. S3 버킷 생성

버킷은 타켓 어카운트에 저장한다. 여러 개의 소스 어카운트의 백업을 하나의 타겟 어카운트에서 관리하니 버킷 이름을 소스 어카운트 이름으로 저장하였다.

# S3 버킷 생성
BUCKET=velero-backup-source-cluster
REGION=ap-northeast-2
PROFILE=target-cluster

aws s3api create-bucket --profile $PROFILE \
    --bucket $BUCKET \
    --region $REGION \
    --create-bucket-configuration LocationConstraint=$REGION

# 버킷 버전 관리 활성화
aws s3api put-bucket-versioning \
  --bucket $BUCKET \
  --versioning-configuration Status=Enabled \
  --profile $PROFILE

버킷 정책에 Source, Target 계정 모두 접근 가능하도록 설정한다.

# 크로스 계정 버킷 정책 생성
cat > cross-account-bucket-policy.json << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VeleroBackupAccessSourceCluster",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::${SOURCE_ACCOUNT_ID}:role/VeleroBackupRole"
            },
            "Action": [
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}",
                "arn:aws:s3:::${BUCKET}/*"
            ]
        },
        {
            "Sid": "VeleroBackupAccessTargetCluster",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::${TARGET_ACCOUNT_ID}:role/VeleroBackupRole"
            },
            "Action": [
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}",
                "arn:aws:s3:::${BUCKET}/*"
            ]
        }
    ]
}
EOF

# 버킷 정책 적용
aws s3api put-bucket-policy \
    --bucket $BUCKET \
    --policy file://cross-account-bucket-policy.json \
    --profile $PROFILE

4. Velero 설치

Velero 설치를 Helm으로 진행하면 에러가 발생하여 Velero CLI로 설치하였다.

velero install \
    --provider aws \
    --plugins velero/velero-plugin-for-aws:v1.10.0 \
    --bucket $BUCKET \
    --backup-location-config region=$REGION \
    --snapshot-location-config region=$REGION \
    --no-secret

설치하고 Service Account를 설정을 IRSA 연결을 위하여 변경한다.
헬름으로 설치하면 자동으로 변경 옵션이 있는데, CLI에서는 아래와 같이 수동으로 변경해야 하는 것 같다.

k edit sa velero
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::{ACCOUNT_ID}:role/VeleroBackupRole

설치를 완료하면 아래와 같이 Velero backup storage location CRD를 확인할 수 있다.

k get backupstoragelocations.velero.io
NAME      PHASE       LAST VALIDATED   AGE     DEFAULT
default   Available   25s              5m57s   true

만약 설치에 문제가 발생하면 위 backupstoragelocations 명령어 결과에서 PHASE가 Unavailable로 표시된다. 그러면 IAM Policy, Role 등 다시 확인해야 한다. 나도 이 문제 때문에 2일 정도 고생했다.

그리고 stern(또는 k logs) 명령어로 파드 로그도 정상인지 확인해야 한다.

k stern velero
velero-85b787698d-kqdcn velero time="2025-08-12T05:58:41Z" level=info msg="BackupStorageLocations is valid, marking as available" backup-storage-location=velero/default controller=backup-storage-location logSource="pkg/controller/backup_storage_location_controller.go:128"

백업 및 복구 테스트

백업은 매우 편리하다.

velero backup create backup-$(date +%Y%m%d-%H%M%S) --include-namespaces baas --ttl 876000h

cron 스케쥴 설정한 정기 백업이 아니라 위와 같이 클러스터 마이그레이션 용도처럼 영구히 백업하면 ttl 설정을 876000h(100년)으로 설정한다. 기본 설정은 30일이라 30일 후에 자동으로 삭제된다.

다음으로 복구 프로세스.

먼저 백업 데이터를 확인한다. 다른 계정에서 백업한거라 백업 데이터를 먼저 확인한다.

velero backup get
NAME                          STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION    SELECTOR
prod-backup-20250814-143657   Completed   0        0          2025-08-14 14:36:59 +0900 KST   29d       prod-backup   <none>

아래와 같이 복구 명령어도 백업처럼 간단하다.

velero restore create restore-$(date +%Y%m%d-%H%M%S) --from-backup prod-backup-20250814-143657 --namespace-mappings main:main
Restore request "restore-20250814-145320" submitted successfully.
Run `velero restore describe restore-20250814-145320` or `velero restore logs restore-20250814-145320` for more details.

describe 명령어를 사용하면 상세하게 복구 상태를 확인할 수 있다.

velero restore describe <복구이름>

에러 메시지

            error restoring targetgroupbindings.elbv2.k8s.aws

타겟그룹 관련 에러를 확인할 수 있는데, 서로 다른 계정에서 타겟그룹을 만드는 거라 무시해도 된다. 나중에 ALB 생성하면 자동으로 해결된다.

k get-all -n

get-all 명령어로 확인하면 configmap, secret, service, deployment, pod 등 모든 리소스가 정상으로 복구되는 것을 확인할 수 있다.

이처럼 수월하게 백업, 복구가 가능하다.

Velero는 쿠버네티스 환경에서 강력한 백업/복구 도구다. 특히 계정 간 마이그레이션 시 유용하다. IAM 및 S3 정책 설정이 다소 복잡하지만, 그래도 차근차근 하다보면 해결할 수 있다.

profile
도서 <24단계 실습으로 정복하는 쿠버네티스> 저자. 쿠버네티스/EKS 관련 문의 erdia22@gmail.com.

0개의 댓글