kubernetes 를 이용하다보면 모든 컨테이너에서 동일한 volume 을 사용해야 하는 경우가 생깁니다. 예를 들어 wordpress 같은 경우 동일한 HTML 파일을 가지고 있어야 사용자에게 동일한 화면을 보여줄 수 있으며, 필자가 주로 개발하는 Hyperledger Fabric 의 경우 모든 peer, orderer 등 다른 node 들이 crypto 파일을 공유할 수 있어야 합니다.

그냥 쉽게 EBS 볼륨 을 사용하면 되지 않나 생각할 수도 있지만 EBS 의 경우 아래 그림처럼 Available Zone (가용영역) 내에서 생기는 스토리지이기 때문에 서로 다른 가용영역에서는 공유할 수 없는 문제가 생깁니다. 즉, 쿠버네티스를 사용하면 어떤 pod 가 어떤 가용영역에 들어갈 지 모르기 때문에 모든 pod 가 동일한 volume 을 share 하고 싶다면 특별한 방법을 사용해야 합니다.

intro_01

즉, 모두 공유할 수 있는 Storage 인 EFS 를 사용해야 합니다. 하지만 아래 그림에서 보듯이 EFS 와 EKS 는 서로 분리되어 있는 컴포넌트 이기 때문에 따로 생성해주어야 합니다. 그로 인해 조금 다른 구조를 띄게 됩니다. 다시 말하자면, 평상시 PV 를 사용할때와는 다른 프로세스를 거쳐야 하는데 아래 그림에서 볼수 있는 각각의 컴포넌트 생성 과정인 1) EFS 를 생성, 2) provisioner deployment 생성, 3) storageclass 생성, 4) 만든 storage 에 PVC 생성 이라는 과정을 거쳐야 합니다.

intro_02

그럼 이제 한 단계씩 만들면서 EFS 를 어떻게 구성하는지 알아보도록 하겠습니다.

참고로 이번 포스팅은 EKS 세팅하기 에서 이어지는 부분이므로 아직 세팅이 안되신 분들은 먼저 EKS 를 세팅하고 봐주시길 바랍니다.

또한 이번 포스팅은 aws 문서 를 참고했습니다.

EFS 생성

그럼 먼저 EFS 를 생성하도록 하겠습니다. 이전 포스팅을 보시면, 저희는 eks 를 위한 vpc 를 생성했었습니다. EFS 는 같은 private 망 안에서만 접근할 수 있도록 설정해야 하므로 생성한 vpc를 선택해 주도록 합니다.

또한 Security Group 도 default 를 사용하지 말고 이전에 만들었던 NodeSecurityGroup 을 선택해 줍니다.

install_01

참고로 EFS 를 생성하시면 EC2 서비스에 두 종류(설정한 Available zone 갯수 만큼)의 네트워크 인터페이스가 생기게 됩니다.

install_02

그 이후 이 EFS 를 사용하기 위해서는 저희가 만든 Kubernetes node 에 EFS util 을 설치해서 EFS 를 사용할 수 있는 상태로 만들어 주어야 합니다. (만약, 처음부터 EFS 를 사용할 예정이었다면 Node Group 을 만들 때 cloudformation 의 command 로 적어주었어도 되었겠죠?) 혹시 이 때 ssh(22 포트)를 열지 않으신분들은 잘…(배스천 호스트 방법 등을 이용) 접속해주시기 바랍니다.

# node 1 에 amazon-efs-utils 설치
ssh -i {pem key} ec2-user@5{node1 public ip} "sudo yum install -y amazon-efs-utils"

# node 2 에 amazon-efs-utils 설치
ssh -i {pem key} ec2-user@5{node2 public ip} "sudo yum install -y amazon-efs-utils"

# node 3 에 amazon-efs-utils 설치
ssh -i {pem key} ec2-user@5{node3 public ip} "sudo yum install -y amazon-efs-utils"

네 이제 kubernetes 에서 EFS 를 사용하기 위한 세팅이 끝났습니다. 다음 포스팅부터는 EKS 를 사용해보도록 하겠습니다.

EFS Provisioner

EFS 를 사용하기 위해서는 중간에 provisioner 를 만들어 이와 소통하도록 만들어 주어야 합니다. 이 provisioner 도 결국은 pod 로 만들어져 있으며 단순히 배포해주면 됩니다. 이로 인해서 NFS 를 사용할 수 있는 발판(?) 을 마련할 수 있게 됩니다.

