PVC Pending의 세 원인 — EBS CSI · IRSA · hostPort

보안3분조회

EBS CSI 드라이버는 쿠버네티스가 요청한 PVC 를 실제 AWS EBS 볼륨으로 만들어 파드에 붙여 주는 컴포넌트이고, IRSA(IAM Roles for Service Accounts)는 파드가 노드 자격증명 대신 자기 몫의 IAM 역할로 AWS 권한을 얻는 방식입니다. 이 둘이 이번 PVC Pending 의 핵심이었습니다.

EKS 가 아닌 자체 관리 클러스터에 Vault 를 올리는데 data-vault-0 PVC 가 Pending 에서 안 넘어갔습니다. 볼륨이 안 붙으니 파드도 안 뜹니다.

EBS CSI 컨트롤러의 AWS 자격증명 획득 실패

kubectl describe pvc data-vault-0 -n vault

이벤트에 이렇게 남아 있었습니다.

failed to provision volume ... failed to get EC2 IMDS role credentials
operation error EC2: CreateVolume, get identity: get credentials:
  failed to refresh cached credentials
net/http: timeout awaiting response headers

EBS CSI 컨트롤러가 CreateVolume 을 호출하려면 AWS 자격증명이 필요합니다. IMDS 로 노드 역할을 가져오려다 실패했습니다.

EKS 라면 IRSA 가 콘솔에서 몇 번 클릭으로 붙지만, 자체 관리 클러스터에서는 OIDC 공급자부터 직접 구성해야 합니다. ServiceAccount 에 역할을 연결했습니다.

kubectl patch sa ebs-csi-controller-sa -n kube-system \
  -p '{"metadata":{"annotations":{"eks.amazonaws.com/role-arn":"arn:aws:iam::123456789012:role/ebs-csi-controller-role"}}}'

annotation 은 파드가 새로 떠야 반영됩니다.

kubectl delete pod -l app.kubernetes.io/name=aws-ebs-csi-driver -n kube-system

이번엔 컨트롤러 자체가 Pending

파드를 지웠더니 새 컨트롤러 파드가 안 떴습니다.

1 node(s) didn't have free ports for the requested pod ports

배포 YAML 에 hostPort: 9808 이 박혀 있었습니다. hostPort 는 노드의 그 포트를 독점합니다. 이미 죽어가는 이전 파드가 포트를 잡고 있으니 새 파드가 들어갈 자리가 없습니다.

hostPorthostNetwork 를 둘 다 뺐습니다.

kubectl edit deployment ebs-csi-controller -n kube-system
# spec.template.spec
hostNetwork: true          ← 제거

# ebs-plugin 컨테이너의 ports
- containerPort: 9808
  hostPort: 9808           ← 이 줄 제거

파드가 정상적으로 재시작되자 PVC 가 Bound 로 넘어가고 Vault 도 Running 이 됐습니다.

겹쳐 있던 세 층의 원인

PVC 하나가 Pending 인 상태였지만 걸려 있던 건 세 층이었습니다.

인증    EBS CSI 컨트롤러에 AWS 자격증명이 없음
스케줄링 hostPort 독점으로 컨트롤러 파드가 못 뜸
네트워크 hostNetwork 설정이 불필요하게 붙어 있음

첫 번째를 고치고 나서야 두 번째가 드러났듯이, 앞 문제를 걷어내기 전에는 뒤 문제가 아예 보이지 않습니다. kubectl describe 의 이벤트를 단계마다 다시 읽어야 하는 이유가 여기 있습니다.

hostPorthostNetwork 는 노드 자원을 직접 잡는 설정이라 스케줄링 제약이 됩니다. 애드온 매니페스트에 이런 게 들어 있으면 정말 필요한지 확인하는 게 좋습니다. 대부분은 없어도 동작합니다.

권한도 노드 역할에 몰아주지 말고 IRSA 로 필요한 워크로드에만 붙입니다. 노드 역할에 얹으면 그 노드에 뜨는 모든 파드가 같은 권한을 갖게 됩니다.

  1. 불러오는 중