쿠버네티스 일반

Kubernetes Snapshot 백업/복구

Jerry_이정훈 2021. 7. 16. 09:12
728x90

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

 

Test 내역

  • snapshot 지원 storage class 확인
  • snapshot 생성 
  • snapshot 통한 application pvc 복구(mysql) 

흥미로운건 DB 임에도 불구하고 db dump 등의 추가 작업을 하지 않았는데 snapshot으로 복구한 pvc로 정상적으로 DB가 기동된다는 것입니다. (제가 DB에 대하여 잘 몰라서 그런 것 같은데) DB도 파일 시스템에 정상적으로 write만 된 파일만 있으면 정상적으로 복구되는 게 신기 하였습니다.

 

먼저, snapshot을 사용하기 위해서는 storage class가 snapshot을 지원하여야 합니다. 당연하게도 kube는 API를 통해서 명령어를 내리는 것이지 snapshot 자체를 만들지는 않습니다. storage가 snapshot을 생성합니다. 현재 사용 중인 storage가 kube 환경의 snapshot을 지원해야 합니다.

 

kube snapshot 지원하는 스토리지로 저는 오픈소스 rook-ceph를 이용하였습니다. (처음에는 openebs cstor 사용하였는데 어떤 이유인지 모르겠지만 snapshot이 제대로 되지 않았습니다.) ceph 사용하면 disk io 성능이 잘 안 나오는 경우가 많습니다. 충분한 노드와 디스크 수량이 필요합니다. 물론 ceph 최적화 설정도 해야 하는데, 경험이 필요한 영역 입니다. ^^

 

그리고 snapshot을 실제 운영 환경에 사용하려면 자동 snapshot schedule tool(snap scheduler), snapshot 백업 및 복구 시간, 시스템 resource 사용량 등도 확인이 필요한데, 이는 다른 포스팅에서 다루겠습니다. 

 

현재 snapshotclass 확인 

[spkr@erdia22 ~ (ubuns:wordpress-1)]$ k get volumesnapshotclasses.snapshot.storage.k8s.io
NAME                                DRIVER                       DELETIONPOLICY   AGE
csi-cstor-snapshotclass             cstor.csi.openebs.io         Delete           28d
csi-rbdplugin-snapclass             rook-ceph.rbd.csi.ceph.com   Delete           23d
k10-clone-csi-cstor-snapshotclass   cstor.csi.openebs.io         Retain           27d
k10-clone-csi-rbdplugin-snapclass   rook-ceph.rbd.csi.ceph.com   Retain           23d

저는 csi-rdbplugin-snapclass를 이용 예정입니다.

 

snapshot 백업, 복구 검증 Application으로 저는 wordpress 사용합니다. wordpress application이 MySQL를 사용하여 DB 백업/복구 테스트에 적합하였습니다.  

 

wordpress YAML 예제

https://kubernetes.io/ko/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/

 

그럼 백업할 PVC를 먼저 확인해 보겠습니다. 

[spkr@erdia22 ~ (ubuns:wordpress)]$ k get pvc
NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
mysql-pv-claim   Bound    pvc-0a8a1fbb-5806-472f-b601-be1fab7d7521   20Gi       RWO            rook-ceph-block   22h
wp-pv-claim      Bound    pvc-8c96f27c-63c3-4914-8e67-f87092ed6e6e   20Gi       RWO            rook-ceph-block   22h

mysql에서 사용하는 mysql-pv-claim 대상으로 snapshot 백업, 복구 예정입니다. 

 

Snapshot YAML 

create-snapshot.yml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: mysql-snapshot
spec:
  volumeSnapshotClassName: csi-rbdplugin-snapclass  # snapshot class 지정
  source:
    persistentVolumeClaimName: mysql-pv-claim  # 백업 대상 PVC 지정

[spkr@erdia22 53.snapshot (ubuns:wordpress)]$ k apply -f create-snapshot.yml 
volumesnapshot.snapshot.storage.k8s.io/mysql-snapshot created

YAML 파일 자체는 아주 단순합니다. 원하는 PVC와 snapshot class만 지정하면 됩니다. 

 

이제 생성된 snapshot을 확인합니다.

[spkr@erdia22 53.snapshot (ubuns:wordpress-1)]$ k get volumesnapshot
NAME             READYTOUSE   SOURCEPVC        SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS             SNAPSHOTCONTENT                                    CREATIONTIME   AGE
mysql-snapshot   true         mysql-pv-claim                           20Gi          csi-rbdplugin-snapclass   snapcontent-5cfa7665-5faa-4fde-8b62-b53ea3e2f111   15m            15m

정상적으로 snapshot이 생성되었습니다. 

 

그럼, PVC 복구 전 해당 POD와 PVC를 삭제하겠습니다. PVC 삭제를 하기 위해서 POD 삭제가 필요하므로 POD까지 같이 삭제(--replicas=0) 합니다.

[spkr@erdia22 53.snapshot (ubuns:wordpress)]$ k scale deployment wordpress-mysql --replicas=0
deployment.apps/wordpress-mysql scaled

