본문 바로가기
스터디 이야기/25' AWS EKS

VolumeSnapshot & SnapScheduler로 Kubernetes 볼륨 자동 백업하기

by lakescript 2025. 2. 22.
728x90

 

들어가며

Kubernetess 환경에서 PVC로 Storage를 만들어 관리한다면 백업(스냅샷)을 해야 하는 상황이 발생할 수 있고, 백업을 주기적으로 생성해야 하는 상황이 생길 수도 있는데요. 이를 위해 Kubernetes에서는 VolumeSnapshot을 통해 PVC의 특정 시점 데이터를 백업할 수 있고, SnapScheduler를 사용하면 주기적으로 자동으로 백업할 수도 있습니다.

 

VolumeSnapshot

VolumeSnapshot은 Kubernetes에서 PersistentVolumeClaim(PVC)의 특정 시점의 상태를 캡처하는 기능으로, 이를 통해 데이터를 백업하거나 복구할 수 있습니다. 

 

VolumeSnapshotClass

다양한 스토리지 백엔드에 대한 스냅샷 생성 정책을 정의합니다. 

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: csi-hostpath-snapclass
driver: csi.example.com

 

위와 같이 사용할 CSI 드라이버를 명시해 줍니다. 또한 deletionPolicy을 설정할 수 있는데, Delete라면 VolumeSnapshot을 삭제할 때 같이 삭제되고, Retain이라면 유지됩니다.(기본값은 delete)

VolumeSnapshot

특정 PVC의 스냅샷을 생성하는 리소스입니다.

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: new-snapshot-test
spec:
  volumeSnapshotClassName: csi-hostpath-snapclass
  source:
    persistentVolumeClaimName: pvc-test

 

위에서 생성한 volumeSnapshotClassName을 적고, 어떤 PVC를 snapshot 할 건지 명시해 줍니다.

 

VolumeSnapshotContent

VolumeSnapshotController로 인해 VolumeSnapshotContent가 자동으로 생성되며, 생성되었을 때 적용된 설정이나 상태가 명세되어있습니다.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
  name: snapcontent-72d9a349-aacd-42d2-a240-d775650d2455
spec:
  deletionPolicy: Delete
  driver: hostpath.csi.k8s.io
  source:
    volumeHandle: ee0cfb94-f8d4-11e9-b2d8-0242ac110002
  sourceVolumeMode: Filesystem
  volumeSnapshotClassName: csi-hostpath-snapclass
  volumeSnapshotRef:
    name: new-snapshot-test
    namespace: default
    uid: 72d9a349-aacd-42d2-a240-d775650d2455

 

snapscheduler

https://backube.github.io/snapscheduler/

 

Documentation

Take scheduled snapshots of your Kubernetes persistent volumes.

backube.github.io

 

SnapScheduler는 PV의 스냅샷을 정기적으로 자동 생성하고, 보존 정책을 관리할 수 있도록 도와주는 오픈소스 프로젝트입니다. Cron 표현식을 사용하여 스냅샷 생성 주기를 설정할 수 있고, 최대 보존 개수나 보존 기간과 같은 보존 정책을 설정할 수 있습니다. 

 

apiVersion: snapscheduler.backube/v1
kind: SnapshotSchedule
metadata:
  name: hourly-schedule
  namespace: your-namespace
spec:
  claimSelector:
    matchLabels:
      app: your-app
  schedule: "0 * * * *"  # 매시간 정각에 실행
  retention:
    maxCount: 10  # 최대 10개의 스냅샷 보존
  snapshotTemplate:
    snapshotClassName: your-snapshot-class

 

위와 같이 SnapScheduler yaml 파일을 생성하여 schedue, retention, template 등을 설정하여 정기적으로 snapshot을 생성할 수 있습니다.

 

 

실습

https://lakescript.net/entry/AEWS-3-1-Amazon-EKS-Storage#amazon-ebs

 

[AEWS] 3-1. Amazon EKS - Storage (EBS, EFS)

사전 준비 더보기 위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion E

lakescript.net

해당 실습은 Amazon EBS CSI driver와 gp3 storage class가 설치되었다는 가정하게 진행됩니다.  위의 링크 참고하여서 먼저 설치 및 설정 진행하신 후 실습을 따라와 주세요.

 

설치

VolumeSnapshot, VolumeSnapshotContent, VolumeSnapshotClass는 API가 아닌, CRDs이기 때문에 먼저 CRD를 설치해줘야 합니다.

 

Snapshot CRDs 설치

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml

 

CRD 설치 확인

kubectl get crd | grep snapshot

 

설치 후 crd를 조회해 보겠습니다.

 

kubectl api-resources  | grep snapshot

 

이제 snapshot 관련 api를 사용할 수 있는지 위 명령어를 통해 api resources를 조회해 보겠습니다.

 

volumesnapshotclasses는 vsclass, vsclasses로 축약해서 사용할 수 있고, volumesnapshotcontents는 vsc, vscs로 축약되고 마지막으로 volumesnapts은 vs로 축약해서 사용할 수 있습니다.

 

Snapshot Controller 설치

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml

 

