PVC Pending — EBS CSI 자격증명과 hostPort
EC2 위에 kubeadm 으로 직접 올린 쿠버네티스 클러스터에 Vault 를 설치하는 중이었습니다. EKS 였으면 애드온 탭에서 체크 한 번으로 끝날 것들을 이 클러스터에서는 하나씩 직접 붙여야 하는데, 그날 걸린 게 스토리지였습니다.
Helm 으로 Vault 를 올리자마자 data-vault-0 PVC 가 Pending 에서 안 넘어갔고, 볼륨을 못 받으니
Vault 파드도 Pending 인 채로 같이 멈춰 있었습니다.
Vault 는 저장한 시크릿을 디스크에 쌓아 두니 PVC 를 하나 요구하고, 노드가 EC2 라 그 볼륨은 EBS 로 잡힙니다. PVC 를 실제 EBS 볼륨으로 만들어서 노드에 붙여 주는 건 EBS CSI 드라이버니까, 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 컨트롤러가 AWS 에 CreateVolume 을 호출하려면 자격증명이 있어야 합니다. EC2 안에서는
보통 IMDS 라는 링크로컬 주소(169.254.169.254)에 물어보면 그 노드에 붙은 IAM 역할의 임시 키를
내주는데, 거기서 응답을 못 받고 실패했습니다.
여기서 노드 역할에 EBS 권한을 얹어 주면 당장은 풀리지만 그러면 그 노드에 뜨는 모든 파드가 같은 권한을 갖게 됩니다. 대신 IRSA(IAM Roles for Service Accounts)를 붙였습니다. 파드가 노드 자격증명 대신 자기 ServiceAccount 에 연결된 IAM 역할로 AWS 권한을 얻습니다. EKS 라면 콘솔에서 몇 번 클릭으로 붙지만 자체 관리 클러스터에서는 OIDC 공급자부터 직접 구성해야 합니다.
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
지우면 Deployment 가 다시 띄우면서 이번엔 웹훅을 거칩니다.
이번엔 컨트롤러 자체가 Pending
파드를 지웠더니 새 컨트롤러 파드가 안 떴습니다.
1 node(s) didn't have free ports for the requested pod ports
배포 YAML 에 hostPort: 9808 이 박혀 있었는데, hostPort 는 노드의 그 포트를 파드가 독점하게
만드는 설정이라 같은 포트를 쓰는 파드는 노드당 하나만 뜰 수 있습니다. 죽어 가는 이전 파드가 아직
포트를 잡고 있으니 새 파드가 들어갈 자리가 없었습니다.
이 컨트롤러에는 hostPort 도 hostNetwork 도 필요 없어서 둘 다 뺐습니다.
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 이었지만 걸려 있던 건 인증과 스케줄링 두 층이었는데, 자격증명이 없어서 볼륨을
못 만든 게 첫 번째고, 그걸 고치려고 파드를 재시작하자 hostPort 때문에 컨트롤러가 아예 못 뜬 게
두 번째입니다. 첫 번째를 걷어내기 전에는 두 번째가 존재하는지도 알 수 없었습니다. 조치를 한 번
할 때마다 kubectl describe 의 이벤트를 다시 읽어야 하는 이유가 여기 있습니다.
hostPort 와 hostNetwork 는 노드 자원을 직접 잡는 설정이라 그대로 스케줄링 제약이 되니,
애드온 매니페스트에 이런 게 들어 있으면 정말 필요한지 확인해 보는 게 좋습니다. 이 컨트롤러는 둘
다 빼도 동작했습니다. 권한도 노드 역할에 몰아주지 말고 IRSA 로 필요한 워크로드에만 붙이면 EBS
권한은 이 컨트롤러에만 남고, 나중에 그 노드에 뭐가 뜨든 거기까지 따라가지 않습니다.
댓글 0