쿠버네티스 일반

Kube snapshot scheduler

Jerry_이정훈 2021. 7. 22. 13:17
728x90

오늘은 kube 환경에서 snapshot 생성을 정해진 시간에 실행하고 보관 주기(retention) 설정이 가능한 snapshotscheduler kube tool 소개해 드립니다.

 

많은 Kube 툴들이 그렇지만, 이 툴도 설치에서 사용까지 5분 정도면 가능합니다. 빠르게 검증해서 사용하기 유용합니다.

Test 내역

  • Kube Snapshot Schedule 설정
    : 매 6시간 마다 snapshot 생성 및 4 Copy 보관(최대 24H 보관)
    : 매일 새벽 3시 snapshot 생성 및 7 Copy 보관(7일 보관)
  •  snapshot 복구 검증 
  • snapshot 사용 용량 확인은 실패 (^^)

snapshot을 사용하기 위해서는 kube 환경의 snapshot을 지원하는 (당연하지만) storage가 있어야 합니다. 이게 가장 큰 허들이네요. ^^ 일반 상용 스토리지가 snapshot 지원하는 건 당연하지만 그게 kube 환경의 snapshot을 지원 여부는 다른 이야기이기도 합니다. 사용하는 스토리지 벤더에 문의해야 합니다.

 

저는 오픈소스 Ceph(rook 이용) storage로 검증 하였습니다. 다행히 Ceph는 Major 오픈 소스 스토리지 답게 Kube 환경의 snapshot을 지원 합니다. 사실은, 저도 ceph를 Kube 운영 환경에 사용하지는 않고 openebs-hostpath를 사용 중 입니다. ceph는 kube 환경에서 사용하는 고객 사례들이 많이 있어 실 사용하시는데 크게 문제점은 없을 것 같습니다. (물론 ceph 성능 튜닝은 꼭 필요합니다.) 

 

Storage 사용 환경 

[spkr@erdia22 kvdi (ubuns:yelb)]$ k get volumesnapshotclasses.snapshot.storage.k8s.io
NAME                      DRIVER                       DELETIONPOLICY   AGE
csi-rbdplugin-snapclass   rook-ceph.rbd.csi.ceph.com   Delete           31h
[spkr@erdia22 kvdi (ubuns:yelb)]$ k get sc
NAME              PROVISIONER                  RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
rook-ceph-block   rook-ceph.rbd.csi.ceph.com   Delete          Immediate           true                   31h

(Rook-ceph 설치 및 ceph snapshotclass 설정 방법은 다른 포스팅 참조 부탁 드립니다. )

 

사전 필요 사항 확인 이 후 Snapscheduler 설치 하겠습니다. 설치는 Helm 이용하여 간단하게 가능합니다.

[spkr@erdia22 53.snapshot (ubuns:yelb)]$ helm repo add backube https://backube.github.io/helm-charts/
"backube" has been added to your repositories

[spkr@erdia22 53.snapshot (ubuns:yelb)]$ kubectl create namespace backube-snapscheduler
namespace/backube-snapscheduler created

[spkr@erdia22 53.snapshot (ubuns:yelb)]$ kns backube-snapscheduler
Context "ubuns" modified.
Active namespace is "backube-snapscheduler".

