AEWS 스터디에서는 AWS의 관리형 Kubernetes인 Elastic Kubernetes의 다양한 기능들을 실습해보면서 익혀본다. 이 글은 스터디를 참여하면서 학습한 내용을 정리하는 연재 글이다. 스터디 진도에 맞춰 글을 작성한다.
이 글에서는 EKS AWS - EBS Controller에 대해서 알아본다.
1. AWS EBS Controller?
EBS CSI driver는 AWS 자원인 EBS 볼륨을 생성하고, 파드에 생성한 볼륨을 연결해준다. CSI-Controller는 AWS API를 호출해서 AWS 스토리지를 관리한다. CSI-Node는 kubelet에서의 마운트요청을 받아 pod에 AWS의 스토리지를 연결해준다.
accessModes를 ReadWriteOnce로 해야하는 이유는 EBS는 블록 스토리지라서 한개의 노드만 연결이 가능하기 때문이다. 그리고 EBS스토리지 기본 설정은 동일 AZ에 있는 EC2 인스턴스만 연결 된다.
2. Amazon EBS CSI driver 설치하기 (Amazon EKS add-on)
쿠버네티스에는 SA가 생성되고, AWS에는 IAM 역할이 생성된다. iam serviceaccount로 확인해 보면 LB controller, csi controller IRSA와 Role이 확인 된다. eksctl 명령어로 aws-ebs-csi-driver를 EKS에 addon으로 설치하면, ebs-csi-controller 파드에 6개 컨테이너 확인 할 수 있다.
- IRSA란?
IRSA는 IAM Role for Service Account의 약자 입니다. 풀네임에서 볼 수 있듯이 kubernetes의 serviceaccount를 사용하여 pod의 권한을 IAM Role로 제어할 수 있도록 하는 기능을 말합니다. serviceaccount는 AWS의 자원이 아닌데 어떻게 IAM Role을 할당할 수 있는 걸까요? 이걸 해주는게 바로 OIDC라고 부르는 OpenID Connect 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# 아래는 aws-ebs-csi-driver 전체 버전 정보와 기본 설치 버전(True) 정보 확인
aws eks describe-addon-versions \
--addon-name aws-ebs-csi-driver \
--kubernetes-version 1.24 \
--query "addons[].addonVersions[].[addonVersion, compatibilities[].defaultVersion]" \
--output text
v1.18.0-eksbuild.1
Tru
v1.17.0-eksbuild.1
False
...
# ISRA 설정 : AWS관리형 정책 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
# ISRA 확인
kubectl get sa -n kube-system ebs-csi-controller-sa -o yaml | head -5
eksctl get iamserviceaccount --cluster myeks
NAMESPACE NAME ROLE ARN
kube-system aws-load-balancer-controller arn:aws:iam::991354587926:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-PEOPA8V0D4TO
kube-system ebs-csi-controller-sa arn:aws:iam::991354587926:role/AmazonEKS_EBS_CSI_DriverRole
...
# Amazon EBS CSI driver addon 추가
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
# 확인
eksctl get addon --cluster ${CLUSTER_NAME}
kubectl get deploy,ds -l=app.kubernetes.io/name=aws-ebs-csi-driver -n kube-system
kubectl get pod -n kube-system -l 'app in (ebs-csi-controller,ebs-csi-node)'
kubectl get pod -n kube-system -l app.kubernetes.io/component=csi-driver
# ebs-csi-controller 파드에 6개 컨테이너 확인
kubectl get pod -n kube-system -l app=ebs-csi-controller -o jsonpath='{.items[0].spec.containers[*].name}' ; echo
ebs-plugin csi-provisioner csi-attacher csi-snapshotter csi-resizer liveness-probe
# csinodes 확인
kubectl get csinodes
# gp3 스토리지 클래스 생성
kubectl get sc
cat <<EOT > gp3-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp3
allowVolumeExpansion: true
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
allowAutoIOPSPerGBIncrease: 'true'
encrypted: 'true'
#fsType: ext4 # 기본값이 ext4 이며 xfs 등 변경 가능 >> 단 스냅샷 경우 ext4를 기본으로하여 동작하여 xfs 사용 시 문제가 될 수 있음 - 테스트해보자
EOT
kubectl apply -f gp3-sc.yaml
kubectl get sc
kubectl describe sc gp3 | grep Parameters
|
cs |
기본 스토리지클래스에서 allowVolumeExpansion 필드가 true로 설정된 경우 볼륨 확장을 지원한다. 추가된 파라미터를 확인 해보면 encrypted (암호화) allowAutoIOPSPerGBIncrease (IOPS범위에 맞도록 볼륨 자동확장)이 들어가 있다.
3. PVC/PV 파드 테스트
EBS 볼륨의 VolumeId, VolumeType, InstanceId 확인해본다.
1
2
3
4
5
6
7
8
9
10
11
12
|
# 워커노드의 EBS 볼륨 확인 : tag(키/값) 필터링 - 링크
aws ec2 describe-volumes --filters Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node --output table
aws ec2 describe-volumes --filters Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node --query "Volumes[*].Attachments" | jq
aws ec2 describe-volumes --filters Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node --query "Volumes[*].{ID:VolumeId,Tag:Tags}" | jq
aws ec2 describe-volumes --filters Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node --query "Volumes[].[VolumeId, VolumeType, Attachments[].[InstanceId, State][]][]" | jq
aws ec2 describe-volumes --filters Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node --query "Volumes[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}" | jq
# 워커노드에서 파드에 추가한 EBS 볼륨 확인
aws ec2 describe-volumes --filters Name=tag:ebs.csi.aws.com/cluster,Values=true --output table
aws ec2 describe-volumes --filters Name=tag:ebs.csi.aws.com/cluster,Values=true --query "Volumes[*].{ID:VolumeId,Tag:Tags}" | jq
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}" | jq
|
cs |
PVC, Pod 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# PVC 생성
cat <<EOT > awsebs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
storageClassName: gp3
EOT
kubectl apply -f awsebs-pvc.yaml
kubectl get pvc,pv
# 파드 생성
cat <<EOT > awsebs-pod.yaml
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
EOT
kubectl apply -f awsebs-pod.yaml
# PVC, 파드 확인
kubectl get pvc,pv,pod
kubectl get VolumeAttachment
# 추가된 EBS 볼륨 상세 정보 확인
aws ec2 describe-volumes --volume-ids $(kubectl get pv -o jsonpath="{.items[0].spec.csi.volumeHandle}") | jq
# PV 상세 확인 : nodeAffinity 내용의 의미는?
kubectl get pv -o yaml | yh
...
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.ebs.csi.aws.com/zone
operator: In
values:
- ap-northeast-2b
...
kubectl get node --label-columns=topology.ebs.csi.aws.com/zone,topology.kubernetes.io/zone
kubectl describe node | more
# 파일 내용 추가 저장 확인
kubectl exec app -- tail -f /data/out.txt
# 아래 명령어는 확인까지 다소 시간이 소요됨
kubectl df-pv
## 파드 내에서 볼륨 정보 확인
kubectl exec -it app -- sh -c 'df -hT --type=overlay'
kubectl exec -it app -- sh -c 'df -hT --type=ext4'
Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme1n1 ext4 3.9G 16M 3.8G 1% /data
|
cs |
미리 볼륨과 연결되어 Bound 상태로 변한 PVC를 확인 할 수 있다. kubectl df-pv 툴은 현재 파드가 쓰는 PV 정보를 잘 보여준다. 사이즈, 사용 용량 등을 한번에 확인 할 수있다.
볼륨 증가
볼륨 증가를 지원하지만 감소는 지원하지 않는다.
1
2
3
4
5
6
7
8
9
10
|
# 현재 pv 의 이름을 기준하여 4G > 10G 로 증가 : .spec.resources.requests.storage의 4Gi 를 10Gi로 변경
kubectl get pvc ebs-claim -o jsonpath={.spec.resources.requests.storage} ; echo
kubectl get pvc ebs-claim -o jsonpath={.status.capacity.storage} ; echo
kubectl patch pvc ebs-claim -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}'
kubectl patch pvc ebs-claim -p '{"status":{"capacity":{"storage":"10Gi"}}}' # status 는 바로 위 커멘드 적용 후 EBS 10Gi 확장 후 알아서 10Gi 반영됨
# 확인 : 볼륨 용량 수정 반영이 되어야 되니, 수치 반영이 조금 느릴수 있다
kubectl exec -it app -- sh -c 'df -hT --type=ext4'
kubectl df-pv
aws ec2 describe-volumes --volume-ids $(kubectl get pv -o jsonpath="{.items[0].spec.csi.volumeHandle}") | jq
|
cs |
pvc, app 삭제
1
|
kubectl delete pod app & kubectl delete pvc ebs-claim
|
cs |
'스터디 > Kubernetes' 카테고리의 다른 글
[AWES] EKS Storage 4/5 - AWS EFS Controller (1) | 2023.05.14 |
---|---|
[AWES] EKS Storage 3/5 - AWS Volume SnapShots Controller (1) | 2023.05.14 |
[AWES] EKS Storage 1/5 - 임시 파일시스템과 local-path 스토리지 클래스 (0) | 2023.05.14 |
[AWES] EKS Networking - AWS LB Controller, Ingress (0) | 2023.05.07 |
[AWES] EKS Networking 특징과 네트워크 흐름 (0) | 2023.05.07 |