왜 EFS를 사용하게 되었는가?

무스마의 기존 프로젝트는 가용 영역을 하나만을 사용하여 진행 중이었습니다. 그래서 가용 영역 하나의 접근만을 지원하는 EBS를 사용 중이었으나 새로 시작하는 프로젝트는 여러 가용 영역에서 볼륨의 접근이 필요하였습니다. EBS는 단일 가용 영역에서만 접근이 가능하여 여러 가용 영역의 사용이 불가능합니다. 그래서 여러 가용 영역에서 접근이 가능한 EFS의 사용이 필요했습니다.

EBS와 EFS의 차이점

  EBS EFS
가용영역 하나의 AZ만 접근 가능 여러 AZ에서 접근 가능
크기 처음 설정한 크기 사용한 만큼 확장
비용 GB당 0.116$ GB당 0.33$

EBS는 EFS보다 가격이 저렴하지만 단일 가용 영역만 지원하기에 문제가 있었습니다.

사용 방법

Amazon EFS CSI 드라이버를 설치하는 방법으로 진행 하였습니다.

EFS 사용 권한을 위한 ServiceAccount 생성

  1. EFS 사용을 위한 serviceAccount 생성을 하기 위해 iam 정책 json을 다운 받습니다.

     $ curl -o iam-policy-example.json https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/v1.3.2/docs/iam-policy-example.json
    
  2. iam을 생성 합니다.

     $ aws iam create-policy \
         --policy-name 정책이름 \
         --policy-document file://iam-policy-example.json
    
  3. serviceAccount 생성

     $ eksctl create iamserviceaccount \
         --name efs-csi-controller-sa \
         --namespace kube-system \
         --cluster <cluster-name> \
         --attach-policy-arn arn:aws:iam::<Account-ID>:policy/<정책이름> \
         --approve \
         --override-existing-serviceaccounts \
         --region <your-region-code>
    

Amazon EFS 드라이버 설치

  1. Helm 저장소 추가

     $ helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
    
  2. repo update

    $ helm repo update
    
  3. chart 설치시 다른 리전을 사용하실 경우 주소를 확인하여 image.repository를 변경 해주세요.

     $ 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
    

EFS 생성 및 보안 그룹 수정

  1. 저는 aws-cdk로 EFS를 생성하였습니다.
export class EfsStack extends cdk.Stack {
  constructor(
    app: cdk.Construct,
    id: string,
    props: cdk.StackProps,
    protected readonly deps: Deps,
  ) {
    super(app, id, props)
    this.efs
  }

  public get efs(): cdk.FileSystem {
    return new efs.FileSystem(this, 'efs', {
      vpc: this.deps.vpc,
      encrypted: true,
    })
  }
}

각자 사용할 vpc와 subnet을 선택하여 EFS를 생성해 주세요.

  1. efs의 보안그룹의 inbound rule에 eks cluster를 추가해 줍니다. 스크린샷 2021-10-07 11 30 0051

EFS 연결

  1. kubernets pod에서 EFS를 사용하기 위해 storageClass 생성을 해줍니다. 참고

     apiVersion: storage.k8s.io/v1
     kind: StorageClass
     metadata:
       name: efs-sc
     parameters:
       # 권한
       directoryPerms: 700
       fileSystemId: <생성 된 efs의 file system id>
       # 현재 액세스 포인트 기반 프로비저닝만 지원됩니다. efs-ap
       provisioningMode: efs-ap
     provisioner: efs.csi.aws.com 
    
  2. 배포

     $ kubectl apply -f storageclass.yaml
    
  3. persistentVolumeClaim 생성

     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       name: efs-claim
     spec:
       accessModes:
         - ReadWriteMany
       resources:
         requests:
           # Amazon EFS는 탄력적 파일 시스템이므로 파일 시스템 용량 제한을 적용하지 않으나 저장 용량은 Kubernetes의 필수 필드이므로 5Gi이와 같이 유효한 값을 지정해야 합니다. 이 값은 EFS 파일 시스템의 크기를 제한하지 않습니다.
           storage: 1Gi
       storageClassName: efs-sc
    
  4. statefulset 생성

     apiVersion: apps/v1
     kind: StatefulSet
     metadata:
       name: test1
     spec:
       replicas: 1
       selector:
         matchLabels:
           app.kubernetes.io/component: app
           app.kubernetes.io/name: test1
       serviceName: test1
       template:
         metadata:
           labels:
             app.kubernetes.io/component: app
             app.kubernetes.io/name: test1
         spec:
           containers:
             - image: centos
               name: test1
               volumeMounts:
                 - mountPath: /data
                   name: persistent-storage
           volumes:
             - name: persistent-storage
               persistentVolumeClaim:
                 claimName: efs-claim
    
  5. 생성 확인 스크린샷 2021-10-01 16 16 0045

    스크린샷 2021-10-01 16 17 0002

테스트

실제로 적용이 되었나 테스트 해보겠습니다.

ap-southeast-2a에서 test.txt를 생성 후 AZ를 변경하여 node 생성 후 test.txt가 존재 하는지 확인 해보겠습니다.

  1. ap-south-2a 확인 스크린샷 2021-10-01 11 19 0037

  2. pod에 접속하여 test.txt 파일 생성 스크린샷_2021-10-01_14 55 0011

  3. Node AZ 변경 스크린샷_2021-10-01_15 11 0043

  4. pod에 접속하여 파일 확인 스크린샷_2021-10-01_14 57 0014

정상적으로 확인이 가능합니다.

마무리

지금까지 EKS에 EFS를 연결하여 사용하는 방법을 알아보았습니다. 여러 가용 영역의 사용이 필요하고 용량의 사용을 가늠하기 힘든 경우 EFS를 사용한다면 좋은 효과를 낼 수 있습니다. EBS는 가격이 조금 저렴하고 가장 빠른 대기시간을 지원합니다. 둘 중 어느 것이 좋다고 하여 하나만 쓰는 것보단 현재 개발 중인 프로젝트에 맞는 서비스의 선택이 필요해 보입니다. 감사합니다.

References