위에서 직접 적어주어야 할 부분은 환경설정의 FILE_SYSTEM_ID(파일 시스템 ID), nfs 서비 name(DNS 이름) 입니다. 이 두가지는 efs 를 생성하셨을 때 획득할 수 있습니다. 아래 사진(efs 서비스에 접속했습니다.)에 표시된 두 가지로 바꿔 주도록 합니다. 또한 aws region 을 seoul(ap-northeast-2) 로 바꾸는 것도 잊지 말아야 합니다. provisioner name 은 이름을 지정해 주도록 합니다. (필자는 kscory.com/aws-efs 로 지정했습니다.)

provisioner_01

그럼 이를 이용해 provisioner 를 배포하겠습니다.

# 배포
$ kubectl apply -f provisioner.yaml

# 확인
$ kubectl describe deployment efs-provisioner
$ kubectl describe serviceaccount efs-provisioner

rbac (권한 설정)

provisioner pod 가 잘 배포되었다면 이제 이에 대한 권한을 주도록 합니다. (rbac.yaml) 만약 default 가 아닌 다른 namespace 에서 실행했다면 아래에 교체하라고 주석 쳐져 있는 부분을 변경하도록 합니다.

작성을 하셨다면 rbac 를 적용하겠습니다.

# rbac 적용
$ kubectl apply -f rbac.yaml

# 확인
$ kubectl describe role leader-locking-efs-provisioner
$ kubectl describe rolebinding leader-locking-efs-provisioner
$ kubectl describe clusterrole efs-provisioner-runner
$ kubectl describe clusterrolebinding run-efs-provisioner

storageclass 생성

이제 efs 를 사용하기 위해 storageclass 를 생성하겠습니다. 이 파일도 또한 class.yaml 에 존재하니 참고 바랍니다. 아래에서 provisioner 이름의 경우 이전에 적용했던 이름을 그대로 적용시켜 줍니다. 참고로 필자는 kscory.com/aws-efs 으로 지정했다고 이야기 했었습니다.

그럼 적용해 봅시다

# storage class 배포
$ kubectl apply -f class.yaml

# 확인
$ kubectl describe storageclass aws-efs

네 이렇게 하면 이제 efs 를 쓸 준비가 되었습니다. 이제 이 storage class 에 원하는 pvc 를 만들어서 요청하기만 하면 됩니다.

PVC 생성

PVC 의 경우 이제 내가 원하는 pod 에서 요청할 template 으로 만들어 주면 됩니다. aws 에서 제공해주는 튜토리얼의 경우 테스트 용도로 efs 를 name 으로 갖는 claim.yaml PVC template 파일을 제공해 주고 있습니다.

이를 이용해서 잘 작동하는지 확인해 보겠습니다.

적용해 봅시다

# PVC 생성
$ kubectl apply -f claim.yaml

# 확인
$ kubectl describe pvc efs

Test 용 application 배포

이제 efs 가 잘 동작하는지 확인해 보겠습니다. 튜토리얼에서 제공해주는 test-pod.yaml template 은 아래에서 command 를 보면 알겠지만 efs 볼륨에 touch /mnt/SUCCESS & & exit 0 | | exit 1" 를 사용하게 됩니다.

pod 를 생성해보겠습니다.

# pod 생성
$ kubectl apply -f test-pod.yaml

# 확인
$ kubectl describe pod test-pod

생성이 잘 되었다면 성공입니다. 만약 describe 했을 때 failure 가 떠있다면 실패한 것이니 어디서 오류가 났는지 확인해보시기 바랍니다.

그럼 정말로 share 가 잘 되는지 확인하기 위해 test 용도의 pod2 를 만들어보겠습니다. 이번에는 pod 생성시 아무런 파일도 생성하지 않을 것이기 때문에 이 pod 에 접속하여 이전 pod 에서 생성한 파일이 공유되고 있다면 성공입니다. (test-pod2.yaml)

이를 만들고 확인해보겠습니다.

# test-pod2 배포
$ kubectl apply -f test-pod2.yaml

# test-pod2 에 파일이 있는지 확인
$ kubectl exec -it test-pod2 ls /mnt/

결과로 SUCCESS 라는 파일이 있는 걸 확인하셨나요? 그럼 성공입니다!

마무리

앞에서 말한대로 efs 를 가끔 사용할 일이 생길 수 있습니다. 처음에는 조금 헤깔렸지만 하다보면 익숙해질 것으로 생각됩니다. 하지만 아직 봐야 할 것들이 산더미라는 사실이 참 …. 세상엔 공부할 것이 정말 많은 것 같습니다.