최근 클러스터에 대한 백업 도구로 Velero를 사용하는 곳이 많아지고 있습니다.
그럼 Velero란?
클러스터 레벨에서의 재해복구, 오브젝트 및 데이터 백업을 위한 오픈소스 도구 입니다.
Velero의 기능을 좀 더 살펴보겠습니다.
- PV 데이터 스냅샷
- 클러스터 전체백업 또는 선택적 백업(A-Namespace에 있는 오브젝트만 백업한다)
- 백업된 데이터를 통한 Restore
- 백업 스케줄링(cron 표현식을 사용하여 Velero 커맨드를 통해 백업스케줄링을 수행할 수 있습니다.)
그럼, 여기서 궁금한 점이 생길 수 있습니다.
바로 etcdctl을 통한 ETCD 백업과, Velero를 통한 백업에 어떤 차이가 있을지.
각 도구별 특징을 간략히 나누면 아래와 같습니다.
ETCD 백업
- etcd라는 데이터베이스를 백업한다.
- 클러스터를 통으로 백업한다.
- CSP에서 제공하는 관리형 쿠버네티스를 사용하는 경우 etcd를 백업하지 못한다.(기본적으로 CSP(Cloud Service Provider)에서 관리하기 때문에 접근이 통제되어 있음.)
Velero를통한 클러스터 백업
- 특정 리소스를 백업할 수 있다.(특정 네임스페이스에 속한 리소스 백업, label selector를 통해 매칭되는 리소스만 백업, 백업 스케줄링 기능)
- CSP와 연계하여 PV 백업 가능
위와 같이 etcdctl 백업은 클러스터의 전체 상태 백업에 유용하며, Velero 백업은 클러스터의 일부 또는 지속적인 백업, 그리고 CSP와의 연계가 필요한 경우에 유용합니다. 상황에 따라서 이 두 가지 방법을 적절히 활용하면 될 것 같습니다.
이제부터 Velero를 통한 클러스터 백업을 진행 해보겠습니다.
실습
사전 구성 및 실습 환경
- CSP: NKS(NCloud Kubernetes Service)
- Kubernetes Cluster Version: 1.24.10
- OS: Ubuntu18.04
- Velero Version: 1.10.3
- Object Storage
1. velero 설치 및 세팅
velero를 설치할 /tmp 디렉토리로 이동합니다.
cd /tmp
wget을 통해 velero를 다운받습니다.
wget https://github.com/vmware-tanzu/velero/releases/download/v1.10.3/velero-v1.10.3-linux-amd64.tar.gz
압축을 해제합니다.
tar -xvzf velero-v1.10.3-linux-amd64.tar.gz
velero커맨드를 사용할 수 있도록 파일을 이동시켜줍니다.
mv velero-v1.10.3-linux-amd64/velero /usr/local/bin/velero
2. Secret등록
velero를 통해 백업을 진행할 때 오브젝트 스토리지에 저장하는데요. restore를 할때에도 마찬가지로 오브젝트 스토리지에 있는 백업파일을 참조하여 진행하게 됩니다.
이때 CSP에서 제공하는 Object Storage와 연계하기 위해서는 Secret 정보를 등록 해야합니다.
$ vi cloud-credential
[default]
aws_access_key_id=<ACCESS_KEY_ID>
aws_secret_access_key=<SECRET_ACCESS_KEY>
region=<REGION>
server_api_uri=https://ncloud.apigw.ntruss.com/vserver/v2
#####예시######
[default]
aws_access_key_id=123ABC456DEF789GHI # 포털 > 마이페이지 > 인증키 관리에서 확인
aws_secret_access_key=123ABC456DEF789GHI123ABC456DEF789GHI # 포털 > 마이페이지 > 인증키 관리에서 확인
region=KR # 한국리전
server_api_uri=https://ncloud.apigw.ntruss.com/vserver/v2
3. Velero 서버 설치
Velero 서버를 설치합니다. Obejct Storage는 미리 생성되어 있어야 하며, 저의 경우 sjhvelerotest라는 이름의 bucket을 생성 해놓았습니다.
velero install \
--provider velero.io/aws \
--bucket sjhvelerotest \
--plugins velero/velero-plugin-for-aws:v1.6.2,nks.kr.private-ncr.ntruss.com/velero-plugin-for-ncloud:v0.0.7 \
--backup-location-config region=kr,s3ForcePathStyle="true",s3Url=https://kr.object.private.ncloudstorage.com \
--use-volume-snapshots=false \
--secret-file=./cloud-credential
설치 여부를 확인합니다.
kubectl get pod -n velero
NAME READY STATUS RESTARTS AGE
velero-668c4fd44f-8f9xc 1/1 Running 0 8m13s
4. 스냅샷 구성
클러스터 블록 스토리지의 스냅샷을 정상적으로 생성할 수 있도록, 아래 명령어를 실행하여 네이버 클라우드 플랫폼에서 제공하는 플러그인을 기본 스냅샷 프로바이더로 지정합니다
velero snapshot-location create default --provider ncloud/volume-snapshotter-plugin
5. 예제 리소스 배포
이제 거의다 왔습니다. 실제로 backup 테스트를 진행하기 위해 예제 리소스를 배포 해보도록 하겠습니다.
# nginx-example.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: nginx-example
labels:
app: nginx
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-log-pvc
namespace: nginx-example
labels:
app: nginx
spec:
storageClassName: nks-block-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: nginx-example
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: nginx-logs
persistentVolumeClaim:
claimName: nginx-log-pvc
containers:
- image: nks.kr.ncr.ntruss.com/nginx:1.9
name: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/var/log/nginx"
name: nginx-logs
readOnly: false
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: nginx-example
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
type: LoadBalancer
selector:
app: nginx
여기까지 잘 따라오셨다면 NKS를 통해 생성된 LB로 nginx webserver에 접속을 해봅니다.
잘 접속이 되네요.
이제 nginx에 대한 Access로그를 Pod에 직접 접속하여 정상적으로 쌓였는지 확인합니다.
kubectl get pod -n nginx-example
NAME READY STATUS RESTARTS AGE
nginx-deploy-7cb796cf76-8cvrr 1/1 Running 0 5m15s
nginx pod에 접속합니다.
kubectl get pod -n nginx-example
NAME READY STATUS RESTARTS AGE
nginx-deploy-7cb796cf76-8cvrr 1/1 Running 0 5m15s
kubectl exec -it -n nginx-example nginx-deploy-7cb796cf76-8cvrr /bin/bash
root@nginx-deploy-7cb796cf76-8cvrr:/#
nginx server에대한 access 로그를 확인합니다.
정상적으로 로깅이 된 것이 확인 됩니다.
cd /var/log/nginx
root@nginx-deploy-7cb796cf76-8cvrr:/var/log/nginx# cat access.log
10.10.1.11 - - [31/Jul/2023:07:42:02 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36" "-"
10.10.1.11 - - [31/Jul/2023:07:42:02 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://223.130.144.72/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36" "-"
6. deployment 재배포
현재 nginx-example의 이미지는 NCloud에서 제공되는 이미지입니다. 이번엔 docker hub에서 nginx image를 Pull 해보겠습니다.
kubectl set image deployment nginx-deploy -n nginx-example nks.kr.ncr.ntruss.com/nginx:1.9=nginx:1.14
Pod Template.Containers.nginx.image를 보면 nginx:1.14로 변경된 것을 확인할 수 있습니다
또한, message를 보면 정상적으로 스케일이 Down 되었다가 다시 Up된 것을 확인 가능합니다.
kubectl describe deployment nginx-deploy -n nginx-example
Name: nginx-deploy
Namespace: nginx-example
CreationTimestamp: Mon, 31 Jul 2023 16:41:34 +0900
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=nginx
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.14
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts:
/var/log/nginx from nginx-logs (rw)
Volumes:
nginx-logs:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: nginx-log-pvc
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: nginx-deploy-7cb796cf76 (0/0 replicas created)
NewReplicaSet: nginx-deploy-5c7c46565f (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 15m deployment-controller Scaled up replica set nginx-deploy-7cb796cf76 to 1
Normal ScalingReplicaSet 17s deployment-controller Scaled up replica set nginx-deploy-5c7c46565f to 1
Normal ScalingReplicaSet 14s deployment-controller Scaled down replica set nginx-deploy-7cb796cf76 to 0
7. 이제는 nginx-example 네임스페이스를 백업 해보도록 하겠습니다.
$ 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.
정상적으로 백업이 되었는지 확인합니다.
상태값이 Completed가 되면 정상적으로 백업이 되었다고 보면 됩니다.
$ velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
nginx-backup Completed 0 0 2023-07-31 17:06:45 +0900 KST 29d default <none>
$ velero backup describe
Name: nginx-backup
Namespace: velero
Labels: velero.io/storage-location=default
Annotations: velero.io/source-cluster-k8s-gitversion=v1.24.10
velero.io/source-cluster-k8s-major-version=1
velero.io/source-cluster-k8s-minor-version=24
Phase: Completed
Errors: 0
Warnings: 0
Namespaces:
Included: nginx-example
Excluded: <none>
Resources:
Included: *
Excluded: <none>
Cluster-scoped: auto
Label selector: <none>
Storage Location: default
Velero-Native Snapshot PVs: auto
TTL: 720h0m0s
CSISnapshotTimeout: 10m0s
Hooks: <none>
다음으로 Object Storage에 정상적으로 업로드 되었는지 확인합니다.
Object Storage로도 잘 업로드 되었네요.
8. nginx-example 네임스페이스 삭제
nginx-example 네임스페이스를 삭제하여 해당 네임스페이스에 속한 모든 리소스를 함께 제거합니다.
$ kubectl delete ns nginx-example
namespace "nginx-example" deleted
$ kubectl get all -n nginx-example
No resources found in nginx-example namespace.
9. nginx-example 네임스페이스 복원
이제 삭제된 nginx-example네임스페이스를 복원 합니다.
$ velero restore create --from-backup nginx-backup
Restore request "nginx-backup-20230731172203" submitted successfully.
Run `velero restore describe nginx-backup-20230731172203` or `velero restore logs nginx-backup-20230731172203` for more details.
복원이 잘 되었네요.
$ kubectl get all -n nginx-example
NAME READY STATUS RESTARTS AGE
pod/nginx-deploy-5c7c46565f-dp5vd 1/1 Running 0 22s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-svc LoadBalancer 198.19.181.89 <pending> 80:32656/TCP 22s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deploy 1/1 1 1 22s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deploy-5c7c46565f 1 1 1 22s
replicaset.apps/nginx-deploy-7cb796cf76 0 0 0 22s
백업 당시의 deployment에 대한 정보와 일치한 것이 확인됩니다.
$ kubectl describe deploy nginx-deploy -n nginx-example
Name: nginx-deploy
Namespace: nginx-example
CreationTimestamp: Mon, 31 Jul 2023 17:22:10 +0900
Labels: app=nginx
velero.io/backup-name=nginx-backup
velero.io/restore-name=nginx-backup-20230731172203
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=nginx
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.14
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts:
/var/log/nginx from nginx-logs (rw)
Volumes:
nginx-logs:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: nginx-log-pvc
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: nginx-deploy-7cb796cf76 (0/0 replicas created)
NewReplicaSet: nginx-deploy-5c7c46565f (1/1 replicas created)
Events: <none>
결론
Ncloud에서 제공하는 관리형 쿠버네티스 서비스인 NKS와, Kubernetes Cluster Backup & Restore 도구인 Velero를 통해 백업 및 리스토어를 해보았습니다.
기본적으로 관리형 쿠버네티스 서비스의 경우 클러스터 구성, CSP 서비스와 연계 등 다양한 이점이 있지만, ETCD에 대한 접근 권한을 주지 않기때문에 운영중인 클러스터에 대한 Backup 및 Restore가 어려운 점이 있습니다. 하지만 Velero는 리소스에 대한 전체 백업과, 일부 백업, PV 백업, Cron기능 등 이를 잘 활용한다면 클러스터를 보다 안정적으로 운영할 수 있을 것 같습니다.
'Kubernetes' 카테고리의 다른 글
Kubernetes Network Study #2(Service to Pod) (0) | 2023.11.23 |
---|---|
Kubernetes Network Study #1 (Pod to Pod, CNI. Calico) (0) | 2023.11.22 |
Ingress에서 다른 Namespace에 있는 Service로 라우팅 하기 (0) | 2023.07.25 |
Kubernetes 인증서 관리를 위한 가이드: cert-manager와 issuer 설치 (1) | 2023.07.25 |
CKA 합격후기(2023.05.29 합격) (0) | 2023.07.17 |