스토리지 디버깅
2026-04-07 작성2026-06-30 수정6분 읽기
스토리지 디버깅 Decision Tree
EBS CSI Driver 디버깅
기본 점검
# EBS CSI Driver Pod 상태 확인
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
# Controller 로그 확인
kubectl logs -n kube-system -l app=ebs-csi-controller -c ebs-plugin --tail=100
# Node 로그 확인
kubectl logs -n kube-system -l app=ebs-csi-node -c ebs-plugin --tail=100
# IRSA ServiceAccount 확인
kubectl describe sa ebs-csi-controller-sa -n kube-system
EBS CSI Driver 에러 패턴
| 에러 메시지 | 원인 | 해결 방법 |
|---|---|---|
could not create volume | IAM 권한 부족 | IRSA Role에 ec2:CreateVolume, ec2:AttachVolume 등 추가 |
volume is already attached to another node | 이전 노드에서 미분리 | 이전 Pod/노드 정리, EBS 볼륨 detach 대기 (~6분) |
could not attach volume: already at max | 인스턴스 EBS 볼륨 수 제한 초과 | 더 큰 인스턴스 타입 사용 (Nitro 인스턴스: 타입별 상이, 최대 128개) |
failed to provision volume with StorageClass | StorageClass 미존재 또는 설정 오류 | StorageClass 이름/파라미터 확인 |
인스턴스별 EBS 볼륨 제한 확인
# 인스턴스 타입의 최대 EBS 볼륨 수 확인
aws ec2 describe-instance-types \
--instance-types c5.xlarge m5.2xlarge \
--query 'InstanceTypes[].{Type:InstanceType,MaxEBS:EbsInfo.MaximumVolumeCount}' \
--output table
# 노드의 현재 EBS 볼륨 사용량 확인
aws ec2 describe-volumes \
--filters "Name=attachment.instance-id,Values=<instance-id>" \
--query 'Volumes[].{VolumeId:VolumeId,State:Attachments[0].State}' \
--output table
권장 StorageClass 설정
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: topology-aware-ebs
provisioner: ebs.csi.aws.com
parameters:
type: gp3
encrypted: "true"
# gp3 성능 파라미터 (선택)
iops: "3000" # 기본 3,000 IOPS
throughput: "125" # 기본 125 MB/s
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete
WaitForFirstConsumer
volumeBindingMode: WaitForFirstConsumer를 사용하면 PVC가 Pod 스케줄링 시점에 바인딩됩니다. 이를 통해 Pod이 스케줄링되는 AZ에 볼륨이 생성되어 AZ 불일치 문제를 방지할 수 있습니다.
PVC 마운트 실패 패턴
Pattern 1: AZ 불일치
EBS 볼륨은 단일 AZ에 존재하므로, Pod이 다른 AZ의 노드에 스케줄링되면 마운트가 실패합니다.
# 증상: Pod이 ContainerCreating 상태에서 멈춤
kubectl describe pod <pod-name>
# Events:
# Warning FailedAttachVolume AttachVolume.Attach failed : ... volume is in a different availability zone
# PV의 AZ 확인
kubectl get pv <pv-name> -o jsonpath='{.metadata.labels.topology\.kubernetes\.io/zone}'
# Pod이 스케줄링된 노드의 AZ 확인
kubectl get node <node-name> -o jsonpath='{.metadata.labels.topology\.kubernetes\.io/zone}'
해결 방법: volumeBindingMode: WaitForFirstConsumer 사용
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
parameters:
type: gp3
volumeBindingMode: WaitForFirstConsumer # ← AZ 불일치 방지
Pattern 2: EBS 볼륨 제한 초과
인스턴스 타입마다 연결 가능한 최대 EBS 볼륨 수가 제한되어 있습니다.
# 증상: Pod이 ContainerCreating 상태에서 멈춤
kubectl describe pod <pod-name>
# Events:
# Warning FailedAttachVolume AttachVolume.Attach failed : ... maximum number of attachments
# 노드에 연결된 볼륨 수 확인
kubectl get node <node-name> -o json | jq '.status.volumesAttached | length'
# 인스턴스 타입의 최대 볼륨 수 확인
aws ec2 describe-instance-types \
--instance-types <instance-type> \
--query 'InstanceTypes[0].EbsInfo.MaximumVolumeCount'
해결 방법:
- 더 큰 인스턴스 타입 사용 (예: c5.xlarge → c5.2xlarge)
- PVC를 사용하지 않는 Pod을 다른 노드로 이동
- EBS 볼륨을 여러 노드에 분산
Pattern 3: ReadWriteOnce 제약
EBS 볼륨은 ReadWriteOnce (RWO)만 지원하므로 동시에 여러 노드에서 마운트할 수 없습니다.
# 증상: 두 번째 Pod이 ContainerCreating 상태에서 멈춤
kubectl describe pod <pod-name-2>
# Events:
# Warning FailedAttachVolume Multi-Attach error for volume ... Volume is already exclusively attached
# PVC의 accessModes 확인
kubectl get pvc <pvc-name> -o jsonpath='{.spec.accessModes}'
# ["ReadWriteOnce"]
해결 방법:
- 단일 Pod만 PVC를 사용하도록 설계 (StatefulSet 권장)
- 여러 Pod이 동시 접근이 필요하면 EFS 사용 (ReadWriteMany 지원)
# ReadWriteMany가 필요한 경우 EFS 사용
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-data
spec:
accessModes:
- ReadWriteMany # EFS만 지원
storageClassName: efs-sc
resources:
requests:
storage: 10Gi
Pattern 4: 볼륨 Detach 지연
이전 Pod이 삭제되어도 EBS 볼륨이 즉시 detach되지 않아 새 Pod 시작이 지연될 수 있습니다.
# 증상: 이전 Pod 삭제 후 새 Pod이 6분간 ContainerCreating
kubectl describe pod <pod-name>
# Events:
# Warning FailedAttachVolume Volume is already attached to another node
# AWS 콘솔에서 볼륨 상태 확인
aws ec2 describe-volumes --volume-ids <volume-id> \
--query 'Volumes[0].Attachments[0].State'
# "detaching" or "attached"
원인: AWS API의 볼륨 detach는 최대 6분 소요 가능
해결 방법:
- 강제 detach (주의: 데이터 손실 위험)
# 강제 detach (데이터 손실 위험!)
aws ec2 detach-volume --volume-id <volume-id> --force
- StatefulSet에서
podManagementPolicy: Parallel사용하지 않기 (순차 종료 보장)
EFS CSI Driver 디버깅
기본 점검
# EFS CSI Driver Pod 상태 확인
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-efs-csi-driver
# Controller 로그 확인
kubectl logs -n kube-system -l app=efs-csi-controller -c efs-plugin --tail=100
# EFS 파일시스템 상태 확인
aws efs describe-file-systems --file-system-id <fs-id>
# Mount Target 확인 (각 AZ에 존재해야 함)
aws efs describe-mount-targets --file-system-id <fs-id>
EFS 체 크리스트
- Mount Target이 Pod이 실행되는 모든 AZ의 서브넷에 존재하는지 확인
- Mount Target의 Security Group이 TCP 2049 (NFS) 포트를 허용하는지 확인
- 노드의 Security Group에서 EFS Mount Target으로의 아웃바운드 TCP 2049 허용 확인
# Mount Target Security Group 확인
aws efs describe-mount-targets --file-system-id <fs-id> \
--query 'MountTargets[].{MountTargetId:MountTargetId,SubnetId:SubnetId,SecurityGroups:join(`,`,NetworkInterfaceId)}' \
--output table
# Security Group Inbound 규칙 확인 (TCP 2049 허용 필요)
aws ec2 describe-security-groups --group-ids <sg-id> \
--query 'SecurityGroups[0].IpPermissions[?FromPort==`2049`]'
EFS 마운트 실패 디버깅
# Pod 이벤트 확인
kubectl describe pod <pod-name>
# Events:
# Warning FailedMount MountVolume.SetUp failed : ... connection timed out
# EFS Mount Target이 모든 AZ에 있는지 확인
aws efs describe-mount-targets --file-system-id <fs-id> \
--query 'MountTargets[].{AZ:AvailabilityZoneName,State:LifeCycleState,IP:IpAddress}'
# Pod이 실행 중인 노드의 AZ 확인
kubectl get pod <pod-name> -o jsonpath='{.spec.nodeName}' | \
xargs -I {} kubectl get node {} -o jsonpath='{.metadata.labels.topology\.kubernetes\.io/zone}'
EFS StorageClass 예제
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap # Access Point 자동 생성
fileSystemId: fs-1234567890abcdef0
directoryPerms: "700"
gidRangeStart: "1000"
gidRangeEnd: "2000"
basePath: "/dynamic_provisioning"
PV/PVC 상태 확인 및 stuck 해결
PVC 상태별 조치
# PVC 상태 확인
kubectl get pvc -n <namespace>
# PV 상태 확인
kubectl get pv
| PVC 상태 | 의미 | 조치 |
|---|---|---|
| Pending | 볼륨 프로비저닝 대기 | StorageClass 확인, CSI Driver 로그 확인 |
| Bound | PV와 바인딩 완료 | 정상 |
| Lost | PV가 삭제되었지만 PVC는 존재 | PVC 삭제 후 재생성 |
| Terminating | 삭제 중 (finalizer로 인해 멈춤) | finalizer 제거 (아래 참조) |