이제 snaptshot controller를 설치하도록 하겠습니다. 

 

Snapshot Controller 설치 확인

kubectl get deploy -n kube-system snapshot-controller

 

kubectl get pod -n kube-system

 

해당 controller는 kube-system에 배포된 것을 확인하실 수 있습니다.

 

 

Snapshotclass 설치

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/examples/kubernetes/snapshot/manifests/classes/snapshotclass.yaml

 

위의 명령어로 snapshotclass를 설치합니다.

 

Snapshotclass 설치 확인

kubectl get volumesnapshotclasses

 

설치 후 volumesnapshotclasses를 조회해 보면 아래와 같이 조회가 되는 것을 확인하실 수 있습니다.

 

kubectl describe vsclass

 

volumesnapshotclass의 명세를 살펴보겠습니다.

 

Deletion Policy가 기본값인 Delete로 설정되어 있고, Driver는 ebs.csi.aws.com 을 사용하고 있는 것을 확인하실 수 있습니다.

 

다른 CSI Driver를 사용해야 한다면?

https://github.com/kubernetes-csi/external-snapshotter

 

GitHub - kubernetes-csi/external-snapshotter: Sidecar container that watches Kubernetes Snapshot CRD objects and triggers Create

Sidecar container that watches Kubernetes Snapshot CRD objects and triggers CreateSnapshot/DeleteSnapshot against a CSI endpoint. - kubernetes-csi/external-snapshotter

github.com

다른 CSI 드라이버를 사용하고 싶은 경우 위의 링크를 참고해서 설치하시면 됩니다.

 

Snapshot 생성

테스트 PVC 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
  storageClassName: gp3

 

VolumeSnapshot 테스트를 위해 PVC를 생성합니다.

 

PVC 생성 확인

kubectl get pvc

 

 

현재는 아직 PVC를 사용하는 Pod가 없기에 Pending 상태인 것을 확인하실 수 있습니다.

 

Pod 생성

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  terminationGracePeriodSeconds: 3
  containers:
  - name: app
    image: centos
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo \$(date -u) >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-claim

 

무한 루프를 돌면서 현재 UTC 시간을 /data/out.txt 파일에 5초마다 기록하는 Pod를 생성하는데, 위에서 생성한 PVC를 연결합니다.

 

pod 생성 확인 및 파일 내용 추가 저장 확인

kubectl get po

 

pod가 정상적으로 배포되었는지 pod 목록을 조회해 보겠습니다.

 

app pod가 정상적으로 실행 중인 것을 확인하실 수 있습니다.

 

kubectl exec app -- tail -f /data/out.txt

 

app pod로 접근하여 /data/out.txt 경로에 파일을 확인해 보겠습니다.

command 실행한 것이 정상적으로 동작하는 것을 확인하실 수 있습니다.

 

AWS EBS Snapshot 조회

volumesnapshot을 생성하기 전에 AWS Console에 접근해서 현재 생성되어 있는 EBS Volumesnapshot이 있는지 확인해 보겠습니다.

현재 아직 생성된 volumesnapshot이 존재하지 않습니다.

 

aws ec2 describe-snapshots --owner-ids self

 

위 명령어로도 현재 생성되어 있는 volumesnapshot을 조회할 수 있습니다.

 

 

마찬가지로 존재하지 않습니다.

 

VolumeSnapshot 생성

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: ebs-volume-snapshot
spec:
  volumeSnapshotClassName: csi-aws-vsc
  source:
    persistentVolumeClaimName: ebs-claim

 

위의 VolumeSnapshot yaml 파일을 생성합니다.

 

kubectl apply -f app-vss.yaml

 

그 후 바로 실행합니다.

 

VolumeSnapshot 확인

kubectl get volumesnapshot, volumesnapshotcontents

 

volumesnapshot과 volumeshotcontent을 조회해 보겠습니다.

 

정상적으로 snapshot이 생성된 것을 확인하실 수 있습니다.

 

 

AWS EBS Snapshot 확인

위에서 확인한 바와 같이 AWS Console에 접근하여 EBS Snapshot을 확인해 보겠습니다.

 

정상적으로 생성된 것을 확인하실 수 있습니다.

 

aws ec2 describe-snapshots --owner-ids self | jq

 

aws cli로도 확인이 가능하니 참고해 주세요!

 

Snapshot으로 복원

Pod 및 PVC 제거

kubectl delete pod app && kubectl delete pvc ebs-claim

 

생성해 놓은 VolumeSnapshot으로 복원해 보기 위해 Pod와 PVC를 제거해 보겠습니다.

 

Pod, PVC, VolumeSnapshot 확인

 

Pod와 PVC는 삭제했기에 현재 아무것도 없고, VolumeSnapshot만 조회되는 것을 확인하실 수 있습니다.

 

PVC 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-snapshot-restored-claim
spec:
  storageClassName: gp3
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
  dataSource:
    apiGroup: snapshot.storage.k8s.io
    kind: VolumeSnapshot
    name: ebs-volume-snapshot

 

dataSource부분에 생성해 놓은 VolumeSnapshot 정보를 적어두면 복원이 가능합니다. 간단하게 apiGroup과 kind, name만 적으면 됩니다.

 

