목차
1. Amazon EBS CSI Driver 설치
    1.1. 1.1. Amazon EBS CSI Driver 설치 및 IRSA 생성
    1.2. Amazon EBS CSI Driver 설치 확인
2. Amazon EBS CSI Driver의 정적 프로비저닝 구성
    2.1. EBS 볼륨 생성
    2.2. 정적 프로비저닝 구성 - PV, PVC, 파드 생성 및 확인
    2.3. 데이터 유지 확인
3. Amazon EBS CSI Driver의 동적 프로비저닝 구성
    3.1. 동적 프로비저닝 구성 - StorageClass, PVC, 파드 생성 및 확인
    3.2. 정보 확인
    3.3. 볼륨 사이즈 증가
4. Amazon Volume Snapshot Controller 구성
    4.1. Amazon Volume Snapshot Controller 설치
    4.2. 동적 프로비저닝 환경 재구성
    4.3. EBS 볼륨 스냅샷 생성 및 확인
    4.4. EBS 볼륨 스냅샷 복원


1. Amazon EBS CSI Driver 설치


이번 실습은 3장 Amazon EKS 원클릭 배포 환경에서 진행합니다.
인프라 배포를 진행하지 않은 경우 링크를 통해 배포 후 복귀 바랍니다.
그리고 새롭게 인프라를 배포하면 아래 기본 설정 명령을 입력 후 진행 바랍니다.

기본 설정 명령어


Default 네임 스페이스 변경

1
kubectl ns default


워커 노드의 IP 변수 선언

1
2
3
4
5
6
7
8
9
10
11
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})

N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})

N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})

echo "export N1=$N1" >> /etc/profile

echo "export N2=$N2" >> /etc/profile

echo "export N3=$N3" >> /etc/profile


노드에 Tool 설치

1
2
3
4
5
ssh ec2-user@$N1 sudo yum install links tree jq tcpdump sysstat -y

ssh ec2-user@$N2 sudo yum install links tree jq tcpdump sysstat -y

ssh ec2-user@$N3 sudo yum install links tree jq tcpdump sysstat -y


EFS 마운트 확인

1
2
3
4
5
6
df -hT --type nfs4

// 만약 마운트가 되지 않는다면.. 수동으로 마운트
EFS_ID=$(aws efs describe-file-systems --query "FileSystems[?Name=='myeks-EFS'].[FileSystemId]" --output text); echo $EFS_ID

mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport $EFS_ID.efs.ap-northeast-2.amazonaws.com:/ /mnt/myefs


AWS Load Balancer Controller 설치

1
2
3
4
5
6
7
helm repo add eks https://aws.github.io/eks-charts

helm repo update

helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller


ExternalDNS 설치

1
2
3
4
5
6
7
8
9
10
// 자신의 도메인 주소로 설정
MyDomain=<자신의 도메인>

MyDnsHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)

echo $MyDomain, $MyDnsHostedZoneId

curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/externaldns.yaml

MyDomain=$MyDomain MyDnsHostedZoneId=$MyDnsHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -


kube-ops-view 설치

1
2
3
4
5
6
7
8
9
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/

helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system

kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'

kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"

echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"



1.1. Amazon EBS CSI Driver 설치 및 IRSA 생성

Amazon EBS CSI Driver의 권한을 위임하기 위한 인증 절차로 IRSA 구성을 선행하고 Amazon EBS CSI Driver를 설치합니다.


Amazon EBS CSI Driver 버전 정보

1
2
3
4
5
6
// Amazon EBS CSI Driver 버전 정보 (True = 기본 설치 버전)
aws eks describe-addon-versions \
    --addon-name aws-ebs-csi-driver \
    --kubernetes-version 1.26 \
    --query "addons[].addonVersions[].[addonVersion, compatibilities[].defaultVersion]" \
    --output text


IRSA 생성

1
2
3
4
5
6
7
8
9
10
11
12
// AWS 관리형 IAM Policy인 AmazonEBSCSIDriverPolicy 사용
eksctl create iamserviceaccount \
  --name ebs-csi-controller-sa \
  --namespace kube-system \
  --cluster ${CLUSTER_NAME} \
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
  --approve \
  --role-only \
  --role-name AmazonEKS_EBS_CSI_DriverRole

// IRSA 확인
eksctl get iamserviceaccount --cluster ${CLUSTER_NAME}


Amazon EBS CSI Driver Add-On 설치

1
2
3
4
eksctl create addon --name aws-ebs-csi-driver\
 --cluster ${CLUSTER_NAME}\
 --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EBS_CSI_DriverRole\
 --force



1.2. Amazon EBS CSI Driver 설치 확인


Amazon EKS 클러스터 Add-On 확인

1
eksctl get addon --cluster ${CLUSTER_NAME}


