- Published on
EKS kubelet NotReady - CNI plugin not initialized 해결
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서버리스가 아닌 **EKS 워커 노드(EC2/Fargate 제외)**에서 노드가 NotReady로 떨어지고, kubelet 로그에 cni plugin not initialized가 반복되면 거의 항상 CNI 초기화 실패(대부분 AWS VPC CNI)입니다.
이 상태에서는 Pod 스케줄링이 멈추거나(노드가 Ready가 아니므로), 이미 떠 있던 Pod도 네트워크가 깨져 ContainerCreating/Pending이 길어지고, kubectl exec/logs 같은 기본 운영 동작까지 연쇄적으로 실패할 수 있습니다. 비슷한 네트워크/노드 계층 트러블슈팅은 EKS에서 kubectl exec·logs가 안 될 때 진단법도 같이 참고하면 원인 분리를 빠르게 할 수 있습니다.
아래는 증상 확인 → 원인 분기 → 복구 순서로, 현장에서 바로 써먹을 수 있는 체크리스트입니다.
1) 증상 확인: 정말 CNI 초기화 문제인가?
노드 상태와 이벤트
kubectl get nodes -o wide
kubectl describe node <node-name> | sed -n '/Conditions:/,/Addresses:/p'
kubectl describe node <node-name> | sed -n '/Events:/,$p'
대개 다음 중 하나가 보입니다.
Ready=False/NetworkUnavailable=True- 이벤트에
cni plugin not initialized
kubelet 로그에서 키워드 확인
노드에 SSH/SSM 접속이 가능하다면:
sudo journalctl -u kubelet -n 300 --no-pager | egrep -i "cni|not initialized|network plugin|aws-cni"
대표적인 로그 패턴:
Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:... cni plugin not initialized
CNI 데몬셋(aws-node) 상태 확인
EKS 기본 CNI는 AWS VPC CNI(aws-node DaemonSet) 입니다.
kubectl -n kube-system get ds aws-node
kubectl -n kube-system get pods -l k8s-app=aws-node -o wide
kubectl -n kube-system describe pod -l k8s-app=aws-node | sed -n '/Events:/,$p'
- 특정 노드에서만
aws-node가CrashLoopBackOff/Init:Error라면 그 노드의 CNI 초기화가 실패한 것입니다.
2) 원인 분기: 가장 흔한 6가지
cni plugin not initialized는 “kubelet이 CNI 바이너리/설정 또는 CNI 데몬(aws-node) 준비를 확인하지 못했다”는 의미입니다. EKS에서는 보통 아래 원인 중 하나입니다.
(A) aws-node가 뜨지 못함: IRSA/권한 문제
최근에 IRSA로 CNI 권한을 바꿨거나, 노드 IAM Role 정책을 수정했다면 최우선으로 의심합니다.
확인:
kubectl -n kube-system logs -l k8s-app=aws-node --tail=200
로그에 이런 류가 있으면 권한 문제입니다.
AccessDenied/UnauthorizedOperationfailed to assign an IP address to container
조치 방향:
- EKS 권장 방식은 aws-node에 IRSA 적용(또는 노드 IAM Role에 정책 부여)인데, 중간에 꼬이면 CNI가 바로 죽습니다.
- IRSA 관련 트러블은 EKS IRSA 설정했는데 STS AccessDenied 뜰 때도 함께 점검하세요.
권장 체크
aws-node서비스어카운트에 올바른 어노테이션이 있는지- 연결된 IAM 정책에
ec2:AssignPrivateIpAddresses,ec2:UnassignPrivateIpAddresses,ec2:DescribeNetworkInterfaces등 CNI 필수 권한이 포함되는지
(B) aws-node 이미지/버전 불일치 또는 업그레이드 실패
클러스터 업그레이드(예: 1.27→1.28) 후 addon 버전이 뒤쳐지거나, 수동으로 yaml 적용하다가 이미지 태그가 꼬이면 발생합니다.
확인:
kubectl -n kube-system describe ds aws-node | sed -n '/Image:/p'
조치(가장 안전): EKS Addon으로 aws-vpc-cni를 관리
# 현재 애드온 상태
aws eks describe-addon --cluster-name <cluster> --addon-name vpc-cni
# 권장: 애드온 업데이트(버전은 환경에 맞게)
aws eks update-addon \
--cluster-name <cluster> \
--addon-name vpc-cni \
--resolve-conflicts OVERWRITE
> 운영 중이라면 OVERWRITE는 기존 커스텀 설정을 덮을 수 있으니, 적용 전 현재 DS/env 설정을 백업해두는 것이 안전합니다.
(C) 노드의 CNI 바이너리/설정 파일 손상 (특히 커스텀 AMI)
EKS 최적화 AMI가 아닌 커스텀 AMI를 쓸 때 종종 나옵니다.
노드에서 확인:
# CNI 설정 파일
ls -al /etc/cni/net.d/
cat /etc/cni/net.d/* 2>/dev/null | head
# CNI 바이너리
ls -al /opt/cni/bin/ | head
정상이라면 /etc/cni/net.d/에 설정이 존재하고, /opt/cni/bin/에 CNI 플러그인 바이너리가 있어야 합니다.
조치:
- 가능하면 EKS Optimized AMI로 노드그룹을 재생성/롤링
- 커스텀 AMI라면 bootstrap 스크립트에서 CNI 구성 요소가 제거/변경되지 않는지 확인
(D) 보안그룹/NACL/라우팅 문제로 AWS API 또는 IMDS 접근 불가
aws-node는 ENI/IP 할당을 위해 AWS API 호출이 필요합니다. 노드가 NAT/라우팅 문제로 AWS API에 못 나가거나, IMDS를 막아 자격증명을 못 얻으면 초기화가 실패할 수 있습니다.
확인 포인트:
- 프라이빗 서브넷 노드라면 NAT Gateway/Instance 경유 egress가 정상인지
- VPC Endpoint(Interface Endpoint)로
ec2,sts등을 쓰는 경우 보안그룹/정책이 맞는지 - IMDSv2 강제 환경에서 hop limit/iptables로 막지 않았는지
노드에서 간단 점검:
# IMDSv2 토큰 발급(실패하면 IMDS 접근 문제)
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/instance-id
(E) IP 고갈(서브넷/ENI/IP 부족)로 CNI가 더 이상 할당 못함
이 경우는 노드가 Ready였다가 신규 Pod가 안 뜨는 형태로도 나타나지만, 상황에 따라 aws-node가 에러를 내며 초기화/재시도 루프에 빠질 수 있습니다.
확인:
- 해당 노드 인스턴스 타입의 ENI/IP 한도
- 서브넷의 남은 IP
- aws-node 로그에
failed to assign an IP address류
조치:
- 서브넷 확장 또는 추가 서브넷/노드그룹 분산
ENABLE_PREFIX_DELEGATION(프리픽스 위임) 도입 검토- Pod 밀도를 낮추거나 인스턴스 타입 상향
(F) kube-proxy/CoreDNS 등 시스템 파드 연쇄 장애로 “네트워크가 안 된다”로 오판
cni plugin not initialized는 CNI 자체 문제인 경우가 많지만, 운영에서는 동시에 여러 증상이 겹쳐 원인이 헷갈립니다.
예를 들어 ALB 504가 뜨는데 Pod는 정상이라면 네트워크 경로/노드 계층을 따로 봐야 합니다. 관련해서는 EKS ALB Ingress 504인데 Pod는 정상일 때도 참고하면 좋습니다.
3) 빠른 복구 절차(안전한 순서)
아래는 “원인 파악이 아직 100% 안 됐지만, 서비스 복구가 급한 상황”에서 흔히 쓰는 순서입니다.
3-1) 문제 노드 격리 후 교체(가장 확실한 응급처치)
노드 1~2대만 문제라면 교체가 제일 빠릅니다.
kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --grace-period=30
그 다음:
- Managed Node Group이면 desired를 늘려 새 노드 투입 → 문제 노드 종료
- ASG라면 인스턴스 리프레시/교체
3-2) aws-node 재기동
CNI 데몬셋이 꼬였을 때는 재기동만으로도 회복되는 경우가 있습니다.
kubectl -n kube-system rollout restart ds/aws-node
kubectl -n kube-system rollout status ds/aws-node --timeout=3m
특정 노드만 문제면 해당 노드의 aws-node Pod만 지웠다가 재생성시키는 방법도 있습니다.
kubectl -n kube-system delete pod -l k8s-app=aws-node --field-selector spec.nodeName=<node-name>
3-3) vpc-cni 애드온을 “정상 버전”으로 재적용
업그레이드/수동 변경 이력이 있으면 애드온 재적용이 정공법입니다.
aws eks update-addon \
--cluster-name <cluster> \
--addon-name vpc-cni \
--resolve-conflicts OVERWRITE
적용 후 확인:
kubectl -n kube-system get pods -l k8s-app=aws-node -o wide
kubectl get nodes
3-4) 권한 문제라면 IRSA/정책부터 복구
IRSA를 쓰는 경우(권장)에는 아래를 확인합니다.
kubectl -n kube-system get sa aws-node -o yaml | sed -n '/annotations:/,/secrets:/p'
eks.amazonaws.com/role-arn이 의도한 IAM Role인지- 신뢰 정책(trust policy)에 OIDC provider/sub 조건이 올바른지
권한이 꼬였을 때는 “일단 노드 IAM Role에 정책을 붙여서 급한 불을 끄고” IRSA를 재정리하는 방식도 실무에서 자주 씁니다(단, 최소권한 원칙 위반 가능).
4) 재발 방지 체크리스트
애드온은 EKS Addon으로 일원화
aws-vpc-cni,coredns,kube-proxy는 가능한 한 EKS Addon으로 관리- 수동 YAML 커스텀은 변경 이력/드리프트를 만들기 쉬움
노드 부팅/AMI 표준화
- EKS Optimized AMI(또는 Bottlerocket)로 표준화
- 커스텀 AMI는
/etc/cni/net.d,/opt/cni/bin건드리는 스크립트가 없는지 점검
IP 용량(서브넷/인스턴스 타입) 모니터링
- 서브넷 가용 IP 임계치 알람
- 인스턴스 타입별 Pod 밀도 한도(ENI/IP) 문서화
장애 시 관측 포인트를 고정
kubelet로그 키워드aws-node로그/이벤트- 노드 IMDS/AWS API 접근성
5) 현장용 “원인→증상” 요약
- 권한(IRSA/IAM) 문제: aws-node 로그에 AccessDenied, 노드 NotReady 지속
- 애드온 버전/업그레이드 꼬임: 특정 시점(업그레이드 직후)부터 집단 발생
- CNI 파일/바이너리 손상: 커스텀 AMI/수동 작업 후 특정 노드에서만 재현
- 라우팅/IMDS 차단: 프라이빗 서브넷/NACL 변경 직후, 토큰 발급 실패
- IP 고갈: 신규 Pod 위주로 실패, aws-node에 IP 할당 실패 로그
위 절차대로 보면 대부분의 EKS kubelet NotReady: cni plugin not initialized는 (1) aws-node 상태/로그 확인과 (2) IRSA/IAM 권한 또는 (3) vpc-cni 애드온 재적용에서 해결됩니다.
원하시면 사용 중인 구성(Managed Node Group 여부, CNI IRSA 사용 여부, 프라이빗 서브넷/NAT/Endpoint 구성, 최근 변경 이력)을 기준으로 “가장 가능성 높은 1~2개 원인”으로 좁혀서 커맨드 중심의 런북 형태로 더 구체화해드릴게요.