Pod 생성

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  terminationGracePeriodSeconds: 3
  containers:
  - name: app
    image: centos
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo \$(date -u) >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-snapshot-restored-claim

 

위에서 생성했던 pod yaml과는 다르게 새롭게 생성한 PVC 이름(ebs-snapshot-restored-claim)을 적어서 배포합니다.

 

복원된 PVC로부터 이전 파일 내용 유지 및 새로 추가로 저장되는지 확인

kubectl exec app -- tail -f /data/out.txt

 

위의 명령어로 app pod에 접근해서 /data/out.txt 파일을 확인해 보겠습니다.

 

 

복원된 PVC에 저장된 데이터 및 새롭게 복원 후 쓰여진 데이터를 확인하실 수 있습니다.

 

SnapScheduler를 통한 정기적으로 자동 생성

설치

helm repo add backube https://backube.github.io/helm-charts/

 

SnapshotScheduler를 설정하기 위해 설치를 진행합니다. helm을 통해 쉽게 설치할 수 있습니다.

 

kubectl create namespace snapscheduler
helm install -n snapscheduler snapscheduler backube/snapscheduler

 

snapscheduelr를 위한 namespace를 생성한 후 helm을 통해 배포하도록 합니다.

 

 

기존 PVC에 label 부여

 kubectl get pvc --show-labels

 

PVC의 label을 설정해 놓고, snapscheduler에서 해당 label만 선택하여 생성하게 되면 특정 label의 PVC만 정기적으로 자동 생성하게 됩니다. (snapscheduler에서 label을 선택하지 않는다면 namespace 전체의 PVC의 snapshot이 생성되게 됩니다.)

 

먼저 생성되어 있는 PVC에 label 까지조회해 보겠습니다.

 

 

현재 생성되어있는 PVC에는 label이 설정되어있지 않네요.

 

kubectl label pvc ebs-snapshot-restored-claim dedicated=5m

 

위의 명령어를 통해 label을 설정한 후 다시 조회해보겠습니다.

 

설정한 label이 잘 보이는 것을 확인하실 수 있습니다.

 

Sanpscheduler 생성

---
apiVersion: snapscheduler.backube/v1
kind: SnapshotSchedule
metadata:
  name: snapscheduler-5m
  namespace: default
spec:
  retention:
    expires: "720h"
    maxCount: 3
  schedule: "*/3 * * * *"
  claimSelector:
    matchLabels:
      dedicated: 5m
  snapshotTemplate:
    labels:
      environment: dev
    snapshotClassName: csi-aws-vsc

 

위와 같이 간단하게 snapscheduler yaml 파일을 생성해 보도록 하겠습니다. dedicated: 5m이라는 label을 가진 PVC들을 대상으로 진행되며, 생성된 지 720시간이나 3대 이상이 되면 삭제되게 retention 규칙을 설정했고,  environment: dev  라는 label이 붙은 snapshot이 3분마다 생성됩니다.

 

Sanpscheduler 확인

kubectl get snapshotschedules

 

생성된 snapscheduler를 확인해 보겠습니다.

 

 

설정한 대로 잘 생성된 것을 확인하실 수 있습니다. 여기서 다음 snapshot은 언제 생성되는지  NEXT SNAPSHOT  으로 확인하실 수 있습니다. 

 

생성된 snapshot 확인

kubectl get vs

 

설정해 놓은 시간이 지난 후 volumesnapshot을 확인해 보겠습니다.

 

 

snapscheduler을 정기적으로 자동 생성된 snapshot이 존재하는 것을 확인하실 수 있습니다.

 

 

snapshot이 생성되었으니 위와 같이  NEXT SNAPSHOT  의 시간이 변경되었습니다.

 

해당 시간에 snapshot을 확인해 보면 역시 아래와 같이 정상적으로 생성된 것을 확인하실 수 있습니다.

 

 

또한, 설정한 바와 같이 최대 3개 이상으로 생성되지 않습니다. 

 

마지막으로 AWS Console에서도 확인해보면 생성된 EBS Volume Snapshot이 정상적으로 보여지는 것을 확인하실 수 있습니다.

 


참고

https://backube.github.io/snapscheduler/

 

Documentation

Take scheduled snapshots of your Kubernetes persistent volumes.

backube.github.io

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

 

Volume Snapshots

In Kubernetes, a VolumeSnapshot represents a snapshot of a volume on a storage system. This document assumes that you are already familiar with Kubernetes persistent volumes. Introduction Similar to how API resources PersistentVolume and PersistentVolumeCl

kubernetes.io

https://aws.amazon.com/ko/blogs/containers/using-amazon-ebs-snapshots-for-persistent-storage-with-your-amazon-eks-cluster-by-leveraging-add-ons/

 

Using Amazon EBS snapshots for persistent storage with your Amazon EKS cluster by leveraging add-ons | Amazon Web Services

Originally, containers were a great fit for stateless applications. However, for many use cases there is a need for persistent storage, without which stateful workloads aren’t possible. Kubernetes first introduced support for stateful workloads with in-t

aws.amazon.com

 

728x90