- Published on
EKS CNI Prefix Delegation인데도 IP 부족할 때
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
EKS에서 Amazon VPC CNI의 Prefix Delegation(PD) 을 활성화하면 “이제 IP 부족은 끝”이라고 기대하기 쉽습니다. PD는 ENI에 개별 Secondary IP를 하나씩 붙이는 대신, /28 같은 프리픽스 블록을 통째로 위임받아 노드가 더 효율적으로 Pod IP를 할당하게 해줍니다.
그런데도 실제 운영에서는 여전히 다음과 같은 증상으로 IP 부족을 마주합니다.
- 새 Pod가
Pending에 머물고 이벤트에Failed to assign an IP address to container류 메시지가 보임 - 특정 노드에서만 Pod 생성이 막히고 다른 노드는 여유가 있음
- 서브넷의
Available IP addresses가 빠르게 0에 근접 - 노드 스케일아웃을 해도 “서브넷 IP 부족”으로 노드가 제대로 뜨지 않음
이 글은 PD를 켰는데도 IP가 부족해지는 진짜 병목이 어디인지를 서브넷 → 노드(ENI) → CNI 설정 → 워크로드 패턴 순으로 쪼개서 점검하고, 바로 적용 가능한 처방을 제공합니다.
관련 증상이 0/XX nodes available로 뭉뚱그려 보일 때는 원인 분해에 도움이 되는 글도 함께 참고하세요: EKS Pod Pending 0/XX nodes available 원인별 해결
Prefix Delegation의 핵심: “노드 안”은 넉넉해져도 “서브넷”은 그대로다
PD는 노드가 소비하는 IP를 줄여주는 기능이 아닙니다. 오히려 보통은 이렇게 동작합니다.
- 기존(Secondary IP 모드): Pod 1개당 IP 1개를 서브넷에서 직접 할당(ENI의 secondary IP로)
- PD 모드: ENI에
/28프리픽스(16개 IP) 단위로 할당하고, 그 블록에서 Pod에 IP를 분배
즉, PD는 “API 호출/관리 오버헤드 감소 + 빠른 할당 + ENI당 Pod 밀도 개선”에 강점이 있고, 서브넷 전체의 IP 총량을 늘려주지는 않습니다.
따라서 PD를 켰는데도 IP가 부족하다면, 대부분은 아래 중 하나입니다.
- 서브넷 자체가 작다(/24 이하) 혹은 노드 수/Pod 수 대비 너무 타이트함
- 노드가 프리픽스를 미리 많이 확보하면서 서브넷 IP를 빨리 잠식
- ENI/프리픽스 할당 한도(인스턴스 타입, warm 설정) 때문에 특정 노드에서만 부족
- IP를 회수하지 못하는 상황(빠른 churn, terminating 지연, 장애/드레인 반복)
1) 가장 먼저: 서브넷 가용 IP 확인 (PD든 뭐든 여기서 끝나는 경우가 많다)
서브넷이 병목이면 노드/Pod 어느 쪽도 답이 없습니다.
체크 방법
aws ec2 describe-subnets \
--subnet-ids subnet-xxxx subnet-yyyy \
--query 'Subnets[].{SubnetId:SubnetId,CIDR:CidrBlock,Available:AvailableIpAddressCount,AZ:AvailabilityZone}' \
--output table
판단 기준
AvailableIpAddressCount가 급격히 줄어드는 중이면 서브넷이 근본 병목입니다.- 특히
/24(256 IP) 서브넷은 EKS 노드 + ENI + Pod가 조금만 늘어도 빠르게 고갈됩니다.
처방
- 더 큰 CIDR(/22, /21 등) 의 서브넷을 새로 만들고 노드그룹을 옮기거나 확장
- VPC가 허용하면 VPC/서브넷 CIDR 확장(운영 영향 고려)
- 멀티 AZ면 AZ별 서브넷 크기 균형도 중요(한 AZ만 먼저 고갈되면 해당 AZ 노드만 막힘)
2) “PD 켰는데 왜 이렇게 서브넷 IP가 빨리 줄지?”: Warm Prefix가 과할 수 있다
PD에서는 노드가 Pod가 생기기 전에 프리픽스를 미리(warm) 확보해두는 전략을 씁니다. 이 값이 크면, 실제로 Pod가 많지 않아도 노드들이 /28을 선점해 서브넷 IP를 빨리 잠식합니다.
확인: aws-node DaemonSet 환경변수
kubectl -n kube-system get ds aws-node -o jsonpath='{.spec.template.spec.containers[0].env}' | jq
대표적으로 확인할 항목:
ENABLE_PREFIX_DELEGATION=trueWARM_PREFIX_TARGET(프리픽스를 몇 개나 미리 유지할지)WARM_ENI_TARGET/WARM_IP_TARGET(PD 모드에서는 해석이 달라질 수 있어 혼용 주의)
흔한 실수
WARM_PREFIX_TARGET를 필요 이상으로 크게 설정- HPA/배치가 많아 Pod churn이 심한데, warm을 과하게 잡아 노드가 프리픽스를 계속 끌어안음
권장 접근
- 처음엔 보수적으로:
WARM_PREFIX_TARGET=1또는 워크로드에 맞춘 최소치부터 시작 - Pod 생성 지연이 문제일 때만 점진적으로 올리기
예시: WARM_PREFIX_TARGET 조정
kubectl -n kube-system set env ds/aws-node \
ENABLE_PREFIX_DELEGATION=true \
WARM_PREFIX_TARGET=1
kubectl -n kube-system rollout status ds/aws-node
3) 노드 단위 병목: 인스턴스 타입의 ENI/Prefix 한도에 걸린다
PD를 켜도 인스턴스 타입별 네트워크 한도는 그대로입니다.
- 인스턴스 타입마다 붙일 수 있는 ENI 개수, ENI당 프리픽스 개수(또는 IP 개수) 상한이 존재
- 특정 노드에서만 IP 할당 실패가 나면, 서브넷이 아니라 그 노드의 ENI/Prefix 한도일 가능성이 큽니다.
증상
- 노드 A는 Pod가 더 못 붙는데 노드 B는 여유
aws-node로그에 프리픽스/ENI 할당 실패가 보임
확인: aws-node 로그
kubectl -n kube-system logs -l k8s-app=aws-node --tail=200
처방
- Pod 밀도가 높다면 더 큰 인스턴스 타입(네트워크 한도가 큰 타입)으로 변경
- 노드당 Pod 상한을 낮추는 것도 방법(스케줄링 분산)
노드가 정상 조인/네트워킹 상태인지까지 같이 의심된다면, Bottlerocket 환경에서 디버깅 루트가 막히기 쉬우니 이 글이 도움이 됩니다: EKS Bottlerocket 노드 SSH 없이 SSM으로 접속·디버깅
4) “분명 Pod 줄었는데 IP가 안 돌아온다”: IP 회수 지연/누수 패턴 점검
IP 부족이 일시적인 피크가 아니라 “한번 부족해지면 계속 부족”이라면, 회수 지연이나 누수 패턴을 의심해야 합니다.
대표 케이스
- Spot 노드 종료/축출이 잦아 Pod/노드 수명주기 churn이 큼
Terminating이 길어지는 워크로드(긴 preStop, connection draining)- PDB/우선순위 때문에 드레인이 꼬여 노드에 파드가 오래 남음
Spot/축출 루프가 IP 압박을 증폭시키는 경우가 많습니다. 운영 중이라면 다음 글의 관점을 같이 적용해보세요: EKS Pod Eviction Loop - PDB·우선순위·Spot 정리
점검 커맨드
- Terminating 파드가 많은지:
kubectl get pod -A | grep Terminating | head
- 노드 드레인/축출 이벤트:
kubectl get events -A --sort-by=.lastTimestamp | tail -n 50
처방
- 종료가 긴 서비스는
terminationGracePeriodSeconds,preStop를 현실적으로 조정 - PDB를 과도하게 타이트하게 잡지 않기
- Spot 비중이 높다면 온디맨드 베이스라인 확보 + 분산(여러 타입/여러 AZ)
5) PD 설정을 했는데 “실제로는 PD가 아니다” 체크
간혹 “설정했다고 생각했는데 실제로는 PD가 적용되지 않은” 상태가 있습니다.
확인 포인트
aws-node가 최신 애드온/이미지인지 (EKS Add-on 사용 시 버전)- DaemonSet에
ENABLE_PREFIX_DELEGATION=true가 반영됐는지 - 노드 IAM Role에 VPC CNI가 요구하는 권한이 정상인지
애드온 버전과 설정이 엇갈리면, 표면적으로는 PD를 켠 것 같아도 내부 동작이 예상과 달라질 수 있습니다.
6) 실전 트러블슈팅 플로우(10분 안에 결론 내기)
운영에서 빠르게 결론을 내리려면 아래 순서가 효율적입니다.
1단계: 서브넷부터 본다
AvailableIpAddressCount가 낮으면: 서브넷 확장/추가가 정답
2단계: 노드별 편차가 있는지 본다
- 특정 노드만 막히면: 인스턴스 네트워크 한도 / ENI/Prefix 할당 실패
3단계: warm 설정이 서브넷을 잠식하는지 본다
- 노드 수가 많은데 실제 Pod는 적다 →
WARM_PREFIX_TARGET과대 가능성
4단계: 회수 지연(축출/Terminating) 확인
- 이벤트/Terminating이 많다 → churn을 줄이거나 종료 경로 최적화
예시: “서브넷은 여유 있는데 특정 노드에서만 IP 할당 실패” 케이스
아래는 가장 흔한 케이스 중 하나를 재현 가능한 형태로 정리한 것입니다.
- 증상 확인
kubectl describe pod <pending-pod>
# Events:
# Warning FailedCreatePodSandBox ... failed to assign an IP address to container
- 해당 Pod가 스케줄된 노드 확인
kubectl get pod <pending-pod> -o wide
- 그 노드에서 aws-node 로그 확인
kubectl -n kube-system logs -l k8s-app=aws-node --tail=200 | sed -n '1,200p'
- 결론
- 서브넷 가용 IP는 충분
- 그런데 aws-node가 ENI/Prefix 추가 할당을 실패
- 처방
- 인스턴스 타입 상향 또는 노드 풀 분리(고밀도 워크로드 전용)
- Pod 분산(anti-affinity, topologySpreadConstraints)
마무리: PD는 “노드 효율”이고, IP 총량은 “서브넷 설계”다
Prefix Delegation은 EKS에서 IP 할당 성능과 운영 안정성을 크게 올려주지만, IP 부족 문제를 완전히 없애는 만능키는 아닙니다.
- 서브넷이 작으면: PD를 켜도 결국 바닥납니다.
- warm 프리픽스를 과하게 잡으면: Pod가 없어도 서브넷을 잠식합니다.
- 인스턴스 한도에 걸리면: 특정 노드에서만 IP 할당 실패가 납니다.
- churn/축출이 심하면: 회수 지연으로 체감 고갈이 빨라집니다.
다음 액션을 하나만 고르라면, 먼저 서브넷 가용 IP를 표로 뽑아보고(근본), 그 다음 WARM_PREFIX_TARGET와 aws-node 로그로 노드 단 병목을 확인하세요. 이 두 가지만으로도 대부분의 “PD인데도 IP 부족” 이슈는 방향이 잡힙니다.