(kns는 현재 namespace를 변경하는 tool 입니다. https://jerryljh.tistory.com/17)

[spkr@erdia22 53.snapshot (ubuns:backube-snapscheduler)]$ helm pull backube/snapscheduler

[spkr@erdia22 53.snapshot (ubuns:backube-snapscheduler)]$ tar xvfz snapscheduler-1.3.0.tgz 
snapscheduler/Chart.yaml
snapscheduler/values.yaml
snapscheduler/templates/NOTES.txt
snapscheduler/templates/_helpers.tpl
snapscheduler/templates/deployment.yaml
snapscheduler/templates/role.yaml
snapscheduler/templates/rolebinding.yaml
snapscheduler/templates/serviceaccount.yaml
snapscheduler/.helmignore
snapscheduler/README.md
snapscheduler/crds/snapscheduler.backube_snapshotschedules.yaml
[spkr@erdia22 53.snapshot (ubuns:backube-snapscheduler)]$ mv snapscheduler snapscheduler-1.3.0

저는 항상 Helm 설치 시 Helm 파일을 다운받아 해당 values.yaml 파일을 수정해서 사용합니다. 현재 설정 확인 및 향후 히스토리 관리에 용이 합니다.

[spkr@erdia22 53.snapshot (ubuns:backube-snapscheduler)]$ mv snapscheduler snapscheduler-1.3.0
[spkr@erdia22 53.snapshot (ubuns:backube-snapscheduler)]$ cd snapscheduler-1.3.0/

[spkr@erdia22 snapscheduler-1.3.0 (ubuns:backube-snapscheduler)]$ cp values.yaml my-values.yaml

snapscheduler는 helm values.yaml file 특별한 수정없이 설치 하였습니다. 

 

관련 snapshot scheduler Helm YAML 파일은 아래 github 에서 확인 하실 수 있습니다.

https://github.com/junghoon2/diamanti-k8s-bootcamp/tree/master/53.snapshot/02.snapscheduler-1.3.0

 

GitHub - junghoon2/diamanti-k8s-bootcamp: DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다.

DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다. - GitHub - junghoon2/diamanti-k8s-bootcamp: DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다.

github.com

[spkr@erdia22 snapscheduler-1.3.0 (ubuns:backube-snapscheduler)]$ helm install snapscheduler -f my-values.yaml .
W0716 13:45:22.234650    6085 warnings.go:70] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
W0716 13:45:22.285323    6085 warnings.go:70] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
W0716 13:45:24.301375    6085 warnings.go:70] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
W0716 13:45:26.334598    6085 warnings.go:70] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
W0716 13:45:28.297827    6085 warnings.go:70] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
NAME: snapscheduler
LAST DEPLOYED: Fri Jul 16 13:45:28 2021
NAMESPACE: backube-snapscheduler
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing SnapScheduler!

Chart version: 1.3.0
SnapScheduler version: 1.2.0

The SnapScheduler operator is now installed in the backube-snapscheduler
namespace, and snapshotschedules should be enabled cluster-wide.

See https://backube.github.io/snapscheduler/usage.html to get started.

Schedules can be viewed via:
$ kubectl -n <mynampspace> get snapshotschedules
[spkr@erdia22 snapscheduler-1.3.0 (ubuns:backube-snapscheduler)]$ k get snapshotschedules.snapscheduler.backube 
No resources found in backube-snapscheduler namespace.

정상적으로 pod가 설치가 완료 되었습니다.

[spkr@erdia22 snapscheduler-1.3.0 (ubuns:backube-snapscheduler)]$ k get pod
NAME                             READY   STATUS    RESTARTS   AGE   IP             NODE       NOMINATED NODE   READINESS GATES
snapscheduler-7c9b84466c-9qjqr   1/1     Running   0          30s   10.233.94.14   ubun20-3   <none>           <none>
snapscheduler-7c9b84466c-kcjf7   1/1     Running   0          30s   10.233.94.20   ubun20-3   <none>           <none>

이제 snapshot을 이용할 PVC를 선택합니다. 저는 yelb라는 demo 용 kube application을 사용 하였습니다. 

 

yelb 관련 소스 파일 https://github.com/junghoon2/diamanti-k8s-bootcamp/tree/master/73.DemoPJT/04.yelb

 

GitHub - junghoon2/diamanti-k8s-bootcamp: DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다.

DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다. - GitHub - junghoon2/diamanti-k8s-bootcamp: DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다.

github.com

 

간단히 레스토랑 추천하는 Demo App 입니다.

PVC 테스트를 위하여 원본 Redis 설정에서 redis volume을 PVC를 이용하도록 변경 하였습니다.

[spkr@erdia22 kvdi (ubuns:yelb)]$ k get pvc
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
redis-pvc   Bound    pvc-2fabb3b3-e368-4bd5-bb6b-1fb66eb0b6f2   200Gi      RWO            rook-ceph-block   24h

이제 모든 준비가 되었습니다. 정해진 시간을 snapshot을 생성하고 원하는 Copy만큼 보관하도록 snap scheduler 적용을 합니다.

 

