티스토리 뷰

Cloud/Kubernetes

Velero

jacobbaek Jacob_baek 2021. 4. 6. 23:56

Kubernetes 환경에서 Backup과 Restore를 명령줄로 수행할수 있는 도구를 찾다가 Velero라는 도구가 있어 이를 사용해보면서 내용을 정리해보았다.

Velero란

Velero란 (이전에 알려진것은 Heptio Ark이다.) Kubernetes Cluster 자원과 PV(persistent Volume)들을 Backup하고 Restor 할수 있게 해주는 도구이다.

Velero는 다음과 같은 기능을 수행할수 있다.

Velero는 다음과 같은 구성을 가진다.

  • velero client
  • velero controller
  • object storage

위 구성은 다음과 같은 방식으로 동작된다.
velero cli <-> velero controller <-> object storage

즉, velero cli를 통해 velero controller에 backup 생성을 요청하게 되고 controller는 backup 데이터를 object storage에 생성한다.

How Velero works

위에 설명했던 동작과정은 다음과 같다.

  • https://velero.io/docs/main/how-velero-works/
  • velero client는 Backup object를 생성하는 Kubernetes API server에 호출을 생성한다.
  • BackupController는 새로운 Backupobject를 알려주고 검증을 수행한다.
  • BackupController는 backup process를 시작한다. 자원에 대한 API Server 쿼리를 통한 backup할 데이터를 수집한다.
  • BackupController는 object storage server에 호출을 생성한다.
  • 출처 : https://github.com/mboumsahi/velero

Velero 사용

Velero 사용전에

Velero 사용을 위해서는 object storage가 준비되어 있어야 한다.
하여 example에서는 minio yaml을 제공하고 있고 이를 통해 s3 호환이 되는 object storage 환경에서
테스트 해볼수 있다. 물론 s3 나 실제 서비스 가능한 환경을 이용하는것을 추천한다.

Velero 설치

Velero는 cli 도구와 실제 backup 및 restore를 수행할 kubernetes 에 동작되는 controller 두개의 구성요소가 있다고 볼수 있다.
먼저 CLI를 다운로드 받고 파일을 등록된 PATH에 복사하는 과정을 거쳐 velero command를 사용할수 있도록 한다.

root@localhost:~# curl -L https://github.com/vmware-tanzu/velero/releases/download/v1.5.4/velero-v1.5.4-linux-amd64.tar.gz | tar xvfz -
root@localhost:~# sudo mv velero-v1.5.4-linux-amd64/velero /usr/local/bin

복사한 CLI를 사용하여 kubernetes 환경에 Controller를 설치해보자.

root@localhost:~# velero install --provider aws --plugins velero/velero-plugin-for-aws:1.0.0 --bucket velero --secret-file ~/.credentials-minio  --use-volume-snapshots=false --use-restic --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.0.1:9000
  • 여기서 192.168.0.1:9000 의 경우 velero example에서 제공하는 minio 이다.
  • minio는 S3 호환이기에 AWS를 provider로 지정한다.
    (Provider는 링크를 참고하기를 바란다.)

또한 참고할것은
.credentials-minio로 지정한 파일을 아래와 같이 생성해주어야 한다.(파일명은 자유롭게 하여도 무방하다.)

[default]
aws_access_key_id = minio
aws_secret_access_key = minio123

물론 아래와 같이 별도의 object storage를 지정하지 않고도 설치가 가능하다.
다만 옵션상에 use-volume-snapshots가 false 상태여야 한다. 물론 이와 같은 방식은 사실 의미 있는 방식은 아니다.
Backup과 restore를 로컬에서만 진행하게 되어 Backup에 의미가 사라진 방식이라 볼수 있다.

root@localhost:~# velero install --no-default-backup-location --no-secret --use-volume-snapshots=false

아래 페이지에 OS별 설치방법이 잘나와있으니 참고바란다.

velero quick guide

아래 링크에서 제공하는 nginx-example을 기반으로 Backup 및 Restore를 수행해보자.

또한 Object Storage는 Example로 제공되는 Minio를 사용하였다.
첫번째 Kubernetes는 kubespray로 배포된 환경이며 두번째 Kubernetes는 K3s를 사용하였다.

Backup

Example로 제공되는 nginx-example을 배포하여 각종 resource를 생성하고

root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# kubectl apply -f with-pv.yaml
namespace/nginx-example created
persistentvolumeclaim/nginx-logs created
deployment.apps/nginx-deployment created
service/my-nginx created
root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# kubectl get all -n nginx-example
NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-53a7xab28-m1x3c   1/1     Running   0          6s
pod/nginx-deployment-53a7xab28-yrfk4   1/1     Running   0          6s