[spkr@erdia22 53.snapshot (ubuns:wordpress)]$ k delete pvc mysql-pv-claim 
persistentvolumeclaim "mysql-pv-claim" deleted

[spkr@erdia22 53.snapshot (ubuns:wordpress)]$ k get pod,pvc
NAME                             READY   STATUS    RESTARTS   AGE
pod/wordpress-5994d99f46-xg4dr   1/1     Running   0          22h

NAME                                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
persistentvolumeclaim/wp-pv-claim   Bound    pvc-8c96f27c-63c3-4914-8e67-f87092ed6e6e   20Gi       RWO            rook-ceph-block   22h

DB가 다운되어 당연히 wordpress 사이트도 접속되지 않습니다.

snapshot으로 PVC를 복구하기 위해서는 PVC 생성 시 옵션으로 해당 snapshot을 지정하여 PVC를 생성이 가능합니다. 

 

그럼 YAML 파일을 이용하여 snapshot으로 PVC를 복구 하겠습니다. 

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

[spkr@erdia22 53.snapshot (ubuns:wordpress)]$ k apply -f pvc-from-snap.yml 
persistentvolumeclaim/mysql-pv-claim created
  • metadata.name : 기존 PVC 이름과 동일하게 맞추어 줍니다.
  • spec.storageClassName: 생성되는 PVC가 할당되는 storageClass 이름 입니다.
  • spec.dataSource.name: 이전에 생성한 snapshot 이름 입니다. 

PVC가 정상적으로 생성되었습니다. 

[spkr@erdia22 53.snapshot (ubuns:wordpress)]$ k get pvc
NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
mysql-pv-claim   Bound    pvc-a0b7ebb7-ad15-46f2-abb6-018c47be1bc7   20Gi       RWO            rook-ceph-block   1s
wp-pv-claim      Bound    pvc-8c96f27c-63c3-4914-8e67-f87092ed6e6e   20Gi       RWO            rook-ceph-block   22h

물론 기존 PVC와 동일한 이름이 아닌 다른 이름으로도 PVC 생성도 가능합니다. 이 경우 MySQL POD를 별도로 하나 더 만들어서 DB 파일 검증 용도 또는 새로운 application으로도 만들 수 있습니다. 

 

이제 기존 MySQL POD를 다시 재기동합니다.

[spkr@erdia22 53.snapshot (ubuns:wordpress)]$ k scale deployment wordpress-mysql --replicas=1
deployment.apps/wordpress-mysql scaled

[spkr@erdia22 ~ (ubuns:wordpress-1)]$ kgpw
NAME                              READY   STATUS              RESTARTS   AGE     IP              NODE       NOMINATED NODE   READINESS GATES
wordpress-5994d99f46-nf98z        1/1     Running             0          3m54s   10.233.94.228   ubun20-3   <none>           <none>
wordpress-mysql-6c479567b-nvw9v   0/1     ContainerCreating   0          3s      <none>          ubun20-3   <none>           <none>
wordpress-mysql-6c479567b-nvw9v   0/1     ContainerCreating   0          10s     <none>          ubun20-3   <none>           <none>
wordpress-mysql-6c479567b-nvw9v   1/1     Running             0          11s     10.233.94.230   ubun20-3   <none>           <none>

데이터가 작아서 비교적 빠른 11s 만에 복구가 되었습니다. snapshot 기반이라 데이터가 크다가 하여도 복구가 당연히 빠르기도 합니다. 

 

사이트도 정상적으로 복구되었습니다.  

(블로그 작성하는 시간이 지나서 ^^ 기존 wordpress application를 삭제하여 새로운 wordpress 사이트를 생성하여 기존 사이트와 이름이 다릅니다. snapshot 문제는 아닙니다.)

 

이렇게 snapshot을 사용하면 사용자 실수 등으로 인한 문제 발생 시 데이터 복구가 가능합니다. (다시 한 번 DB 임에도 db dump 없이 복구 된다는 건 신기합니다.) 

 

실제 운영 환경에서 사용하려면 매일 혹은 매주 schedule snapshot 을 생성하는 기능이 필요합니다. 다행스럽게 gemini 라는 오픈소스가 있습니다. 그리고 스토리지 이중화를 위하여 snapshot으로 생성한 PVC를 외부 스토리지(NAS 혹은 S3 등 object 스토리지)로 저장도 필요합니다.

 

이건 다른 포스팅에서 다루도록 하겠습니다.

 

참조: https://kubernetes.io/ko/docs/concepts/storage/volume-snapshots/

 

볼륨 스냅샷

쿠버네티스에서 스토리지 시스템 볼륨 스냅샷은 VolumeSnapshot 을 나타낸다. 이 문서는 이미 쿠버네티스 퍼시스턴트 볼륨에 대해 잘 알고 있다고 가정한다. 소개 API 리소스 PersistentVolume 및 PersistentV

kubernetes.io

 

반응형