Amazon EBS CSI Driver의 컨테이너 확인

1
2
3
4
5
// ebs-csi-controller 파드에 컨테이너 확인
kubectl get pod -n kube-system -l app=ebs-csi-controller -o jsonpath='{.items[0].spec.containers[*].name}' ; echo

// ebs-csi-node 데몬셋에 컨테이너 확인
kubectl get daemonset -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver -o jsonpath='{.items[0].spec.template.spec.containers[*].name}' ; echo


csinode 확인

1
kubectl get csinodes




2. Amazon EBS CSI Driver의 정적 프로비저닝 구성


Amazon EBS CSI Driver 환경에서 정적 프로비저닝을 구성합니다.


2.1. EBS 볼륨 생성


EBS 볼륨 수동 생성

1
2
3
4
5
6
7
8
9
10
11
12
// EBS 볼륨 생성 - 가용 영역: ap-northeast-2c
aws ec2 create-volume \
  --size 5 \
  --availability-zone ap-northeast-2c \
  --volume-type gp3 \
  --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=static-ebs-vol}]'

// EBS 볼륨 ID 변수 선언
EBS_ID=$(aws ec2 describe-volumes --query "Volumes[?Tags[?Value=='static-ebs-vol']].[VolumeId]" --output text); echo $EBS_ID

// 생성된 EBS 볼륨 확인
aws ec2 describe-volumes --volume-ids $EBS_ID | jq


신규 터미널 - 모니터링

1
2
// 신규 터미널 생성 및 접속 - pod, pv, pvc 모니터링
watch -d kubectl get pod,pv,pvc


2.2. 정적 프로비저닝 구성 - PV, PVC, 파드 생성 및 확인


정적 프로비저닝 - PV 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_sp_pv.yaml

cat ebs_sp_pv.yaml | yh

// EBS 볼륨 ID 치환
sed -i "s/vol-01234567890123456/$EBS_ID/g" ebs_sp_pv.yaml; cat ebs_sp_pv.yaml | yh

// PV 생성
kubectl apply -f ebs_sp_pv.yaml

// PV 정보 확인
kubectl describe pv | yh


정적 프로비저닝 - PVC 생성

1
2
3
4
5
6
7
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_sp_pvc.yaml

cat ebs_sp_pvc.yaml | yh

// PVC 생성
kubectl apply -f ebs_sp_pvc.yaml


정적 프로비저닝 - 파드 생성

1
2
3
4
5
6
7
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_sp_pod.yaml

cat ebs_sp_pod.yaml | yh

// 파드 생성
kubectl apply -f ebs_sp_pod.yaml


볼륨 정보 확인

1
2
3
4
5
6
7
8
// VolumeAttachment 확인
kubectl get VolumeAttachment

// 파드에서 마운트 대상의 디스크 사용 확인
kubectl exec -it ebs-sp-app -- sh -c 'df -hT --type=ext4'

// 클러스터 내 PV의 디스크 사용 확인 (krew tool)
kubectl df-pv


2.3. 데이터 유지 확인


파드에서 데이터 확인

1
2
// 파드에서 out.txt 파일 확인
kubectl exec ebs-sp-app -- tail -f /data/out.txt


컨테이너 프로세스 재시작 후 확인

1
2
3
4
5
// 컨테이너 프로세스 강제 종료 후 재시작
kubectl exec ebs-sp-app -c app -- kill -s SIGINT 1

// 파드에서 out.txt 파일 확인
kubectl exec ebs-sp-app -- tail -f /data/out.txt


파드 재생성 후 확인

1
2
3
4
5
6
7
8
9
// 파드 삭제 후 생성
kubectl delete pod ebs-sp-app

kubectl apply -f ebs_sp_pod.yaml

// 파드에서 out.txt 파일 확인
kubectl exec ebs-sp-app -- head /data/out.txt

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


실습 종료 후 자원 삭제

1
2
3
4
5
6
7
8
9
10
11
12
13
// 파드 삭제
kubectl delete pod ebs-sp-app

// PVC 삭제
kubectl delete pvc ebs-sp-claim

// PV 삭제
kubectl delete pv ebs-sp-pv

// 수동으로 생성한 EBS 볼륨 삭제 후 확인
aws ec2 delete-volume --volume-id $EBS_ID

aws ec2 describe-volumes --volume-ids $EBS_ID | jq

Note: PVC를 삭제하면 PV는 Released 상태로 전환되는데 현재 볼륨을 보존한 상태로 사용 가능한 상태가 아닙니다. 즉, PVC를 다시 생성해도 해당 PV를 사용할 수 없는 것으로 PV 상태를 강제로 Available 상태로 전환시켜야 합니다.
kubectl patch pv ebs-sp-pv -p ‘{“spec”:{“claimRef”: null}}’