snap schedule 적용을 위해서는 아래의 SnapshotScheduler YAML 파일을 이용합니다.

 

관련 파일

https://github.com/junghoon2/diamanti-k8s-bootcamp/tree/master/53.snapshot/02.snapscheduler-1.3.0

 

GitHub - junghoon2/diamanti-k8s-bootcamp: DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다.

DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다. - GitHub - junghoon2/diamanti-k8s-bootcamp: DIAMANTI 시스템 운영을 위한 DIAMANTI & Kubernetes 실습 자료 입니다.

github.com

apiVersion: snapscheduler.backube/v1
kind: SnapshotSchedule
metadata:
  # The name for this schedule. It is also used as a part
  # of the template for naming the snapshots.
  name: every6hour
  # Schedules are namespaced objects
  namespace: yelb
spec:
  # A LabelSelector to control which PVCs should be snapshotted
  # claimSelector: 
  #   matchLabels:
  #     "app": "yelb-appserver"
  # Set to true to make the schedule inactive
  disabled: false  # optional
  retention:
    # The length of time a given snapshot should be
    # retained, specified in hours. (168h = 1 week)
    expires: "168h"  # optional
    # The maximum number of snapshots per PVC to keep
    maxCount: 4  # optional
  # The cronspec (https://en.wikipedia.org/wiki/Cron#Overview)
  # that defines the schedule. It is interpreted with
  # respect to the UTC timezone. The following pre-defined
  # shortcuts are also supported: @hourly, @daily, @weekly,
  # @monthly, and @yearly
  schedule: "0 0/6 * * *"
  # schedule: '@hourly'
  snapshotTemplate:
    # A set of labels can be added to each
    # VolumeSnapshot object
    # labels:  # optional
    #   mylabel: diamanti
    # The SnapshotClassName to use when creating the
    # snapshots. If omitted, the cluster default will
    # be used.
    snapshotClassName: csi-rbdplugin-snapclass  # optional
    # snapshotClassName: default-snapclass  # optional
  • metadata.name: every6hour
    : 임의의 이름을 정하면 됩니다. 저는 6시간 마다 snapshot 수행하므로 every6hour로 하였습니다.
  • metadata.namespace: yelb, spec.claimSelector.matchLabels
    : namespace와 PVC Claim의 label 이용하여 PVC를 지정 할 수 있습니다. 저는 namespace 전체 PVC에 대하여 snapshot schedule 설정 할 예정이라 matchLabel 부문을 주석 처리 하였습니다.
  • spec.retention.maxCount : 4
    : retention(유지) 말 그대로 snapshot 보관 주기 설정하는 부분입니다. 저는 6시간 씩 4개 copy 저장하여 최대 하루(24h) 저장하도록 하였습니다.
  • spec.schedule: "0 0/6 * * *"
    : cronjob 설정과 동일합니다. 매 6시(0시, 6시, 12시, 18시) 정각에 snapshot을 수행합니다. 유의 사항이 UTC 기준이라 한국 시간과는 9시간 차이 납니다. 

유사한 설정으로 매일 새벽 3시 snapshot 생성하도록 하려면 아래와 같이 설정합니다.

apiVersion: snapscheduler.backube/v1
kind: SnapshotSchedule
metadata:
  name: daily7days
  namespace: yelb
spec:
  disabled: false  # optional
  retention:
    expires: "168h"  # optional
    maxCount: 7  # optional
  schedule: "0 18 * * *"
  snapshotTemplate:
    # labels:  # optional
    #   mylabel: snap
    snapshotClassName: csi-rbdplugin-snapclass  # optional

(동일한 설정이라 설명은 생략 하겠습니다. UTC 기준으로 18시가 한국 시간 03시(+9h) 입니다.)

 

Apply 하시면 snapschedule 정책이 적용 됩니다.

[spkr@erdia22 02.snapscheduler-1.3.0 (ubuns:yelb)]$ k apply -f daily-snapscheduler.yml 
snapshotschedule.snapscheduler.backube/daily7days unchanged
[spkr@erdia22 02.snapscheduler-1.3.0 (ubuns:yelb)]$ k apply -f hourly-snapscheduler.yml 
snapshotschedule.snapscheduler.backube/every6hour unchanged
(전 이미 적용하여 unchanged로 나옵니다.)

