새소식

AWS/EKS

[EKS Study 3주차] EKS Storage - EFS CSI Controller

  • -

CloudNet@ 팀의 가시다님께서 Leading 하시는 AEWS Study 3주차 스터디 내용 정리

이번 포스팅에서는 EKS Storage 중 EFS CSI Driver 에 대해 알아보겠습니다.

 

1. EFS CSI Driver Install

 

EFS CSI Driver 는 EBS CSI Driver 와 마찬가지로 Amazon EFS 서비스를 EKS 에서 사용할 수 있도록 해주는 CSI Driver 입니다.

 

Cross-AZ 기능이 지원되지 않는 EBS Storage 와는 다르게,
Cross-AZ 가 가능한 공유 스토리지이기 때문에 여러 가용영역의 Pod 가 동일한 데이터를 사용해야 한다면 고려할 수 있는 서비스입니다.

 

 

1.1. IRSA 를 위한 IAM Policy 생성

 

AWS 관리형 정책을 사용하는 EBS CSI Controller 와는 다르게,
EFS CSI Controller 는 고객 관리형 정책을 사용합니다.

 

그렇기 때문에, EFS 권한을 가진 정책을 생성해줍니다.
AWS 콘솔에서 직접 만들어도 되지만 aws cli 를 통해 쉽게 만들 수 있습니다.

 

Policy JSON 파일 생성

cat << EOT > efs-csi-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "elasticfilesystem:DescribeAccessPoints",
        "elasticfilesystem:DescribeFileSystems",
        "elasticfilesystem:DescribeMountTargets",
        "ec2:DescribeAvailabilityZones"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "elasticfilesystem:CreateAccessPoint"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:RequestTag/efs.csi.aws.com/cluster": "true"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "elasticfilesystem:TagResource"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:ResourceTag/efs.csi.aws.com/cluster": "true"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "elasticfilesystem:DeleteAccessPoint",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/efs.csi.aws.com/cluster": "true"
        }
      }
    }
  ]
}
EOT

 

IAM Role 생성

  • 방금 생성한 JSON 정책을 사용하여 AmazonEKS_EFS_CSI_Driver_Policy 라는 이름의 역할을 생성합니다.

 

aws iam create-policy \
    --policy-name AmazonEKS_EFS_CSI_Driver_Policy \
    --policy-document file://efs-csi-policy.json

 

1.2. EFS CSI Driver 설치를 위한 IRSA 설정

 

  • 다음 eksctl 명령어로 IRSA 를 생성합니다.

 

eksctl create iamserviceaccount \
  --name efs-csi-controller-sa \
  --namespace kube-system \
  --cluster ${CLUSTER_NAME} \
  --attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AmazonEKS_EFS_CSI_Driver_Policy \
  --approve

 

터미널 생성 화면

 

AWS CloudFormation Stack 화면

 

생성된 IRSA 는 다음 명령어로 확인할 수 있습니다.

  • kubectl
kubectl get sa -n kube-system efs-csi-controller-sa -o yaml | head -5

 

 

  • eksctl
eksctl get iamserviceaccount --cluster myeks

 

 

1.3. EFS CSI Driver 설치 - helm

 

IRSA 설정이 완료되었다면, EFS Controller 를 설치합니다.

# EFS CSI Driver Helm Repo 추가
helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/

# Helm 업데이트
helm repo update

# Helm Set 옵션으로 원하는 값만 변경 후, Helm 배포
helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \
    --namespace kube-system \helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \
    --namespace kube-system \
    --set image.repository=602401143452.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/eks/aws-efs-csi-driver \
    --set controller.serviceAccount.create=false \
    --set controller.serviceAccount.name=efs-csi-controller-sa
    --set image.repository=602401143452.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/eks/aws-efs-csi-driver \
    --set controller.serviceAccount.create=false \
    --set controller.serviceAccount.name=efs-csi-controller-sa

 

 

다음 명령어로 EFS CSI Driver 설치를 확인할 수 있습니다.

# 배포된 Helm Repo 확인
helm list -n kube-system

# kube-system 에 배포된 EFS CSI Driver 관련 Pod 확인
kubectl get pod \
    -n kube-system \
    -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"

 

 

 

2. EFS CSI Driver 사용

 

2.1. EFS Test Code 다운로드

 

git clone https://github.com/kubernetes-sigs/aws-efs-csi-driver.git /root/efs-csi

cd /root/efs-csi/examples/kubernetes/multiple_pods/specs

 

2.2. EFS Storage Class 생성

 

EFS Storage 를 사용하기 위해 StorageClass 를 생성합니다.

 

cat storageclass.yaml | yh
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com

 

kubectl apply -f storageclass.yaml

 

 

2.3. EFS 사용을 위한 PV/PVC 생성

 

EFS 를 사용하기 위해서는 PV 에 EFS ID 를 넣어주어야 합니다.

다음 명령어로 PV.yaml 에 EFS ID 를 대입해줍니다.

EfsFsId=$(aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text)
sed -i "s/fs-4af69aab/$EfsFsId/g" pv.yaml

 

 

kubectl apply -f pv.yaml

 

PVC 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: efs-claim
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: efs-sc
  resources:
    requests:
      storage: 5Gi

 

kubectl apply -f claim.yaml

 

2.4. EFS 를 사용하는 Pod 생성

 

  • app1 : /data/out1.txt 에 5초마다 현재 시간을 출력
  • app2 : /data/out2.txt 에 5초마다 현재 시간을 출력
apiVersion: v1
kind: Pod
metadata:
  name: app1
spec:
  containers:
  - name: app1
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out1.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: efs-claim
apiVersion: v1
kind: Pod
metadata:
  name: app2
spec:
  containers:
  - name: app2
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out2.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: efs-claim

 

kubectl apply -f pod1.yaml,pod2.yamlkubectl apply -f pod1.yaml,pod2.yaml

 

Pod 에서 EFS Attach 확인

kubectl exec -ti app1 -- sh -c "df -hT -t nfs4"
kubectl exec -ti app2 -- sh -c "df -hT -t nfs4"

 

 

App1 에서 /data/out1.txt , /data/out2.txt 에 대한 내용 출력

kubectl exec -ti app1 -- tail -f /data/out1.txt
kubectl exec -ti app1 -- tail -f /data/out2.txt

 

 

모두 출력이 되므로, 서로 EFS 스토리지를 통해 데이터를 공유하고 있음을 알 수 있습니다.

 

Contents

포스팅 주소를 복사했습니다