0. 개요
Amazon Elastic File System(Amazon EFS)은 AWS 클라우드 서비스와 온프레미스 리소스에서 사용할 수 있는 간단하고 확장 가능하며 탄력적인 완전 관리형 탄력적 NFS 파일 시스템을 제공한다.
아래의 내용에서는 helm을 이용하여 생성한 EFS 볼륨을 pod에 붙여 Gitlab Runner를 통해 자동 배포하는 과정을 기술한다.
1. EFS 생성하기
1.1 보안 그룹 생성
EFS에 적용할 보안 그룹을 생성한다.
EC2 - Security Group - 'Create security group'을 클릭한다.
보안 그룹의 이름과 Description을 기입하고, VPC를 선택한 후, Inbound rule을 추가한다.
Inbound는 EKS의 Worker Node 보안 그룹을 추가한다.
EKS 보안 그룹의 Port는 2049로 입력한 후 생성한다
보안 그룹 생성 후 해당 그룹을 다시 클릭하여 inbound rule에 자기 자신의 보안 그룹:2049번 포트를 추가한다.
1.2 EFS 생성
AWS Console의 EFS에서 'Create file system' 버튼을 클릭하여 EFS를 생성한다.
VPC 설정 후 Subnet과 1.1에서 생성한 Security Group을 선택한다.
Name Tag를 입력한 후, 데이터 암호화가 필요하면 아래에 'Enable encryption of data at rest'을 클릭하고, KMS를 선택한 후, 'Next Step'을 선택한다.
이후에는 Default 세팅으로 EFS를 생성한다.
2. EKS에 Mount하기
2.1 StorageClass, ConfigMap EKS에 적용
EFS를 EKS에 마운트하기 위한 Storage Class와 Config Map을 EKS에 적용한다,
아래의 명령어를 통해 Storage Class와 Config Map을 로컬에 다운로드한다.
wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/aws/efs/deploy/class.yaml wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/aws/efs/deploy/configmap.yaml |
다운로드 후 configmap.yml의 file.system.id와 aws.region을 EFS에 알맞게 수정한다.
수정 후 아래의 명령어를 입력하여 kubectl에 Storage Class와 Config Map을 적용한다.
kubectl apply -f class.yaml kubectl apply -f configmap.yaml |
2.2 deployment.yml 수정
deployment.yml의 spec 하위에 volumeMount를, spec에 volume을 아래와 같이 추가한다.
deployment.yml파일은 helm template을 기반으로 작성되어, 중괄호 내의 값은 helm의 values.yaml파일에서 자동적으로 가져온다.
containers 하위의 volumeMount와 volume 속성을 추가한다.
containers: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: <PORT_NO> protocol: TCP livenessProbe: httpGet: path: /healthcheck port: http readinessProbe: httpGet: path: /healthcheck port: http resources: {{- toYaml .Values.resources | nindent 12 }} env: - name: spring.profiles.active value: {{ .Values.envVariables.profiles }} - name: SPRING_DATASOURCE_URL value: {{ .Values.envVariables.datasource_url }} - name: SPRING_DATASOURCE_USERNAME value: {{ .Values.envVariables.datasource_username }} - name: SPRING_DATASOURCE_PASSWORD value: {{ .Values.envVariables.datasource_password }} volumeMounts: - name: share mountPath: /share volumes: - name: share nfs: server: {{ .Values.persistence.shareServer }} path: / |
2.3 values.yml 수정
위의 volumes 속성의 nfs: server: 에 들어간 persistence.shareServer 값을 values.yaml에 추가한다.
값은 직접 입력하지 않고, CI/CD 환경에서 EFS ID를 동적으로 read하여 helm upgrade할 때 변수를 set할 것이므로 비워둔다.
persistence: shareServer: |
2.4 .gitlab-ci.yml 수정
helm chart 기반으로 배포하는 helm upgrade 명령어에 EFS의 dns name을 변수로 추가한다.
deploy stage에서 EFS ID를 가져오는 명령어를 실행하고, 그 EFS ID 변수를 heml upgrade의 변수로 넘겨준다.
아래의 명령어를 참고하여 helm upgrade를 수정한다.
- EFSID=$(aws efs describe-file-systems --region ap-northeast-2 --query 'FileSystems[?Name==`${EFS_NAME}`].FileSystemId' --output text) - helm upgrade --install --namespace ${APPLICATION_NAME} --set persistence.shareServer="${EFSID}.efs.ap-northeast-2.amazonaws.com" --debug ${APPLICATION_NAME}-dev ./chart |
Gitlab Runner의 log를 확인하여 volume 변수가 정상적으로 입력되었는지 확인한다.
3. EKS Mount되었는지 확인하기
3.1 Pod 접속
kubectl get po 명령어로 신규로 배포된 pod의 ID를 확인한 후, kubectl exec 명령어로 신규로 생성된 두개의 pod 중 하나에 접속한다.
접속 후 mount 된 share 디렉토리에 들어가 cat 명령어로 임시 파일을 생성한 후 다른 하나의 pod에 접속하여 share 디렉토리가 접근이 가능한지 확인한다.
정상적으로 mount되어 같은 파일을 두 개의 pod에서 접근이 가능하다.
'Kubernetes' 카테고리의 다른 글
Istio Envoy Proxy의 TCP Dump 수집 (0) | 2021.12.24 |
---|---|
Pod Affinity를 적용하여 Pod 분산 배포하기 (0) | 2021.09.01 |
Vertical Pod Autoscaling 적용하기 (0) | 2021.09.01 |
Horizontal Pod Autoscaling 적용하기 (0) | 2021.08.31 |
Blue/Green Deployment with Istio (0) | 2021.08.31 |