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해주었던 내용들이 남아있는 것을 확인할 수 있다.