NAME               TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/my-nginx   LoadBalancer   10.233.1.218   <pending>     80:30554/TCP   6s

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   2/2     2            2           6s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-53a7xab28   2         2         2       6s```

velero backup 명령을 이용해 backup 생성을 해보자.

root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# velero backup create nginx-backup-pvc --include-namespaces=nginx-example
Backup request "nginx-backup-pvc" submitted successfully.
Run `velero backup describe nginx-backup-pvc` or `velero backup logs nginx-backup-pvc` for more details.
root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# velero backup get
NAME               STATUS       ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
nginx-backup       Completed    0        0          2021-04-06 14:16:41 +0900 KST   29d       default            <none>
nginx-backup-pvc   InProgress   0        0          2021-04-06 15:43:34 +0900 KST   29d       default            <none>

위와 같이 지정한 nginx-backup-pvc라는 이름으로 backup data가 생성되었음을 확인할수 있따.

아래는 실제 minio에 존재하는 backup 된 데이터들이 생성된 파일과 경로들이다.

root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# mc tree --files minio/velero
minio/velero
├─ backups
│  └─ nginx-backup-pvc
│     ├─ nginx-backup-pvc-csi-volumesnapshotcontents.json.gz
│     ├─ nginx-backup-pvc-csi-volumesnapshots.json.gz
│     ├─ nginx-backup-pvc-logs.gz
│     ├─ nginx-backup-pvc-podvolumebackups.json.gz
│     ├─ nginx-backup-pvc-resource-list.json.gz
│     ├─ nginx-backup-pvc-volumesnapshots.json.gz
│     ├─ nginx-backup-pvc.tar.gz
│     └─ velero-backup.json
└─ restores
   └─ nginx-backup-pvc-20210406140551
      ├─ restore-nginx-backup-pvc-20210406140551-logs.gz
      └─ restore-nginx-backup-pvc-20210406140551-results.gz

여기서 velero-backup.json에는 velero backup describe nginx-backup-pvc로 확인되는 내용들이 json 형태로 기입되어 있다.

Restore

복원은 예제에도 나와있듯이 nginx-example namespace 자체를 삭제하여 pod 및 기존 resource가 미존재하는 상황을 연출하고
velero restore 명령을 사용하여 기존 환경 그대로 다시 서비스를 올리는 과정을 수행해볼것이다.

아래와 같이 앞서 백업했던 with-pv.yaml로 생성한 resource들을 모두 삭제해보자.

root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# kubectl delete -f with-pv.yaml
namespace "nginx-example" deleted
persistentvolumeclaim "nginx-logs" deleted
deployment.apps "nginx-deployment" deleted
service "my-nginx" deleted

이후 velero restore 명령을 이용해 복원해보자.

root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# velero restore create --from-backup nginx-backup-pvc
Restore request "nginx-backup-20210406134314" submitted successfully.
Run `velero restore describe nginx-backup-20210406134314` or `velero restore logs nginx-backup-20210406134314` for more details.

복원이 정상적으로 이루어진다.

Migration

앞서 첫번째, 두번째 Kubernetes Cluster에 대해 언급을 하였는데 Migration의 개념으로 이를 활용할수 있기에 두개의 Kubernetes Cluster에서 어떻게 기존 Resource를 다른 Cluster로 Migration 할수 있는지에 대하여 알아보도록 하겠다.

Cluter2라는 새로운 Kubernetes Cluster를 생성하고 아래와 같이 velero controller를 설치하여 velero backup 및 restore가 가능한 환경을 만들자.

root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64# velero install --provider aws --plugins velero/velero-plugin-for-aws:v1.0.0 --bucket velero --secret-file ~/.credentials-minio --use-volume-snapshots=false --use-restic --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.0.1:9000

Cluster2에 Cluster1에서 수행한 Backup이 조회됨을 알수 있다.

root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# velero backup get
NAME               STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
nginx-backup-pvc   Completed   0        0          2021-04-06 13:52:10 +0000 UTC   29d       default            <none>
root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# velero backup get
NAME               STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
nginx-backup-pvc   Completed   0        0          2021-04-06 14:02:10 +0000 UTC   29d       default            <none>

Cluster2에서 복원을 해보자.

root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# velero restore create --from-backup nginx-backup-pvc
Restore request "nginx-backup-pvc-20210406140551" submitted successfully.
Run `velero restore describe nginx-backup-pvc-20210406140551` or `velero restore logs nginx-backup-pvc-20210406140551` for more details.

아래와 같이 cluster1과 동일한 deployment와 service 그리고 persistentvolumeclaim이 생성됨을 확인할수 있다.

root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64# kubectl get all,pvc -n nginx
-example
NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-66689547d-z5xbz   0/2     Pending   0          16m
pod/svclb-my-nginx-nbjzj               0/1     Pending   0          16m

NAME               TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/my-nginx   LoadBalancer   10.43.216.117   <pending>     80:30778/TCP   16m

NAME                            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/svclb-my-nginx   1         1         0       1            0           <none>          16m

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   0/1     1            0           16m

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-66689547d   1         1         0       16m

NAME                               STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS      AGE
persistentvolumeclaim/nginx-logs   Pending                                      rook-ceph-block   16m

다만 계속 PVC가 Pending 상태로 남는 문제가 있었다.

아래 pvc를 보면 해당 Cluster에서 사용되는 longhorn storageclass가 아닌 다른 storageclass name을 가지고 있고 이로 인해
생성이 안되고 있음을 확인할수 있다.
즉, 생성된 pvc는 기존 StorageClass를 그대로 가져왔음을 확인할수 있다.

root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# kubectl get pvc -n nginx-example
NAME         STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS      AGE
nginx-logs   Pending                                      rook-ceph-block   11m

위와 같은 StorageClass 이슈로 동일한 StorageClass를 사용하는 환경에서만 가능한것으로 파악된다.
참고로 아래에 소개된 바와 같이 PVC의 경우 StorageClass 변경이 불가하다.

그럼 pvc만 없으면 정상적으로 Migration 과정이 동작 되는지 알아보자.
pvc가 없는 nginx-example을 배포하고 이를 backup 해보자.

root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# kubectl delete -f with-pv.yaml
namespace "nginx-example" deleted
persistentvolumeclaim "nginx-logs" deleted
deployment.apps "nginx-deployment" deleted
service "my-nginx" deleted
root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# kubectl apply -f base.yaml
namespace/nginx-example created
deployment.apps/nginx-deployment created
service/my-nginx created
root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# kubectl get all,pvc -n nginx-example
NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-57d5dcb68-gz8l9   1/1     Running   0          34s
pod/nginx-deployment-57d5dcb68-m4cht   1/1     Running   0          34s

NAME               TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
service/my-nginx   LoadBalancer   10.233.51.92   192.168.0.100   80:32485/TCP   33s

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   2/2     2            2           34s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-57d5dcb68   2         2         2       34s

이제 velero backup으로 방금 생성한 nginx-example을 backup 해보자.

root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# velero backup create nginx-backup --include-namespaces=nginx-example
Backup request "nginx-backup" submitted successfully.
Run `velero backup describe nginx-backup` or `velero backup logs nginx-backup` for more details.
root@cluster1:~/velero-v1.5.4-linux-amd64/examples/nginx-app# velero backup get
NAME               STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
nginx-backup       Completed   0        0          2021-04-06 23:41:50 +0900 KST   29d       default            <none>
nginx-backup-pvc   Completed   0        0          2021-04-06 23:02:10 +0900 KST   29d       default            <none>

동일한 backup이 존재하는지 확인한다.

root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# velero backup get
NAME               STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
nginx-backup       Completed   0        0          2021-04-06 14:30:16 +0000 UTC   29d       default            <none>
nginx-backup-pvc   Completed   0        0          2021-04-06 14:02:10 +0000 UTC   29d       default            <none>

이제 기존 배포되어 있던 nginx-example 을 모두 삭제하고 복원해보자.

root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# kubectl delete ns/nginx-example
namespace "nginx-example" deleted
root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# velero restore create --from-backup nginx-backup
Restore request "nginx-backup-20210406144247" submitted successfully.
Run `velero restore describe nginx-backup-20210406144247` or `velero restore logs nginx-backup-20210406144247` for more details.
root@cluster2:~/velero-v1.6.0-rc.2-linux-amd64/examples/nginx-app# kubectl get all -n nginx-example
NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-57d5dcb68-gz8l9   1/1     Running   0          3s
pod/nginx-deployment-57d5dcb68-m4cht   1/1     Running   0          3s

NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/my-nginx   NodePort   10.43.217.140   <none>        80:32407/TCP   3s

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   2/2     2            2           3s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-57d5dcb68   2         2         2       3s

여기서 또 cluster1과 다른 환경이 있어 LoadBalacner를 변경하여 백업 및 복원하였다.
즉, migration 을 원할 경우 기존 환경과 동일한 환경으로 구성하는것을 권장한다.

Restic 연동

restic
단순 file copy program이 아닌 snapshot 을 이용하여 backup하고 이를 repository에 저장한다.
repository에 저장된 데이터는 AES로 암호화되어 안전하게 보관 및 전송될수 있다.

참고사이트

'Cloud > Kubernetes' 카테고리의 다른 글

Velero  (0) 2021.04.06
ingress with subpath  (0) 2021.03.23
Cluster-API  (0) 2021.03.20
kubernetes ingress  (0) 2021.03.15
Longhorn  (0) 2021.03.13
K3s with calico  (0) 2021.03.05
댓글
댓글쓰기 폼