kubernetes 백업 위한 velero x minio docker / kubernetes




쿠버네티스 환경에서 개발을 하다 보면 특정 환경변수를 입력하여 배포 하는 일이 자주 발생한다.
배포때마다 매번 입력하는 상황이 반복 될 수 있는데 이를 피하고자 백업 후에 복원을 하는 방법을 구축했다.



kubernetes 백업의 종류

백업은 노드 레벨과 어플리케이션 레벨로 나눌 수 있다.
노드 레벨은 말그대로 클러스터링 환경을 백업해두고 재구축 하는 것이고,
어플리케이션 레벨은 배포된 리소스들의 백업이다.

마스터 노드 백업
kubernetes 환경을 복원 및 재구축시 진행
etcd snapshot 저장 / kubeadm config 설정 백업


어플리케이션 레벨의 백업 (controller, resource 등등)
Pods, deployment, replicaset 등의 controller 및 리소스 등을 백업하여, 특정 시점의 배포된 상태로 복원한다.

노드 레벨의 백업은 설정 파일 등의 백업 후 재사용으로 환경을 구축해내는 것으로 진행 가능하다.
다행이 어플리케이션 레벨의 백업은 이미 오픈 소스가 있어서 손쉽게 가능하다.

오픈 소스

velero 를 통해 백업 및 복원 기능을 제공할 수 있으며, velero에서 연동 가능한 스토리지로 minio가 소개되어 있다.

이 포스팅에서는 어플리케이션 레벨의 백업에 대한 내용을 진행하겠다.



velero x minio 구축

100

velero

Kubernetes 클러스터 리소스 및 영구 볼륨을 백업 및 복원 할 수있는 도구.

AWS, GCP, Azure 와 연동하여 구축이 가능.

on-premise 환경에선 minio와 호환하여 구축 가능


MinIO

고성능 분산 객체 스토리지 시스템

MinIO는 처음부터 프라이빗 클라우드 객체 스토리지의 표준으로 설계

성능과 확장성이 뛰어나고 가벼운 클라우드 서버 구축 가능



구축에 앞서 velero의 경우 인증을 위한 secret 생성을 먼저 진행해야 한다. 
이 secret에 minio와 연동 위한 인증키 정보를 담아야 minio와 연동하여 백업 데이터를 저장 가능하다.

1
kubectl create secret generic cloud-credentials --namespace <VELERO_NAMESPACE> --from-file cloud=<FILE_NAME>
cs

파일 이름은 minio 구축 시에 입력하는 accessKey와 secretKey 정보가 담긴 파일 경로가 들어가면 된다.
velero 설치시에 설정 되어 있는 기본 secret 이름이 cloud-credentials 이며 참조하는 키 이름이 cloud 인데
따로 설정을 수정하지 않는다면 고정으로 입력해주면 된다.


minio 스토리지 구축

minio 페이지에서 다양한 설치 방법을 제공하고 있다.

Standalone, Distributed 두 가지 설치 방법이 있으며, 하나의 노드에 대해 설치를 진행할 때는 standalone으로 진행하고, 클러스터 환경에선 distributed 로 진행하면 된다.

distributed는 최소 4대의 노드가 필요하며, 쿠버네티스 설치에 대해서는 두 가지로 설치를 진행이 가능하다.

statefulset 설치를 위한 yaml 파일을 생성하여 배포하는 방법과 helm 차트에서 설치가 가능하다.

accessKey와 secretKey에는 특수문자를 넣으면 안된다.



필요한 입력 값을 기입하면 yaml 을 생성해준다. 파일로 저장하여 배포하면 간단히 설치 가능하다.

helm 차트에 등록되어 있는 minio를 설치 가능하다.

helm 차트를 이용할 경우 access_key, secret_key 등에 대한 옵션을 추가해서 설치를 진행해야 한다.


on-premise 환경 진행이므로 PV, PVC 를 미리 생성 후 연결하여 배포를 진행해야한다.

hostPath가 아닌 local-storage를 연동해야 분산환경에서 각 노드간에 저장된 내용 공유가 가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
apiVersion: v1
kind: PersistentVolume
metadata:
  name: minio-local-volume
  namespace: velero
spec:
  capacity:
    storage: 5G
  accessModes:
  - ReadWriteMany
  volumeMode: Filesystem
  storageClassName: "local-storage"
  local:
    path: /data/minio
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - "node-dev1"
          - "node-dev2"
          - "node-dev3"
          - "node-dev4"
          - "node-dev5"
          - "node-dev6"
  claimRef:
    namespace: velero
    name: minio-local-volume-claim
 
---
 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: minio-local-volume-claim
  namespace: velero
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5G
  storageClassName: local-storage
  volumeMode: Filesystem
cs

PVC 생성 후 생성한 yaml 파일로 minio 배포를 진행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
apiVersion: v1
kind: Service
metadata:
  name: minio
  namespace: velero
  labels:
    app: minio
spec:
  clusterIP: None
  ports:
    - port: 9000
      name: minio
  selector:
    app: minio
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: minio
  namespace: velero
spec:
  serviceName: minio
  replicas: 4
  template:
    metadata:
      labels:
        app: minio
    spec:
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: minio-local-volume-claim
      containers:
      - name: minio
        env:
        - name: MINIO_ACCESS_KEY                  ## velero 연동 시 사용되는 정보
          value: "minio"
        - name: MINIO_SECRET_KEY
          value: "minio123"
        image: minio/minio:latest
        args:
        - server 
        - http://minio-{0...3}.minio.velero.svc.cluster.local/data   # 4대의 분산 노드와 통신하기 위한 service 내부 도메인 / 도메인 뒤에 url 경로는 volume 매핑되는 폴더 경로
        ports:
        - containerPort: 9000
        volumeMounts:
        - name: data
          mountPath: /data
 
