2024. 11. 20. 23:54ㆍAWS/EKS
안녕하세요!
Onezero 입니다 :)
EKS에서 여러 pods가 하나의 Storage를 사용하게 할 수 있습니다.
EBS의 경우, 단일 AZ로만 사용가능하여 다른 AZ에서는 접근이 불가능하다는 단점이 있습니다.
이 부분을 해결하기 위해 다른 AZ에서도 사용 가능한 EFS를 사용합니다.
Step1. IAM 정책 및 역할 생성
Github에서 IAM 정책 문서 "iam-policy-example.json" 를 다운로드합니다.
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/iam-policy-example.json
"AmazonEKS_EFS_CSI_Driver_Policy" 정책을 생성합니다.
aws iam create-policy \
--policy-name AmazonEKS_EFS_CSI_Driver_Policy \
--policy-document file://iam-policy-example.json
IAM 역할을 생성하여 여기에 IAM 정책을 연결합니다.
eksctl create iamserviceaccount \
--cluster [Cluster_Name] \
--namespace kube-system \
--name efs-csi-controller-sa \
--attach-policy-arn arn:aws:iam::[Account_ID]:policy/AmazonEKS_EFS_CSI_Driver_Policy \
--approve \
--override-existing-serviceaccounts \
--region ap-northeast-2
완료 후 IAM 콘솔 > Policy > AmazonEKS_EFS_CSI_Driver_Policy 를 보면 아래와 같이 연결된 엔터티를 확인할 수 있습니다.
Step2. EFS Driver 설치 (Helm 이용)
아래 명령어를 통해 Helm repo에 추가합니다.
helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
Helm repo를 업데이트합니다.
helm repo update
Helm 차트를 사용하여 Driver Release를 설치합니다.
helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \
--namespace kube-system \
--set image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/aws-efs-csi-driver \
--set controller.serviceAccount.create=false \
--set controller.serviceAccount.name=efs-csi-controller-sa
Step3. Amazon EFS 파일 시스템 생성
(1) EKS Cluster에 대한 Amazon EFS 파일 시스템 생성
# VPC ID를 검색하여 변수에 저장합니다.
vpc_id=$(aws eks describe-cluster \
--name zero-cluster \
--query "cluster.resourcesVpcConfig.vpcId" \
--output text)
# Cluster의 VPC에 대한 CIDR 범위를 변수에 저장합니다.
cidr_range=$(aws ec2 describe-vpcs \
--vpc-ids $vpc_id \
--query "Vpcs[].CidrBlock" \
--output text \
--region ap-northeast-2)
(2) EFS mount points 에 대한 인바운드 보안 그룹 생성
# 보안그룹을 생성합니다.
security_group_id=$(aws ec2 create-security-group \
--group-name MyEfsSecurityGroup \
--description "My EFS security group" \
--vpc-id $vpc_id \
--output text)
# Cluster 의 VPC에 대한 CIDR에서 인바운드 NFS 트래픽을 허용하는 인바운드 규칙을 생성합니다.
aws ec2 authorize-security-group-ingress \
--group-id $security_group_id \
--protocol tcp \
--port 2049 \
--cidr $cidr_range
콘솔에 접속하여 보안그룹을 보면 확인이 가능합니다.
(3) EKS Cluster에 대한 EFS 파일 시스템 생성
# 파일시스템을 생성합니다.
file_system_id=$(aws efs create-file-system \
--region ap-northeast-2 \
--performance-mode generalPurpose \
--query 'FileSystemId' \
--output text)
# Node가 있는 서브넷에 대한 mount targets을 추가합니다.
aws efs create-mount-target \
--file-system-id [File System ID] \
--subnet-id [Subnet ID] \
--security-groups [Security Group ID]
EFS 생성된 콘솔 화면 결과 입니다.
Step4. Sample Application 배포
EFS에 대한 StorageClass 매니페스트를 다운로드 후 생성한 파일시스템 ID값을 fileSystemID에 넣어줍니다.
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
# Storageclass.yaml (File System ID값을 넣어줍니다.)
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: [File System ID]
directoryPerms: "700"
gidRangeStart: "1000" # optional
gidRangeEnd: "2000" # optional
basePath: "/dynamic_provisioning" # optional
subPathPattern: "${.PVC.namespace}/${.PVC.name}" # optional
ensureUniqueDirectory: "true" # optional
reuseAccessPoint: "false" # optional
아래 명령어를 통해 StorageClass를 배포합니다.
kubectl apply -f storageclass.yaml
StorageClass 배포가 완료되면, pod와 PersistentVolumeClaim을 배포하는 매니페스트를 다운로드하고 배포합니다.
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml
# pod.yaml 내용입니다.
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: efs-claim
spec:
accessModes:
- ReadWriteMany
storageClassName: efs-sc
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Pod
metadata:
name: efs-app
spec:
containers:
- name: app
image: centos
command: ["/bin/sh"]
args: ["-c", "while true; do echo $(date -u) >> /data/out; sleep 5; done"]
volumeMounts:
- name: persistent-storage
mountPath: /data
volumes:
- name: persistent-storage
persistentVolumeClaim:
claimName: efs-claim
아래 명령어를 통해 배포합니다.
kubectl apply -f pod.yaml
Controller가 변경 사항을 수집하는지 확인합니다.
kubectl logs efs-csi-controller-6b7f7dc47-fq95x \
-n kube-system \
-c csi-provisioner \
--tail 10
PersistentVolume 이 Bound 상태가 PersistentVolumeClaim으로 설정되어 생성되었는지 확인합니다.
데이터가 볼륨에 기록이 되었는지 아래 명령어를 통해 확인합니다.
kubectl exec efs-app -- bash -c "cat data/out"
감사합니다!
