[1.짧게 말해서]
1.Velero란?
Velero란 Kubernetes 클러스터의 백업 및 복구, 마이그레이션을 위한 오픈소스 도구이다. Velero를 사용하면 클러스터의 상태를 스냅샷으로 저장하고, 필요할 때 이를 복구하거나 다른 클러스터로 마이그레이션 가능하다.Velero는 클러스터의 리소스 단위 백업이 가능하고 PV 백업이 가능하다.
[2. 조금 더 자세하게]
1. 동작원리
- The Velero client makes a call to the Kubernetes API server to create a Backup object.
- The BackupController notices the new Backup object and performs validation.
- The BackupController begins the backup process. It collects the data to back up by querying the API server for resources.
- The BackupController makes a call to the object storage service – for example, AWS S3 – to upload the backup file.
공식 문서에 나온 설명이다.
차례대로 보면 다음과 같다.
1. Velero 클라이언트가 Kubernetes API 서버에 Backup 객체 생성 요청:
사용자가 velero backup create test-backup 명령어를 실행하면, Velero 클라이언트는 Kubernetes API 서버에 Backup 객체를 생성하라는 요청을 보낸다.
이 Backup 객체는 백업 작업에 대한 정보를 포함하고 있다.(백업 객체 이름, 세부설정, 백업시간, 성공여부 등)
-> 백업객체는 백업작업의 진행상황에 따라 변화함. (EX) 백업 객체가 처음 생성되면, status 필드는 비어 있거나 기본값으로 설정되어있음)
2. BackupController가 새로운 Backup 객체를 감지하고 검증 수행:
Kubernetes 클러스터 내에서 실행 중인 BackupController는 새로운 Backup 객체가 생성된 것을 감지한다.
BackupController는 이 객체에 대한 검증을 수행하여 백업 작업이 올바르게 설정되었는지 확인한다.
3. BackupController가 백업 프로세스를 시작:
검증이 완료되면, BackupController는 백업 프로세스를 시작한다. 이 과정에서 BackupController는 Kubernetes API 서버에 쿼리를 보내어 백업할 리소스 데이터를 수집한다.
4. BackupController가 오브젝트 스토리지 서비스에 백업 파일 업로드 요청:
수집된 데이터는 tarball 형식으로 압축되어 백업 파일로 생성된다.
BackupController는 오브젝트 스토리지 서비스(예: AWS S3)에 이 백업 파일을 업로드한다.
(AWS 사용 시, 어떤 s3에 백업할지 설정)
PV 디스크 스냅샷 생성:
기본적으로 velero backup create 명령어는 퍼시스턴트 볼륨(Persistent Volume, PV)의 디스크 스냅샷을 생성한다.
이 스냅샷은 퍼시스턴트 볼륨의 현재 상태를 캡처하여 나중에 복구할 수 있도록 한다.
스냅샷 생성 동작은 추가 플래그를 지정하여 조정할 수 있다. 예를 들어, --snapshot-volumes=false 옵션을 사용하면 스냅샷 생성을 비활성화 가능하다.
참고
Velero를 설치하면 다음과 같은 주요 컴포넌트가 함께 설치된다.
- Velero 서버: Kubernetes 클러스터 내에서 실행되며, 백업 및 복구 작업을 관리
- BackupController: 새로운 Backup 객체를 감지하고, 백업 작업을 수행
- RestoreController: 새로운 Restore 객체를 감지하고, 복구 작업을 수행
- ScheduleController: 백업 스케줄을 관리하고, 정해진 일정에 따라 백업 작업을 실행
2. 백업 방식
백업 종류라고 하기에는 거창하지만, Velero는 다음 두 가지 백업방식을 지원한다.
- On-Demand Backup
- Scheduled Backup
On-Demand Backup은 말그대로 사용자가 필요할 때마다 수동으로 실행하는 백업이다.
명령어를 통해 즉시 백업을 시작한다.
EX) velero backup create my-backup --include-namespaces my-namespace
Scheduled Backup은 정해진 일정에 따라 자동으로 실행되는 백업이다.
사용자가 미리 정의한 일정에 따라 주기적으로 클러스터 또는 특정 리소스를 백업한다.
EX)velero schedule create my-scheduled-backup --schedule="0 2 * * *" --include-namespaces my-namespace
이 명령어는 매일 새벽 2시에 my-namespace 네임스페이스의 백업을 생성한다.
3. Hooks
Velero는 Hooks라는 기능을 지원한다. Hook을 이용하면 백업 또는 복원 작업 전후에 특정 명령어를 실행할 수 있도록 설정 가능하다. 이를 통해, 백업 및 복원 작업의 일관성을 유지하고 필요한 추가작업을 수행할 수 있다.
Hook은 크게 두가지로 나뉠 수 있다.
- Backup Hooks
- Restore Hooks
Backup Hooks는 백업 작업 전후에 실행되는 hook이며, Restore Hooks는 복원 작업중에 실행 되는 hook이다.
3-1. Backup Hooks
backup hooks는 백업 전에 실행되는 Pre Hooks와 백업작업이 완료되고 실행되는 Post Hooks로 나뉜다.
hook을 사용하는 방법은 크게 두가지가 있는데, 일단 Pod Annotation을 이용해 사용하는 방법 먼저 설명하겠다.
Pod에 다음과 같은 주석을 설정하여 Velero 백업 전후로 작업 설정이 가능하다.
Pre Hooks
- pre.hook.backup.velero.io/container:
명령어를 실행할 컨테이너를 지정한다.. 기본값은 Pod의 첫 번째 컨테이너이며. Optional이다. - pre.hook.backup.velero.io/command:
실행할 명령어를 지정. 기본적으로 이 명령어는 셸 내에서 실행되지 않는다. 셸이 필요한 경우, 명령어의 시작 부분에 /bin/sh와 같은 셸 명령어를 포함해야 한다. 여러 인수가 필요한 경우, 명령어를 JSON 배열로 지정할 수 있다. 예: ["/usr/bin/uname", "-a"]. Optional - pre.hook.backup.velero.io/on-error:
명령어가 0이 아닌 종료 코드를 반환할 경우의 동작을 지정. 기본값은 Fail. 유효한 값은 Fail과 Continue. Optional - pre.hook.backup.velero.io/timeout:
명령어 실행을 기다리는 시간을 지정. 명령어가 타임아웃을 초과하면 오류로 간주. 기본값은 30초. Optional
Post Hooks
- post.hook.backup.velero.io/container:
명령어를 실행할 컨테이너를 지정. 기본값은 Pod의 첫 번째 컨테이너. - post.hook.backup.velero.io/command:
실행할 명령어를 지정. 기본적으로 이 명령어는 셸 내에서 실행되지 않는다. 셸이 필요한 경우, 명령어의 시작 부분에 /bin/sh와 같은 셸 명령어를 포함해야 한다. 여러 인수가 필요한 경우, 명령어를 JSON 배열로 지정할 수 있다. 예: ["/usr/bin/uname", "-a"]. . - post.hook.backup.velero.io/on-error:
명령어가 0이 아닌 종료 코드를 반환할 경우의 동작을 지정. 기본값은 Fail. 유효한 값은 Fail과 Continue. - post.hook.backup.velero.io/timeout:
명령어 실행을 기다리는 시간을 지정. 명령어가 타임아웃을 초과하면 오류로 간주. 기본값은 30초.
복원하려는 Pod에 위 Annotation을 이용해서 백업 전 후 작업을 설정할 수 있다.
백업 대상인 nginx pod에 annotaiton을 이용해서 fsfreeze 명령어를 실행하여 해당 파일시스템을 프리징하고 백업이 완료된 후 프리징을 해제하는 예시이다.
kubectl annotate pod -n nginx-example -l app=nginx \
pre.hook.backup.velero.io/command='["/sbin/fsfreeze", "--freeze", "/var/log/nginx"]' \
pre.hook.backup.velero.io/container=fsfreeze \
post.hook.backup.velero.io/command='["/sbin/fsfreeze", "--unfreeze", "/var/log/nginx"]' \
post.hook.backup.velero.io/container=fsfreeze
##백업생성
velero backup create nginx-hook-test
##백업이 제대로 생성되었는지 확인
velero backup get nginx-hook-test
##Pre hook 또는 Post hook 동작 확인
velero backup logs nginx-hook-test | grep hookCommand
Annotation 이외에도, Backup 오브젝트의 API를 이용하는 방법도 있다. 직관적이니, 예시하나를 들면서 마무리 하겠다.
apiVersion: velero.io/v1
kind: Backup
metadata:
name: my-backup ##백업 오브젝트 이름
namespace: velero
spec:
includedNamespaces: ##백업에 포함할 네임스페이스
- default
hooks:
resources: ##hook을 적용할 리소스 지정
- name: my-pod ##hook의 이름. 백업로그에 나오는
includedNamespaces: ##Hook을 적용할 네임스페이스. 위에 있는 동일 'includedNamespaces'와 다름
- default
includedResources: ##hook을 적용할 리소스
- pods
labelSelector: ## pod 라벨셀렉터 적용 가능
matchLabels:
app: test
component: server
pre:
exec:
- container: my-container
command:
- /bin/sh
- -c
- "fsfreeze --freeze /mnt/data"
onError: Fail
post:
exec:
- container: my-container
command:
- /bin/sh
- -c
- "fsfreeze --unfreeze /mnt/data"
onError: Fail
3-2. Restore Hooks
restore hook은 복원 작업 중에 실행되는 명령어를 정의한다. 이는 백업된 데이터를 복원할 때 특정 작업을 수행해야 할 때 유용하다. 예를 들어, 데이터베이스를 복원한 후 특정 스크립트를 실행하거나, 애플리케이션을 재구성하는 작업을 수행할 수 있다.
Post HooK과 헷갈릴 수 있는데, 아예 다른 개념이다. Backup Hooks에서 지원하는 post hook은 애초에 백업이 완료되고 나서이고, Restore Hooks는 시점이 백업이 아닌, 복원을 수행할 때이다.
Restore Hook은 두가지 Hooks를 지원한다.
- InitContainer Hooks: 이 후크는 복원된 파드에 초기화 컨테이너를 추가하여 애플리케이션 컨테이너가 시작되기 전에 필요한 설정을 수행한다.
ex) - Exec Restore Hooks: 이 후크는 복원된 Kubernetes 파드의 컨테이너에서 사용자 정의 명령이나 스크립트를 실행하는 데 사용된다.
Restore hook역시, 사용방법은 동일하다. annotation 또는 Restore Object의 API Spec을 이용한다.
첫번째로, Annotaiton사용 하여 Init Container Hooks를 사용하는 방법이다. Backup Hooks와 이름만 다르고 내용은 유사하다.
- init.hook.restore.velero.io/container-image
init container의 이미지를 지정한다.(Pod에 초기화 컨테이너가 추가되기 떄문이다.) - init.hook.restore.velero.io/container-name
init Container의 이름 지정 - init.hook.restore.velero.io/command
Init Container Entry Point 명령 지정. 기본적으로 entry point를 사용하고, 쉘을 사용하고 싶은 경우 직접 입력
ex) init.hook.restore.velero.io/command: ["/bin/sh", "-c", "echo Initializing... && sleep 10"]
Init Container 사용 예시(Annotation)
apiVersion: v1
kind: Pod
metadata:
name: example-pod
annotations:
init.hook.restore.velero.io/container-image: busybox
init.hook.restore.velero.io/container-name: init-myservice
init.hook.restore.velero.io/command: '["/bin/sh", "-c", "echo Initializing... && sleep 10"]'
spec:
containers:
- name: myservice
image: myservice:latest
ports:
- containerPort: 80
다음은 RestoreSpec을 이용하여 InitContainer Hooks를 사용하는 방법이다.
apiVersion: velero.io/v1
kind: Restore
metadata:
name: r2
namespace: velero
spec:
backupName: b2
excludedResources:
...
includedNamespaces:
- '*'
hooks:
resources:
- name: restore-hook-1
includedNamespaces:
- app
postHooks:
- init:
initContainers:
- name: restore-hook-init1
image: alpine:latest
volumeMounts:
- mountPath: /restores/pvc1-vm
name: pvc1-vm
command:
- /bin/ash
- -c
- echo -n "FOOBARBAZ" >> /restores/pvc1-vm/foobarbaz
- name: restore-hook-init2
image: alpine:latest
volumeMounts:
- mountPath: /restores/pvc2-vm
name: pvc2-vm
command:
- /bin/ash
- -c
- echo -n "DEADFEED" >> /restores/pvc2-vm/deadfeed
두 번째로는, Exec Restore Hooks이다. Pod에 Init Container를 추가하는 방식이 아닌 이미 실행 된 Pod의 컨테이너를 선택하여 command를 실행한다.
Annotation 방식은 다음과 같이 사용된다.
- post.hook.restore.velero.io/container
후크가 실행될 컨테이너의 이름. 기본값은 첫 번째 Container이다.
post.hook.restore.velero.io/command - 컨테이너에서 실행될 명령. 이 명령은 기본적으로 쉘 내에서 실행되지 않는다. 명령을 실행하기 위해 쉘이 필요한 경우, 명령의 시작 부분에 /bin/sh와 같이 직접 입력해줘야한다. 여러 인수가 필요한 경우, 명령을 JSON 배열로 지정한다. 예를 들어, ["/usr/bin/uname", "-a"]와 같이 지정할 수 있다.
- post.hook.restore.velero.io/on-error
실행 실패를 처리하는 방법. 유효한 값은 Fail과 Continue 이고 기본값은 Continue다. Continue 모드에서는 실행 실패가 로그에만 기록된다. Fail 모드에서는 모든 컨테이너에서 후크가 실행되지 않는다. 복원의 상태가 PartiallyFailed로 설정된다. - post.hook.restore.velero.io/exec-timeout
실행이 시작된 후 대기 시간. 기본값은 30초입니다. - post.hook.restore.velero.io/wait-timeout
컨테이너가 준비될 때까지 대기하는 시간. 동일 컨테이너 내의 선행 된 hook들이 모두 완료될 수 있도록 충분히 길어야 한다.. 대기 시간은 컨테이너가 복원될 때 시작되며, 이미지가 풀링되고 볼륨이 마운트되는 데 시간이 걸리는 시간도 포함하여 설정하여야 한다. 설정하지 않을 경우 무기한 대기한다. - post.hook.restore.velero.io/wait-for-ready
명령이 기본 컨테이너가 완전히 준비된 후에 실행되도록 보장하는 부울 값. 이 값을 true로 설정하면, 해당 파드의 다른 모든 후크 실행도 준비 상태를 기다리게 된다. 기본값은 false.
Annotaion 방식 사용 예시
apiVersion: v1
kind: Pod
metadata:
name: example-pod
namespace: app
annotations:
post.hook.restore.velero.io/container: main-container
post.hook.restore.velero.io/command: '["/bin/sh", "-c", "echo \"Post Restore Hook Executed\" && sleep 10"]'
post.hook.restore.velero.io/on-error: Continue
post.hook.restore.velero.io/exec-timeout: 30s
post.hook.restore.velero.io/wait-timeout: 60s
post.hook.restore.velero.io/wait-for-ready: "true"
spec:
containers:
- name: main-container
image: nginx
RestoreSpec 방식
apiVersion: velero.io/v1
kind: Restore
metadata:
name: example-restore
namespace: velero
spec:
hooks:
resources:
- name: restore-hook-2
includedNamespaces:
- app
postHooks:
- exec:
container: main-container
command:
- /bin/sh
- -c
- echo "Post Restore Hook Executed" && sleep 10
onError: Continue
execTimeout: 30s
waitTimeout: 60s
waitForReady: "true"
4. ETCD 백업과의 차이점
ETCD 백업하면 되는데 굳이 Velero를 사용하는 이유가 궁금한 분들을 위해 간단하게 기술한다.
ETCD 백업
- Kuberneted 클러스터의 전체 상태 정보를 백업한다. ETCD는 Key-Value DB로 백업 시, 스냅샷을 생성하여 백업한다.
- CSP 관리형 Cluster(EKS, GKE등) 사용 시 ETCD 백업이 불가하다.
Velero 백업
- namespace, pod, service, configmap, PV등 다양한 Kubernetes 리소스를 개별적으로 백업 가능하다.
- Yaml 형식으로 리소스를 저장하여, 필요할 때 복원할 수 있다. Velero는 리소스 백업 시, 클러스터 내의 리소스 정보를 수집하여 Yaml로 변환하고, 이를 저장소에 백업한다. 후에 복원 시 ,Yaml 파일을 읽어서 k8s api 서버에 적용한다.
- CSP 스냅샷 기능 활용하여 볼륨데이터를 백업한다.
- 스케쥴링 및 백업 정책이 유연하다.
결론
ETCD 백업에 비해 개별 리소스 단위로 세밀한 백업이 가능하며, 스케쥴링과 백업 정책등을 통해 운영자 편의에 맞춰서 유연한 설정이 가능하다. CSP의 관리형 클러스터에도 적용가능하다.
'Kubernetes > 실전압축지식' 카테고리의 다른 글
[실.압.지]Kubernetes Nodeselector란?(Affinity와의 차이점) (0) | 2024.08.29 |
---|---|
[실.압.지]Kubeconfig란 무엇인가? (0) | 2024.08.22 |