CSI 스냅샷은 세 가지 객체로 이루어진다.
| 객체 | 범위 | 역할 |
|---|---|---|
VolumeSnapshotClass |
클러스터 | 어느 드라이버로 어떤 정책으로 만들지 정의한다 |
VolumeSnapshot |
네임스페이스 | 사용자가 만드는 요청이다 |
VolumeSnapshotContent |
클러스터 | 스토리지에 실제로 만들어진 스냅샷을 가리킨다 |
CRD 와 snapshot-controller 는 쿠버네티스에 기본 포함되지 않는다. external-snapshotter 를 따로 설치해야 하며, 설치돼 있지 않으면 VolumeSnapshot 을 만들어도 아무 일도 일어나지 않는다.
kubectl get crd | grep snapshot
kubectl get volumesnapshotclass
스냅샷 객체에는 파이널라이저가 붙어, 아직 쓰이는 대상이 먼저 지워지지 않도록 막는다. PV 를 쓰는 PVC 가 있을 때 PV 삭제를 막는 Storage Object in Use Protection 과 같은 방식이다.
snapshot.storage.kubernetes.io/volumesnapshot-as-source-protection — 이 스냅샷을 원본으로 PVC 를 복원하는 중이면 삭제를 보류한다.snapshot.storage.kubernetes.io/volumesnapshot-bound-protection — 연결된 VolumeSnapshotContent 가 있는 동안 삭제를 보류한다.snapshot.storage.kubernetes.io/volumesnapshotcontent-bound-protection — 반대편에서 같은 역할을 한다.삭제 명령은 받아들여지지만 객체는 Terminating 상태로 남아 있다가 조건이 풀리면 실제로 사라진다. "지웠는데 목록에 계속 보인다"는 상황의 대부분이 이것이다.
kubectl get volumesnapshot -A
kubectl get volumesnapshot <이름> -o jsonpath='{.metadata.finalizers}'
kubectl describe volumesnapshot <이름>
VolumeSnapshotClass 의 deletionPolicy 가 실제 데이터의 운명을 정한다.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
driver: rbd.csi.ceph.com
deletionPolicy: Retain
parameters:
clusterID: rook-ceph
Delete 면 VolumeSnapshot 을 지울 때 스토리지의 스냅샷까지 사라진다. Retain 이면 쿠버네티스 객체만 사라지고 스토리지에는 남는다. 백업 목적이라면 Retain 을 쓰고 별도 보존 정책으로 관리한다.
스냅샷을 dataSource 로 지정해 새 PVC 를 만든다. 원본 PVC 를 덮어쓰는 방식은 없다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restored-pvc
spec:
storageClassName: rook-ceph-block
dataSource:
name: daily-snap
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 50Gi
요청 용량은 원본과 같거나 커야 한다. 복원이 끝날 때까지 원본 스냅샷은 파이널라이저 때문에 삭제되지 않는다.
스냅샷은 백업이 아니다. 대부분의 구현이 같은 스토리지 풀 안에 만들어지므로 스토리지가 통째로 망가지면 함께 사라진다. 외부로 내보내는 백업을 따로 둔다.
애플리케이션 정합성은 보장되지 않는다. 데이터베이스라면 스냅샷 전에 체크포인트나 쓰기 정지를 걸어야 한다.
지워지지 않는 스냅샷을 강제로 없애려고 파이널라이저를 직접 제거하면 스토리지 쪽에 고아 스냅샷이 남는다. 원인을 먼저 확인한다.