SK플래닛 ai활용 데이터엔지니어 과정 2기/쿠버네티스

쿠버네티스 - 5

dev-lee 2026. 3. 25. 21:00

K8S Persistent Volume (PV) — EKS + AWS EFS 통합 요약

1. PV(Persistent Volume) 개념

  • PV란: 포드(Pod)와 독립적으로 존재하는 클러스터 수준의 스토리지 자원
  • 비유: 포드 = 소프트웨어, PV = 하드디스크

핵심 특징

특징 설명
독립적 생명주기 포드 삭제 후에도 데이터 유지
클러스터 리소스 클러스터 전체에서 관리
추상화 실제 저장소 종류와 무관하게 일관된 접근 가능

PV vs PVC

개념 설명 비유
PV 관리자가 생성한 실제 스토리지 자원 빌딩의 빈 사무실 (공급)
PVC 사용자가 크기·접근 모드를 요청하는 객체 사무실 임대 계약서 (요청)

주요 설정 파라미터

  • Capacity: 저장 공간 크기 (예: 5Gi)
  • Access Modes:
    • ReadWriteOnce (RWO): 단일 노드 읽기/쓰기
    • ReadOnlyMany (ROX): 여러 노드 읽기 전용
    • ReadWriteMany (RWX): 여러 노드 읽기/쓰기 (EFS/NFS)
  • Reclaim Policy:
    • Retain: 데이터 보존 (수동 삭제)
    • Delete: 물리 저장소 함께 삭제
    • Recycle: 데이터 비우고 재사용

프로비저닝 방식

  • 정적(Static): 관리자가 PV를 수동으로 미리 생성
  • 동적(Dynamic): PVC 생성 시 StorageClass를 통해 PV 자동 생성 (클라우드 환경 권장)

2. EKS + AWS EFS 통합 작업 순서

1단계: EFS 파일 시스템 및 네트워크 준비

# EFS 파일 시스템 생성 및 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)

echo "생성된 EFS ID: $EFS_ID"
  • EFS 보안 그룹 인바운드 규칙: NFS 포트(2049) 허용 필요
  • 클러스터 노드가 위치한 모든 서브넷에 마운트 타겟 생성

2단계: EFS CSI 드라이버 설치

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

3단계: StorageClass & PV/PVC 정의

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
    volumeHandle: <EFS_ID>
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: efs-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: efs-sc
  resources:
    requests:
      storage: 5Gi
kubectl apply -f efs-pvc.yaml
kubectl get pvc efs-pvc  # Bound 상태 확인

4단계: 애플리케이션(Deployment) 연결

volumes:
  - name: efs-storage
    persistentVolumeClaim:
      claimName: efs-pvc

volumeMounts:
  - name: efs-storage
    mountPath: /usr/share/nginx/html

3. 네트워크 통로(마운트 타겟) 생성

# 노드 보안 그룹 및 서브넷 추출
export NODE_SG=$(aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=*node*" \
  --query "Reservations[0].Instances[0].SecurityGroups[0].GroupId" \
  --output text)

export SUBNETS=$(aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=*node*" \
  --query "Reservations[*].Instances[*].SubnetId" \
  --output text | tr '\t' '\n' | sort -u)

# 2049 포트 인바운드 허용
aws ec2 authorize-security-group-ingress \
  --group-id $NODE_SG \
  --protocol tcp \
  --port 2049 \
  --source-group $NODE_SG

# 서브넷별 마운트 타겟 생성
for subnet in $SUBNETS; do
  aws efs create-mount-target \
    --file-system-id $EFS_ID \
    --subnet-id $subnet \
    --security-groups $NODE_SG
done

# 상태 확인 (available 확인)
aws efs describe-mount-targets --file-system-id $EFS_ID \
  --query 'MountTargets[*].LifeCycleState'

4. 연결 확인 및 테스트

# 포드 상태 확인
kubectl get pods -l app=game-2048

# POD1에서 파일 생성
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에서 파일 확인 (RWX 공유 검증)
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

5. 전체 작업 순서 정리

단계 작업 명령어/도구
1 노드 IAM 역할 권한 부여 aws iam attach-role-policy
2 EFS 보안 그룹 2049 포트 오픈 aws ec2 authorize-security-group-ingress
3 EFS CSI 드라이버 설치 eksctl create addon 또는 Helm
4 StorageClass / PV / PVC 배포 kubectl apply -f efs-pvc.yaml
5 Deployment에 볼륨 마운트 연결 kubectl apply -f game-2048-efs.yaml
6 포드 재시작 및 RWX 테스트 kubectl exec 파일 공유 확인

트러블슈팅 체크리스트

  • kubectl get pvcBound 상태 확인
  • EFS ID가 PV의 volumeHandle과 일치 여부 확인
  • 보안 그룹 2049 포트 인바운드 규칙 확인
  • VPC DNS 호스트 이름 및 DNS 확인 활성화 여부 확인

6. 삭제

# 쿠버네티스 리소스 삭제
kubectl delete -f game-2048-efs.yaml
kubectl delete -f efs-pvc.yaml

# 마운트 타겟 삭제
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
done

# EFS 파일 시스템 삭제
aws efs delete-file-system --file-system-id $EFS_ID

# CSI 드라이버 삭제
helm uninstall aws-efs-csi-driver -n kube-system

# 보안 그룹 규칙 삭제
aws ec2 revoke-security-group-ingress \
  --group-id $NODE_SG \
  --protocol tcp \
  --port 2049 \
  --source-group $NODE_SG

# 클러스터 삭제
eksctl delete cluster --name free-vpc-cluster

'SK플래닛 ai활용 데이터엔지니어 과정 2기 > 쿠버네티스' 카테고리의 다른 글

쿠버네티스 - 7  (0) 2026.03.25
쿠버네티스 - 6  (0) 2026.03.25
쿠버네티스 - 4  (0) 2026.03.25
쿠버네티스 - 3  (0) 2026.03.25
쿠버네티스 - 2  (0) 2026.03.23