3. Amazon EBS CSI Driver의 동적 프로비저닝 구성


Amazon EBS CSI Driver 환경에서 동적 프로비저닝을 구성합니다.


3.1. 동적 프로비저닝 구성 - StorageClass, PVC, 파드 생성 및 확인


신규 터미널 - 모니터링

1
2
3
4
5
// 신규 터미널 1 - pod, pv, pvc, sc 모니터링
watch -d kubectl get pod,pv,pvc,sc

// 신규 터미널 2 - 동적 프로비저닝으로 생성되는 EBS 볼륨 확인
while true; do aws ec2 describe-volumes --filters Name=tag:ebs.csi.aws.com/cluster,Values=true --query "Volumes[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}" --output text; date; sleep 1; done


StorageClass 생성

1
2
3
4
5
6
7
8
9
10
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_dp_sc.yaml

cat ebs_dp_sc.yaml | yh

// StorageClass 생성
kubectl apply -f ebs_dp_sc.yaml

// StorageClass 확인
kubectl describe sc ebs-dp-sc


PVC 생성

1
2
3
4
5
6
7
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_dp_pvc.yaml

cat ebs_dp_pvc.yaml | yh

// PVC 생성
kubectl apply -f ebs_dp_pvc.yaml


파드 생성

1
2
3
4
5
6
7
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_dp_pod.yaml

cat ebs_dp_pod.yaml | yh

// 파드 생성
kubectl apply -f ebs_dp_pod.yaml


3.2. 정보 확인


ebs-csi-controller의 provisioner 로그 확인

1
2
3
4
5
6
7
8
9
10
11
kubectl get pod -n kube-system

// ebs-csi-controller 이름 변수 선언
CSI_CTR_1=$(kubectl get pod -n kube-system -l app=ebs-csi-controller -o jsonpath='{.items[0].metadata.name}') ; echo $CSI_CTR_1

CSI_CTR_2=$(kubectl get pod -n kube-system -l app=ebs-csi-controller -o jsonpath='{.items[1].metadata.name}') ; echo $CSI_CTR_2

// ebs-csi-controller의 provisioner 로그 확인 (Primary ebs-csi-controller 대상에서 확인)
kubectl logs $CSI_CTR_1 -n kube-system -c csi-provisioner --tail 10
or
kubectl logs $CSI_CTR_2 -n kube-system -c csi-provisioner --tail 10


PV 확인

1
kubectl describe pv | yh


ebs-csi-controller의 attacher 로그 확인

1
2
3
4
// ebs-csi-controller의 attacher 로그 확인 (Primary ebs-csi-controller 대상에서 확인)
kubectl logs $CSI_CTR_1 -n kube-system -c csi-attacher --tail 10
or
kubectl logs $CSI_CTR_2 -n kube-system -c csi-attacher --tail 10


볼륨 확인

1
2
3
4
5
6
7
8
9
10
11
// VolumeAttachment 확인
kubectl get VolumeAttachment

// 동적으로 추가된 EBS 볼륨 상세 정보 확인 
aws ec2 describe-volumes --volume-ids $(kubectl get pv -o jsonpath="{.items[0].spec.csi.volumeHandle}") | jq

// 파드에서 마운트 대상의 디스크 사용 확인
kubectl exec -it ebs-dp-app -- sh -c 'df -hT --type=ext4'

// 클러스터 내 PV의 디스크 사용 확인 (krew tool)
kubectl df-pv


파드에서 데이터 확인

1
2
// 파드에서 out.txt 파일 확인
kubectl exec ebs-dp-app -- tail -f /data/out.txt


3.3. 볼륨 사이즈 증가


스토리지 용량 증가

1
2
3
4
5
// pvc에 정의된 스토리지 용량
kubectl get pvc ebs-dp-claim -o jsonpath={.status.capacity.storage} ; echo

// pvc에 정의된 스토리지 용량을 증가 (4Gi -> 10Gi)
kubectl patch pvc ebs-dp-claim -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}'


정보 확인

1
2
3
4
5
// 파드에서 마운트 대상의 디스크 사용 확인
kubectl exec -it ebs-dp-app -- sh -c 'df -hT --type=ext4'

// 클러스터 내 PV의 디스크 사용 확인 (krew tool)
kubectl df-pv


ebs-csi-controller의 resizer 로그 확인

1
2
3
4
// ebs-csi-controller의 resizer 로그 확인 (Primary ebs-csi-controller 대상에서 확인)
kubectl logs $CSI_CTR_1 -n kube-system -c csi-resizer --tail 10
or
kubectl logs $CSI_CTR_2 -n kube-system -c csi-resizer --tail 10


실습 종료 후 자원 삭제

1
2
3
4
5
6
7
8
// 파드 삭제
kubectl delete pod ebs-dp-app

// PVC 삭제
kubectl delete pvc ebs-dp-claim

