1 # 터미널 1 watch -d kubectl get pv,pvc,pods,deployment,rs,svc 2 # 터미널 2 1. EFS 파일 시스템 및 마운트 타겟 생성 먼저 AWS 콘솔이나 CLI에서 실제 EFS를 생성해야 합니다. 파일 시스템 생성: AWS 콘솔에서 EFS를 생성하고 fs-xxxxxx 형태의 ID를 메모하세요. 보안 그룹 설정: EFS 보안 그룹의 인바운드 규칙에 노드 보안 그룹으로부터의 NFS(2049포트) 접속을 허용해야 합니다. 마운트 타겟: 클러스터 노드가 위치한 모든 서브넷에 마운트 타겟을 생성하세요 3 # 파일 시스템 생성 및 ID 추출 export EFS_ID=$(aws efs create-file-system \ --creation-token $(date +%s) \ --performance-mode generalPurpose \ --throughput-mode bursting \ --region ap-northeast-2 \ --query 'FileSystemId' \ --output text) # 생성된 ID 확인 echo "생성된 EFS ID: $EFS_ID" 323301:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# # 생성된 ID 확인 (arn:aws:eks:ap-northeast-2:588752323301:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# echo "생성된 EFS ID: $EFS_ID" 생성된 EFS ID: fs-089c9a72adca07380 (arn:aws:eks:ap-northeast-2:5887523 fs-089c9a72adca07380 4 EFS CSI 드라이버 설치 # Helm 레포지토리 추가 helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/ helm repo update # 드라이버 설치 helm install aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \ --namespace kube-system \ --set controller.serviceAccount.create=false \ --set controller.serviceAccount.name=efs-csi-controller-sa 5 cat < efs-pvc.yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: efs-sc provisioner: efs.csi.aws.com --- apiVersion: v1 kind: PersistentVolume metadata: name: efs-pv spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: efs-sc csi: driver: efs.csi.aws.com # 여기에 본인의 EFS ID를 입력하세요 volumeHandle: fs-089c9a72adca07380 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: efs-pvc spec: accessModes: - ReadWriteMany storageClassName: efs-sc resources: requests: storage: 5Gi EOF # 리소스 배포 kubectl apply -f efs-pvc.yaml # 결과 확인 (arn:aws:eks:ap-northeast-2:588752323301:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# kubectl apply -f efs-pvc.yaml storageclass.storage.k8s.io/efs-sc created persistentvolume/efs-pv created persistentvolumeclaim/efs-pvc created 6 4. 최종 확인 PVC가 정상적으로 연결(Bound)되었는지 확인합니다. kubectl get pvc efs-pvc <2>PVC를 2048 게임 디플로이먼트의 volumes 섹션에 연결 1 PVC를 2048 게임 디플로이먼트의 volumes 섹션에 연결 아래는 volumes와 volumeMounts 섹션을 추가한 통합 YAML 파일입니다. EFS가 연결된 2048 게임 배포 (cat 명령어) 이 설정을 적용하면 게임 파일이 위치하는 /usr/share/nginx/html 디렉토리가 AWS EFS와 동기화됩니다. 2 cat < game-2048-efs.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-2048 namespace: default spec: replicas: 2 selector: matchLabels: app: game-2048 template: metadata: labels: app: game-2048 spec: containers: - name: app-2048 image: public.ecr.aws/l6m2t8p7/docker-2048:latest ports: - containerPort: 80 # 1. 컨테이너 내부의 저장 경로 설정 volumeMounts: - name: efs-storage mountPath: /usr/share/nginx/html # 2. 사용할 PVC 연결 volumes: - name: efs-storage persistentVolumeClaim: claimName: efs-pvc EOF # 설정 적용 (기존 배포가 있다면 업데이트됩니다) kubectl apply -f game-2048-efs.yaml <2>네트워크 통로(마운트 타겟) 이제 이 EFS를 실제 노드들이 사용할 수 있도록 네트워크 통로(마운트 타겟)를 뚫어줄 차례입니다. 현재 사용 중인 클러스터의 서브넷들을 자동으로 찾아 마운트 타겟을 생성하는 스크립트. 1. 노드 보안 그룹 및 서브넷 정보 추출 EFS에 접속할 수 있는 권한을 가진 노드들의 보안 그룹과 서브넷 ID를 변수에 담습니다. # 1. 노드가 속한 보안 그룹 ID 추출 (EFS 접속 허용용) export NODE_SG=$(aws ec2 describe-instances \ --filters "Name=tag:Name,Values=*node*" \ --query "Reservations[0].Instances[0].SecurityGroups[0].GroupId" \ --output text) # 2. 노드들이 위치한 모든 서브넷 ID 추출 (마운트 타겟 생성용) export SUBNETS=$(aws ec2 describe-instances \ --filters "Name=tag:Name,Values=*node*" \ --query "Reservations[*].Instances[*].SubnetId" \ --output text | tr '\t' '\n' | sort -u) echo "Node SG: $NODE_SG" echo "Subnets: $SUBNETS" 2 . 보안 그룹 규칙 추가 (NFS 2049 포트 오픈) 노드들이 EFS에 접근할 수 있도록 노드 보안 그룹끼리 2049 포트 통신을 허용해야 합니다. (또는 EFS 전용 SG를 만들어 노드 SG를 소스로 등록해도 됩니다. 여기서는 편의상 노드 SG에 규칙을 추가합니다.) aws ec2 authorize-security-group-ingress \ --group-id $NODE_SG \ --protocol tcp \ --port 2049 \ --source-group $NODE_SG 3 # 서브넷별 마운트 타겟 생성 (자동 반복) # 추출한 모든 서브넷에 마운트 타겟을 생성합니다. (약 1~2분 소요) for subnet in $SUBNETS; do aws efs create-mount-target \ --file-system-id $EFS_ID \ --subnet-id $subnet \ --security-groups $NODE_SG echo "Mount target created in $subnet" done 4. 최종 확인 마운트 타겟 상태가 available로 바뀌었는지 확인합니다. (2분후) aws efs describe-mount-targets --file-system-id $EFS_ID --query 'MountTargets[*].LifeCycleState' :ap-northeast-2:588752323301:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# aws efs describe-mount-targets --file-system-id $EFS_ID --query 'MountTargets[*].LifeCycleState' [ "creating" ] "available" # 참고 네트워크 설정이 끝나면 이제 쿠버네티스 리소스를 수정할 차례입니다. 아까 작성한 efs-pvc.yaml 파일에서 volumeHandle 값을 방금 만든 ID로 업데이트해 주세요. # YAML 파일의 volumeHandle을 실제 ID로 교체 sed -i "s/volumeHandle: .*/volumeHandle: $EFS_ID/" efs-pvc.yaml # 쿠버네티스에 PV/PVC 배포 kubectl apply -f efs-pvc.yaml <4> 연결 확인 및 테스트 1. 포드 재시작 확인 설정을 적용하면 포드가 순차적으로 다시 생성됩니다. Running 상태가 되는지 확인하세요. kubectl get pods -l app=game-2048 2. 파일 쓰기 테스트 (데이터 영속성 확인) 하나의 포드에 접속해서 파일을 만들고, 다른 포드에서도 그 파일이 보이는지 확인하여 EFS가 제대로 작동하는지 테스트합니다. # 첫 번째 포드에 접속해서 파일 생성 POD1=$(kubectl get pods -l app=game-2048 -o jsonpath='{.items[0].metadata.name}') kubectl exec $POD1 -- sh -c "mkdir -p /usr/share/nginx/html/data && echo 'EFS Storage Connect Success' > /usr/share/nginx/html/data/hello.txt" # 두 번째 포드에서 해당 파일이 보이는지 확인 POD2=$(kubectl get pods -l app=game-2048 -o jsonpath='{.items[1].metadata.name}') kubectl exec $POD2 -- cat /usr/share/nginx/html/data/hello.txt 8752323301:cluster/free-vpc-cluster:N/A) [root@kops-ec2 ~]# kubectl exec $POD2 -- cat /usr/share/nginx/html/data/hello.txt EFS Storage Connect Success <6> 삭제 1 # 2048 게임 배포 삭제 kubectl delete -f game-2048-efs.yaml # PVC 및 PV 삭제 (EFS-SC 포함) kubectl delete -f efs-pvc.yaml 2 # 마운트 타겟 ID 추출 및 삭제 MOUNT_TARGET_IDS=$(aws efs describe-mount-targets --file-system-id $EFS_ID --query 'MountTargets[*].MountTargetId' --output text) for mt_id in $MOUNT_TARGET_IDS; do aws efs delete-mount-target --mount-target-id $mt_id echo "Mount target $mt_id deleted." done 3 # 파일 시스템 삭제 aws efs delete-file-system --file-system-id $EFS_ID 4 # EFS CSI 드라이버 삭제 helm uninstall aws-efs-csi-driver -n kube-system # 노드 보안 그룹에 추가했던 NFS(2049) 규칙 삭제 aws ec2 revoke-security-group-ingress \ --group-id $NODE_SG \ --protocol tcp \ --port 2049 \ --source-group $NODE_SG 5 최종 확인 사항 AWS 콘솔에 접속하여 아래 리소스들이 완전히 사라졌는지 확인하는 것이 가장 안전합니다. EFS 콘솔: 파일 시스템 목록에 fs-089c9a72adca07380가 없는지 확인. EC2 보안 그룹: 노드 보안 그룹의 인바운드 규칙에서 2049 포트가 제거되었는지 확인.