Study_note
[kubernetes] EFS를 POD에 동적 마운팅 본문
쿠버네티스에서는 여러 가용영역에 워커 노드들이 배포되어있는 클러스트 구조로 구성되어있다.
그렇기 때문에 하나의 노드 하나의 가용영역에서만 사용되는 EBS 볼륨은 다른 노드에 같이 마운트를 못하고 다른 가용영에 있는 워커 노드 또한 마운트 하지못한다 이러한 문제점들 때문에 EFS를 사용하여 해결한다.
EFS는 여러 가용 영역에서 접근이 가능하며 여러 노드에서도 사용 가능한 파일 공유 스토리지다
그럼 어떻게 EFS를 EKS에 어떻게 마운트 할까?
이런 동작들은 EFS CSI Driver를 사용하여 연결 가능하다.
EFS CSI Driver (CSI - Container Storage Interface)
Kubernetes 클러스터가 EFS 파일 시스템을 관리할 수 있게 해주는 CSI 인터페이스를 제공하는 도구이다
아래 그림과 같이 CSI Driver 도입 이전에는 각 서비스별로 자체적인 드라이버를 필요로 했지만, CSI Driver 도입 이후 모든 서비스에서 스토리지를 제어가능 하다.
EFS를 파드에 마운트하는 순서는 아래와 같다.
1. EFS에 대한 액세스 권한 및 역할 생성 (IRSA)
2. aws-efs-csi-driver생성 및 방금 생성한 IRSA 역할 부여
3. aws-efs-csi-driver를 사용하여 생성한 EFS를 StorageClass에 연결
4. 생성한 StorageClass 기반에 pvc 생성
5. pvc를 파드에 마운트
CSI 드라이버에 사용할 IAM 정책을 생성하기 위해 GitHub에서 IAM 정책 문서를 다운로드
curl -o iam-policy-example.json https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/iam-policy-example.json
위에서 다운 받은 IAM 정책 문서를 기반으로 정책 생성
aws iam create-policy \
--policy-name EFS_CSI_Driver_Policy \
--policy-document file://iam-policy-example.json
EKS가 EFS에 대한 권한을 가지는 iamserviceaccount인 IRSA 생성
eksctl create iamserviceaccount \
--cluster eks \ # cluster 이름
--namespace kube-system \
--name efs-csi-controller-sa \
--attach-policy-arn arn:aws:iam::111122223333:policy/EFS_CSI_Driver_Policy \ # 정책 ARN 입력
--approve \
Helm repo 추가 및 업데이트 후 upgrade 명령으로 배포 및 set으로 설정들 오버라이딩
image.repository 같은 경우 https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/add-ons-images.html
위에 경로에서 리전별 값 확인 가능
helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
helm repo update
helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \
--namespace kube-system \
--set image.repository=602401143452.dkr.ecr.region-code.amazonaws.com/eks/aws-efs-csi-driver \
--set controller.serviceAccount.create=false \
--set controller.serviceAccount.name=efs-csi-controller-sa # 생성한 servicaccount 이름
클러스터가 있는 VPC ID를 검색하고 이후 단계에서 사용할 수 있도록 변수에 저장
vpc_id=$(aws eks describe-cluster \
--name eks \
--query "cluster.resourcesVpcConfig.vpcId" \
--output text)
클러스터의 VPC에 대한 CIDR 범위를 검색하고 이후 단계에서 사용할 수 있도록 변수에 저장
cidr_range=$(aws ec2 describe-vpcs \
--vpc-ids $vpc_id \
--query "Vpcs[].CidrBlock" \
--output text) \
Amazon EFS 탑재 지점에 대한 인바운드 NFS 트래픽을 허용하는 인바운드 규칙으로 보안 그룹을 생성
security_group_id=$(aws ec2 create-security-group \
--group-name MyEfsSecurityGroup \
--description "My EFS security group" \
--vpc-id $vpc_id \
--output text)
클러스터의 VPC에 대한 CIDR의 인바운드 NFS 트래픽을 허용하는 인바운드 규칙을 생성
aws ec2 authorize-security-group-ingress \
--group-id $security_group_id \
--protocol tcp \
--port 2049 \
--cidr $cidr_range
tcp 2049를 열어주는 MyEfsSecurityGroup의 보안그룹 생성 확인
EFS 생성
file_system_id=$(aws efs create-file-system \
--performance-mode generalPurpose \
--tag Key=Name,Value=eks-efs
--query 'FileSystemId' \
--output text)
클러스터 노드들이 있는 서브넷 ID와 서브넷이 있는 가용 영역을 확인 하고 아래 명령어 입력 시 테이블 형태에 서브넷 확인 가능
aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=$vpc_id" \
--query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \
--output table
생성했던 efs를 노드가 있는 2개의 서브넷의 탑재 대상으로 생성
aws efs create-mount-target \
--file-system-id $file_system_id \
--subnet-id subnet-03899398cd92ebacd \
--security-groups $security_group_id
----
aws efs create-mount-target \
--file-system-id $file_system_id \
--subnet-id subnet-0fcef1b81ca0e2cb1 \
--security-groups $security_group_id
여기 까지 EFS CSI 드라이버 및 IRSA과 EFS를 생성하였고 다음으로 파드에
동적 스토리지인 Storageclass 와 pvc 및 pod를 생성하여 마운트해본다.
테스트용으로 Amazon EFS용 매니페스트를 제공하는데 이것을 다운로드 해준다.
curl -o storageclass.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
원래는 아래와 같은 형태의 야믈 파일이지만 선택사항 부분은 빼주고 위에서 생성했던 efs id를 입력
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-0ea733c8d32b22097 # 생성한 efs id 입력
directoryPerms: "700"
gidRangeStart: "1000" (선택 사항)
gidRangeEnd: "2000" (선택 사항)
basePath: "/dynamic_provisioning" (선택 사항)
provisioningMode : efs에서 프로비저닝할 볼륨 유형입니다. 현재 액세스 포인트 기반 프로비저닝만 지원됩니다
fileSystemId : 액세스 포인트가 생성되는 파일 시스템입니다.
directoryPerms : Access Point에서 만든 루트 디렉터리의 디렉터리 권한입니다.
gidRangeStart (선택 사항) : 액세스 포인트의 루트 디렉터리에 적용할 Posix 그룹 ID의 시작 범위입니다.
gidRangeEnd (선택 사항) : Posix 그룹 ID의 종료 범위입니다.
basePath(선택 사항) : 액세스 포인트 루트 디렉터리가 생성되는 파일 시스템의 경로입니다. 경로가 제공되지 않으면 파일 시스템의 루트 아래에 액세스 포인트 루트 디렉터리가 생성됩니다.
포드 및 pvc을 배포하는 야믈파일을 다운로드 해당 부분은 일반 마운트여서 설명 생략
curl -o pod.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/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
다운로드 받은 2개의 야믈 파일을 배포
kubectl apply -f pod.yaml
kubectl apply -f storageclass.yaml
컨트롤러가 제대로 작동되는지 확인해보면 작동되는거 확인 가능
kubectl get pods -n kube-system | grep efs-csi-controller
생성한 pv,storageclass 또한 제대로 생성
k get pv,pvc,storageclasses.storage.k8s.io
EFS가 마운트 된 파드에 원격 접속 후 마운트 되어진 스토리지 확인하면 설정했던 경로인 /data이고 로컬 호스트로 마운트 확인 가능
생성한 efs-csi 컨트롤러 로그 또한 확인 하면 아래와 같이 성공적으로 pv를 생성한 것을 확인 가능
참조
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/efs-csi.html
https://github.com/awsdocs/amazon-eks-user-guide/blob/master/doc_source/efs-csi.md
'Kubernetes' 카테고리의 다른 글
[kubernetes] Multi Cluster 환경 구성 및 플러그인 kubectx 사용 (0) | 2022.12.02 |
---|---|
[kubernetes] 쿠버네티스 플러그인 패키지 관리자 Krew 및 자주 사용하는 플러그인 tree, neat 사용 (0) | 2022.12.01 |
[kubernetes]AWS Secrets Manager를 통한 쿠버네티스 Secret관리 (0) | 2022.11.29 |
[kubernetes]IRSA 및 OIDC, Serviceaccount, IAM workflow (1) | 2022.11.21 |
[kubernetes] Helm Override 및 Upgrade (0) | 2022.11.17 |