이제 적용된 snapshot schedule 확인을 해 보겠습니다. object 이름이 snapshotschedules 입니다. (tap 하시면 자동 완성됩니다.)

[spkr@erdia22 kvdi (ubuns:yelb)]$ k get snapshotschedules.snapscheduler.backube
NAME         SCHEDULE      MAX AGE   MAX NUM   DISABLED   NEXT SNAPSHOT
daily7days   0 18 * * *    168h      7         false      2021-07-22T18:00:00Z
every6hour   0 0/6 * * *   168h      4         false      2021-07-22T06:00:00Z

위와 같이 정상적으로 적용이 되었습니다. 

[spkr@erdia22 kvdi (ubuns:yelb)]$ k get volumesnapshot
NAME                                READYTOUSE   SOURCEPVC   SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS             SNAPSHOTCONTENT                                    CREATIONTIME   AGE
redis-pvc-daily7days-202107211800   true         redis-pvc                           200Gi         csi-rbdplugin-snapclass   snapcontent-24b49063-66bd-4e0c-9d19-6eecee5dd05e   8h
    8h
redis-pvc-every6hour-202107210600   true         redis-pvc                           200Gi         csi-rbdplugin-snapclass   snapcontent-4adffdfd-8b58-4511-8c4f-3915529b7f07   20h            20h
redis-pvc-every6hour-202107211200   true         redis-pvc                           200Gi         csi-rbdplugin-snapclass   snapcontent-4438698e-1d08-43f4-8621-200536844979   14h            14h
redis-pvc-every6hour-202107211800   true         redis-pvc                           200Gi         csi-rbdplugin-snapclass   snapcontent-ace20ac6-c655-4203-acc9-f8a6fcf6a4fa   8h
    8h
redis-pvc-every6hour-202107220000   true         redis-pvc                           200Gi         csi-rbdplugin-snapclass   snapcontent-9f983e3c-5e4c-474e-b06d-a6a33f52c5ec   144m           144m

저는 하루 전에 적용을 하여 위와 같이 하루 경과 후 정상적으로 hourly, daily Snapshot 생성이 되었네요. hourly 기준으로 4개의 copy만 보관하고 이전 snapshot은 삭제가 되었습니다. 

 

참고로 제가 default namespace의 PVC 대상으로 매 5분 간격으로 snapshot 생성하도록 하였는데, 역시 정상적으로 최신 3개의 copy만 보관하고 기존 snapshot 삭제 되었습니다.

[spkr@erdia22 kvdi (ubuns:yelb)]$ k get volumesnapshot -n default
NAME                            READYTOUSE   SOURCEPVC   SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS             SNAPSHOTCONTENT                                    CREATIONTIME   AGE
rbd-pvc-test-min-202107220215   true         rbd-pvc                             1Gi           csi-rbdplugin-snapclass   snapcontent-c7c8b134-5f55-4309-98aa-855ad9021b7a   11m
11m
rbd-pvc-test-min-202107220220   true         rbd-pvc                             1Gi           csi-rbdplugin-snapclass   snapcontent-7ad7bd26-5740-4c4e-a497-8074ad078535   6m9s
6m10s
rbd-pvc-test-min-202107220225   true         rbd-pvc                             1Gi           csi-rbdplugin-snapclass   snapcontent-cb8930a8-9999-476a-b960-32622f147867   70s
70s

