본문 바로가기
Kubernetes

[NKS]Velero를 활용하여 특정 네임스페이스를 통으로 백업하고 복원하기

by beann 2023. 7. 31.
반응형

최근 클러스터에 대한 백업 도구로 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기능 등 이를 잘 활용한다면 클러스터를 보다 안정적으로 운영할 수 있을 것 같습니다.

 

반응형