// StorageClass 삭제
kubectl delete sc ebs-dp-sc




4. Amazon Volume Snapshot Controller 구성


Amazon EBS CSI Driver 환경에서 Amazon Volume Snapshot Controller를 구성합니다.


4.1. Amazon Volume Snapshot Controller 설치


external-snapshotter CRDs 설치 및 확인

1
2
3
4
5
6
7
8
9
10
11
12
// external-snapshotter CRDs 다운로드
curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml

curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml

curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml

// external-snapshotter CRDs 설치
kubectl apply -f snapshot.storage.k8s.io_volumesnapshots.yaml,snapshot.storage.k8s.io_volumesnapshotclasses.yaml,snapshot.storage.k8s.io_volumesnapshotcontents.yaml

// external-snapshotter CRDs 확인
kubectl get crd | grep snapshot


snapshot-controller 설치 및 확인

1
2
3
4
5
6
7
8
9
10
11
12
// snapshot-controller 다운로드
curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml

curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml

// snapshot-controller 설치
kubectl apply -f rbac-snapshot-controller.yaml,setup-snapshot-controller.yaml

// snapshot-controller 확인
kubectl get deploy -n kube-system snapshot-controller

kubectl get pod -n kube-system -l app=snapshot-controller


VolumeSnapshotClass 생성

1
2
3
4
5
6
7
8
9
10
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/examples/kubernetes/snapshot/manifests/classes/snapshotclass.yaml

cat snapshotclass.yaml | yh

// VolmeSnapshotClass 생성
kubectl apply -f snapshotclass.yaml

// VolmeSnapshotClass 확인
kubectl get vsclass


4.2. 동적 프로비저닝 환경 재구성


StorageClass, PVC, 파드 생성

1
2
3
4
5
kubectl apply -f ebs_dp_sc.yaml

kubectl apply -f ebs_dp_pvc.yaml

kubectl apply -f ebs_dp_pod.yaml


파드에서 데이터 확인

1
2
// 파드에서 out.txt 파일 확인
kubectl exec ebs-dp-app -- tail -f /data/out.txt


4.3. EBS 볼륨 스냅샷 생성 및 확인


VolumeSnapshot 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_vol_snapshot.yaml

cat ebs_vol_snapshot.yaml | yh

// VolmeSnapshot 생성
kubectl apply -f ebs_vol_snapshot.yaml

// VolumeSnapshot 확인
kubectl get volumesnapshot

kubectl get volumesnapshotcontents

// VolumeSnapshot ID 확인
kubectl get volumesnapshotcontents -o jsonpath='{.items[*].status.snapshotHandle}' ; echo


강제로 장애 재현

1
2
// 파드와 PVC 강제 삭제
kubectl delete pod ebs-dp-app && kubectl delete pvc ebs-dp-claim


4.4. EBS 볼륨 스냅샷 복원


PVC 생성 - 스냅샷 복원 설정

1
2
3
4
5
6
7
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_snapshot_restore_pvc.yaml

cat ebs_snapshot_restore_pvc.yaml | yh

// PVC 생성 (restore)
kubectl apply -f ebs_snapshot_restore_pvc.yaml


파드 생성 - 스냅샷 복원 PVC 설정

1
2
3
4
5
6
7
// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/ebs_snapshot_restore_pod.yaml

cat ebs_snapshot_restore_pod.yaml | yh

// 파드 생성 (restore)
kubectl apply -f ebs_snapshot_restore_pod.yaml


파드에서 데이터 확인

1
2
// 파드에서 out.txt 파일 확인
kubectl exec ebs-dp-app -- tail -f /data/out.txt


ebs-csi-controller의 snapshotter 로그 확인

1
2
3
4
// ebs-csi-controller의 snapshotter 로그 확인 (Primary ebs-csi-controller 대상에서 확인)
kubectl logs $CSI_CTR_1 -n kube-system -c csi-snapshotter --tail 10
or
kubectl logs $CSI_CTR_2 -n kube-system -c csi-snapshotter --tail 10


실습 종료 후 자원 삭제

1
2
// 파드, PVC, StorageClass, VolumeSnapshot 삭제
kubectl delete pod ebs-dp-app && kubectl delete pvc ebs-snapshot-restored-claim && kubectl delete sc ebs-dp-sc && kubectl delete volumesnapshots ebs-volume-snapshot


Warning: 다음 섹션의 실습을 이어서 진행할 것으로 Amazon EKS 원클릭 배포를 유지합니다. 혹시나 다음 섹션을 진행하지 않을 경우 3장 Amazon EKS 원클릭 배포를 삭제해 주길 바랍니다.



여기까지 3장의 Amazon EBS CSI Driver 실습을 마칩니다.
수고하셨습니다 :)