이제, 간단히 snapshot 이용한 PVC 복구 검증을 해 보겠습니다. (좀 더 상세한 snapshot PVC 복구 관련은 아래 포스팅 참조 바랍니다. https://jerryljh.tistory.com/40 )

 

Kubernetes Snapshot 백업/복구

Kube 환경에서도 기존 storage 벤더에서 제공하는 snapshot 기능을 사용 가능합니다. kube 환경답게 snapshot도 manifest YAML 파일 형태를 사용합니다. 그럼, 테스트 내역 공유합니다. Test 내역 snapshot 지원 s..

jerryljh.tistory.com

[spkr@erdia22 kvdi (ubuns:yelb)]$ k scale deployment yelb-appserver --replicas=0
deployment.apps/yelb-appserver scaled

[spkr@erdia22 ~ (ubuns:yelb)]$ k delete pvc redis-pvc
persistentvolumeclaim "redis-pvc" deleted

Restore PVC from snapshot  

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # name: mysql-pv-claim  # 기존 PVC 이름과 동일하게 설정
  name: redis-pvc  # 기존 PVC 이름과 동일하게 설정
spec:
  storageClassName: rook-ceph-block  # PVC 복구에 사용할 StorageClass 지정 
  # storageClassName: high  # PVC 복구에 사용할 StorageClass 지정 
  dataSource:
    name: redis-pvc-every6hour-202107210600
    # name: redis-snapshot-50g  # 생성한 snapshot 이름 지정
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 200Gi

snapshot 으로 PVC를 복구 하겠습니다. 

[spkr@erdia22 53.snapshot (ubuns:yelb)]$ k apply -f restorepvc-from-snap.yml 
persistentvolumeclaim/redis-pvc created

[spkr@erdia22 ~ (ubuns:yelb)]$ k get pvc
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
redis-pvc   Bound    pvc-1f72923f-245f-4542-ae03-409f80ae9ede   200Gi      RWO            rook-ceph-block   16s

[spkr@erdia22 kvdi (ubuns:yelb)]$ k scale deployment yelb-appserver --replicas=1
deployment.apps/yelb-appserver scaled

정상적으로 복구된 PVC 기반으로 POD가 재시작 되었으며 웹 브라우저로 서비스 확인도 가능합니다.

[spkr@erdia22 kvdi (ubuns:yelb)]$ kgp
NAME                              READY   STATUS    RESTARTS   AGE   IP             NODE       NOMINATED NODE   READINESS GATES
redis-server-74556bbcb7-sx89q     1/1     Running   0          31h   10.233.66.19   ubun20-2   <none>           <none>
yelb-appserver-5c895ddb7f-whtgf   1/1     Running   0          29s   10.233.66.41   ubun20-2   <none>           <none>
yelb-db-694586cd78-vptmv          1/1     Running   0          31h   10.233.66.20   ubun20-2   <none>           <none>
yelb-ui-8f54fd88c-sgtjd           1/1     Running   0          31h   10.233.66.18   ubun20-2   <none>           <none>

 

App Server ID가 변경되었습니다.

이제 snapshot scheduler 을 이용하여 정기적으로 snapshot 설정이 가능합니다. 

 

다만, 저는 ceph 에서 snapshot이 사용하는 디스크 용량을 확인을 못해서 아쉬웠습니다. snapshot이 사용하는 디스크 용량 확인이 필요한데, 제가 ceph를 잘 몰라서 어디서 해당 내용을 확인해야 하는지 모르겠네요. 아마 상용 스토리지는 쉽게 찾을 수 있도록 관련 정보를 제공 할 것 같습니다. 

[spkr@erdia22 kvdi (ubuns:rook-ceph)]$ k exec -it rook-ceph-tools-656b876c47-9n9t4 -- bash
[root@rook-ceph-tools-656b876c47-9n9t4 /]# ceph status
  cluster:
    id:     0425a9b5-99d1-48c3-9ddf-518b19239569
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum a,b,c (age 31h)
    mgr: a(active, since 31h)
    osd: 6 osds: 6 up (since 31h), 6 in (since 31h)

  data:
    pools:   2 pools, 33 pgs
    objects: 726 objects, 821 MiB
    usage:   8.0 GiB used, 2.9 TiB / 2.9 TiB avail
    pgs:     33 active+clean

  io:
    client:   4.3 KiB/s rd, 13 KiB/s wr, 5 op/s rd, 2 op/s wr

(ceph status 명령로는 snapshot 용량 확인이 안되네요. )

 

이상, snapshot scheduler 소개해 드렸습니다.

 

Diamanti 및 Kubernetes 사업 제휴 및 기술 문의 : leejunghoon@spkr.co.kr 

반응형