클러스터에서의 EBS 볼륨 연결과 스냅샷 백업 (feat. EBS CSI Driver)
EBS CSI Driver
kubernetes 클러스터와 AWS EBS 서비스의 연동을 위한 드라이버로, AWS EBS를 Storage로써 사용하기 위해 설치한다.
EKS 클러스터에 PV를 프로비저닝, 마운트 작업을 수행하고, StorageClass를 이용해 EBS 볼륨을 동적으로 생성/삭제(Dynamic Provision)하는 역할을 수행한다.
EBS CSI Driver는 다음과 같은 특성을 가진다.
- 생성한 EBS의 PVC AccessMode는 ReadWriteOnce로 구성
- EBS는 node(EC2)와 1:1로 매핑되는 구성을 갖기에, 동시에 같은 EBS에 접근 불가
- 동시에 여러 액세스가 필요한 상황에서는 EBS가 아닌 EFS를 사용할 수 있다.
- EBS가 위치한 가용영역으로 PV의 nodeAffinity를 설정
- EC2와 마찬가지로 EBS 볼륨은 AZ 종속이기에, 여러 AZ에 걸쳐서 워커노드를 구성한 클러스터에서는 동일한 AZ에 있는 EC2만 PV를 사용할 수 있다.
EBS CSI Driver를 설치하면 EBS API를 호출하는 ebs-csi-controller pod와 ebs-csi-node pod가 daemonset으로 각 node들에 설치된다.
EBS 연결 실습
이번에도 kOps 클러스터에서 실습을 진행해보도록 한다.
kOps를 통해 클러스터를 생성하면 csi-controller와 csi-node가 별도의 add-on없이 자동으로 설치되며, EBS를 사용하기 위한 kops-csi-1-21이라는 이름의 StorageClass 객체도 동시에 생성된다.
csi-controller에는 6개의 컨테이너(provisioner, attacher, snapshotter, resizer, plugin, liveness-probe), csi-node에는 3개의 컨테이너(plugin, node-driver-registrar, liveness-probe)가 구동중인 것도 확인할 수 있다.
PVC 선언 및 EBS 사용
예제로 MySQL deployment에 EBS를 볼륨으로 사용하는 PVC를 생성하고 연결해보도록 한다.
먼저, 앞서 확인한 EBS CSI Driver를 통해 생성된 EBS StorageClass를 이용하는 PVC를 생성한다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
storageClassName: kops-csi-1-21 # EBS SC 지정
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Pending 상태의 PVC가 생성된 것을 볼 수 있다.
이어서 이 PVC를 사용하는 MySQL deployment를 생성한다.
# mysql-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "my-secret-pw" # 실제 환경에서는 Secret 사용
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql # MySQL 데이터 디렉토리
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc # 앞서 생성한 EBS PVC를 볼륨으로 연결
deployment까지 구축하면 StorageClass에 따라 PV가 동적으로 할당된것을 확인할 수 있다.
또한 이 PV의 내용을 살펴보면, EBS 볼륨ID와 nodeAffinity가 설정된 것도 볼 수 있는데, 앞서 살펴본 EBS CSI Driver의 특성에서 보았듯이 AZ에 종속적이기에 PV와 동일한 AZ에 있는 노드만 사용할 수 있도록 Affinity가 붙은 것을 확인할 수 있다.
EBS 볼륨 확장
이 EBS 볼륨은 용량 확장이 가능하다. 하지만 지정된 용량의 미만 값으로 변경은 불가능하다는 것을 알아두어야한다.
(볼륨의 확장은 Controller의 resizer를 통해 이루어진다.)
kubectl patch pvc [pvc name] -p '{"spec": {"resources": {"requests": {"storage": "8Gi"}}}}'
EBS 백업(스냅샷)
이 DB에 값을 적절히 insert한 뒤 DB의 볼륨을 백업해보도록 한다.
EBS의 스냅샷을 생성하기에 앞서, cluster 설정에서 Cert-manager와 snapshot controller add-on을 활성화시켜준다.
# kops edit cluster
spec:
certManager:
enabled: true
snapshotController:
enabled: true
다음으로 VolumeSnapshotClass를 클러스터에 구축 후, EBS PVC를 백업할 VolumeSnapshot을 생성한다.
# ebs-snapshot.yml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: new-snapshot-test
spec:
volumeSnapshotClassName: csi-aws-vsc
source:
persistentVolumeClaimName: mysql-pvc
VolumeSnapshot을 생성하면 EBS 볼륨의 스냅샷이 생성되며, 약간의 대기 후에 스냅샷을 사용할 수 있는 상태가 된다.
이제 이 스냅샷을 통해 복원해보도록한다. 앞서 생성해준 MySQL과 그 PVC를 삭제하여 데이터들이 유실되었다는 상황을 가정해본다.
kubectl delete -f mysql_deployment.yml && kubectl delete -f ebs-snapshot.yml
생성한 스냅샷(VolumeSnapshot)을 dataSource로 지정하여 PVC를 생성한다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc-reclaim
spec:
storageClassName: kops-csi-1-21 # EBS SC 지정
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
dataSource:
kind: VolumeSnapshot # 스냅샷을 dataSource로 하여 '복원'
apiGroup: snapshot.storage.k8s.io
name: new-snapshot-test # VolumeSnapshot의 이름
그리고 MySQL deployment의 볼륨도 스냅샷으로 생성한 PVC로 변경 후 생성해준다.
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc-reclaim # 스냅샷으로 복구한 PVC 지정
스냅샷을 볼륨으로 연결한 DB에 접속해 내용을 확인하면, 앞서 스냅샷 생성 전에 insert해주었던 내용들이 남아있는 것을 확인할 수 있다.