---
apiVersion: v1
kind: Service
metadata:
  name: minio-service
  namespace: velero
spec:
  type: NodePort
  ports:
    - port: 9000
      targetPort: 9000
      protocol: TCP
      nodePort: 32099
  selector:
    app: minio
cs

볼륨 경로가 잘못되지 않는 상황이면 대부분 배포에 문제는 발생하지 않는다.

storage 특성 때문인지 처음 설치 후에 replicas 수가 조정되면 초기화 에러 및 상태 공유가 안되는 이슈가 발생한다.

처음 구축 시에 사용할 노드에 대해 설계 완료 후 사용 권장한다.

이 후 설치한 <url>:32099로 접속하게 되면 화면이 출력되고 설장한 accessKey와 secretKey로 로그인하면 된다.



velero 서버 구축

velero 사용을 위해서는 velero 서버 구축이 필요하며, 클라이언트 설치가 필요하다.

release 정보 페이지 : https://github.com/vmware-tanzu/velero/releases

1
2
3
wget <RELEASE-TARBALL-URL>
tar -xvf <RELEASE-TARBALL-NAME>.tar.gz -/dir/to/extract/to
cp /dir/to/extract/to/velero /usr/local/bin
cs

클라이언트 설치 완료 후 minio 와 연동 위한 인증키 정보 파일로 부터 secret 을 생성

1
2
3
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
cs

velero 서버 설치를 진행. --backup-location-config 옵션 값은 minio 연동 위한 값으로 모두 넣어줘야 한다. 

또한 velero install 전에 --bucket 옵션으로 주어지는 bucket이 minio에 생성되어 있어야한다.\

1
2
3
4
5
6
7
8
velero install \
    --provider aws \
    --bucket velero \
    --secret-file ./cloud-credentials \
    --use-volume-snapshots=false \
    --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000,publicUrl=<minio가 설치된 서버:포트번호>
    # 1.2.0 버전 업되면서 install 옵션이 추가
    --plugins velero/velero-plugin-for-aws:v1.0.0,velero/velero-plugin-for-microsoft-azure:v1.0.0,velero/velero-plugin-for-gcp:v1.0.0
cs

설치가 진행 되면 관련 서버 및 resource 설치가 진행된다. backup-location 리소스 이름이 default인데 인증키 정보 파일의 인증 정보 탭이름을 일치시켜줘야 한다.

모든 설치 완료 후 버전 확인을 하면 클라이언트 버전과 서버 버전이 모두 보여진다. 제대로 설치가 되지 않으면 server 버전정보가 표시 되지 않는다.

1
2
3
4
5
6
$ velero version
Client : 
    Version: v1.1.0
    Git commit: <commit hash data>
Server:
    Version: v1.1.0     # minio와 연동 실패 등으로 서버가 제대로 구동되지 않을 수 있다.
cs

velero 서버 삭제는 deployment와 관련 리소스 삭제를 같이 진행해야 초기화 설치가 가능하다.

1
2
kubectl delete namespace/velero clusterrolebinding/velero  # 재설치의 경우 굳이 삭제하지 않아도 된다.
kubectl delete crds -l component=velero
cs




velero 간단 사용법


백업

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 네임스페이스 지정
$ velero backup create <BACKUP_NAME> --include-namespaces tpas,heimdall,kafka
 
 
# 특정 네임스페이스 제외
$ velero backup create <BACKUP_NAME> --exclude-namespaces default,kube-system
 
 
# 네임스페이스의 특정 리소스 제외
$ velero backup create <BACKUP_NAME> --include-namespaces tpas,heimdall,kafka --exclude-resources ingress,service
 
 
# 백업 데이터 확인 / 어떤 리소스가 백업되어 있는지 확인 가능
$ velero backup describe <BACKUP_NAME> --details
cs

기본적은 특정 네임스페이스에 포함된 리소스들에 대한 백업 데이터를 생성하는 명령어이다.

생성이 되면 해당 리소스들에 대한 정보가 json화 되어 연동된 minio에 생성한 bucket에 저장된다.

bucket 저장된 데이터는 압축된 데이터로 따로 다운받아서 확인 가능하며, describe 명령어로 백업 리소스 리스트를 확인 가능하다.



복원

1
velero restore create <restore-name> --from-backup <backup-name>
cs

백업 데이터로 부터 복원해주는 명령어로 minio에는 복원 결과와 로그가 남는다.



스케줄링 백업

1
velero schedule create <schedule-name> --schedule="0 1 * * * or @daily" --include-resources deployments,service
cs

스케줄링 백업 데이터를 생성하는 명령어로 crontab 또는 지정된 명령어를 지정하여 주기적인 백업 데이터를 생성할 수 있다.

1
2
3
4
5
6
7
Entry                  | Description                                | Equivalent To
-----                  | -----------                                | -------------
@yearly (or @annually) | Run once a year, midnight, Jan. 1st        | 0 0 1 1 *
@monthly               | Run once a month, midnight, first of month | 0 0 1 * *
@weekly                | Run once a week, midnight between Sat/Sun  | 0 0 * * 0
@daily (or @midnight)  | Run once a day, midnight                   | 0 0 * * *
@hourly                | Run once an hour, beginning of hour        | 0 * * * *
cs



백업 삭제

1
velero backup delete <backup-name>
cs

생성한 백업 데이터를 삭제한다.


운영 환경에서는 필요하다면 사용할 수 있겠지만 보통 운영환경에서 잦은 배포가 발생한다해도 환경변수는 고정인 경우가 많아서 아직 편의성을 제공하는 정도로 와닫지 않는 것 같다.
기술은 활용법의 문제이므로 상황에 맞게 사용법을 고민하면 될 것 같다.




덧글

댓글 입력 영역



광고