EKS 1.33(AL2023) 노드가 NotReady 이고 kubectl describe node 에 다음이 찍힌다.
container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady
message:Network plugin returns error: cni plugin not initialized
aws-node DaemonSet Pod 가 1/2 CrashLoopBackOff 이고 이벤트에 아래 경고가 있다.
Warning MissingIAMPermissions aws-node
Unauthorized operation: failed to call ec2:DescribeNetworkInterfaces due to missing permissions.
VPC CNI 는 노드 IAM Role(또는 IRSA/Pod Identity) 로 EC2 API 를 호출해 ENI 를 붙인다. 권한이 없으면 IPAMD 가 Checking for IPAM connectivity... 에서 멈춰 gRPC 50051 을 열지 못하고 프로브 실패로 재시작을 반복한다.
kubectl get nodes -o wide
kubectl describe node <node>
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 <aws-node-pod>
kubectl -n kube-system logs <aws-node-pod> -c aws-node --tail=200
kubectl -n kube-system logs <aws-node-pod> -c aws-node --previous --tail=200
kubectl -n kube-system logs <aws-node-pod> -c aws-eks-nodeagent --tail=100
aws eks describe-addon --cluster-name <cluster> --addon-name vpc-cni --region ap-northeast-2 \
--query 'addon.{Version:addonVersion,SARoleArn:serviceAccountRoleArn,PodIdentity:podIdentityAssociations,Status:status}'
aws-node 컨테이너는 distroless 라 kubectl exec ... env 가 안 된다. 환경변수는 kubectl get pod <pod> -o jsonpath='{.spec.containers[?(@.name=="aws-node")].env}' 로 본다.
로그 메시지별 원인은 다음과 같다. failed to assign an IP address 는 서브넷 IP 부족, UnauthorizedOperation/AccessDenied 는 IAM, ImagePullBackOff 는 NAT/VPC Endpoint 부재, failed to communicate with API server 는 노드 SG 와 클러스터 SG 사이 443 차단이다.
SDK 는 IRSA 나 Pod Identity 가 있으면 노드 Role 보다 먼저 쓴다. 노드 Role 에 정책이 있어도 무시될 수 있다.
kubectl -n kube-system describe sa aws-node # eks.amazonaws.com/role-arn 어노테이션
aws eks list-pod-identity-associations --cluster-name <cluster> --region ap-northeast-2
aws eks describe-nodegroup --cluster-name <cluster> --nodegroup-name <ng> --region ap-northeast-2 --query 'nodegroup.nodeRole'
aws iam list-attached-role-policies --role-name <node-role> --query 'AttachedPolicies[].PolicyName'
| 상태 | 조치 |
|---|---|
| SA 에 IRSA 어노테이션이 있다 | 그 Role 에 AmazonEKS_CNI_Policy 를 붙이고 Trust Policy 가 클러스터 OIDC 와 system:serviceaccount:kube-system:aws-node 를 허용하는지 확인 |
| Pod Identity 연결이 있다 | 매핑된 Role 에 정책 부착, eks-pod-identity-agent DaemonSet 정상 여부 확인 |
| 둘 다 없다 | 노드 Role 에 AmazonEKSWorkerNodePolicy · AmazonEC2ContainerRegistryReadOnly · AmazonEKS_CNI_Policy 세 개가 모두 있어야 한다 |
aws iam attach-role-policy --role-name <node-role> --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
kubectl -n kube-system rollout restart ds/aws-node
노드 Role 에 정책이 이미 있는데도 거부된다면 Permissions Boundary(aws iam get-role ... --query 'Role.PermissionsBoundary'), Organizations SCP, IMDS hop limit(컨테이너에서 IMDS 를 쓰려면 HttpPutResponseHopLimit 2 이상) 을 의심한다. 노드에 Session Manager 로 들어가 aws sts get-caller-identity 와 aws ec2 describe-network-interfaces 를 직접 호출해 보면 노드와 Pod 중 어디서 거부되는지 갈린다. bastion 에 session-manager-plugin 이 없으면 yum install -y https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm 으로 설치하거나 EC2 콘솔의 연결 → Session Manager 를 쓴다.
노드 Role 에 AmazonEKS_CNI_Policy 가 이미 있었고 IRSA · Pod Identity 는 없었는데도 거부됐다가, 별도 조치 없이 약 한 시간 뒤 노드가 Ready 로 돌아왔다. eksctl 이 Role 과 인스턴스를 거의 동시에 만들면서 STS 가 캐시한 자격증명에 새 정책이 반영되기까지 IAM 전파가 지연된 것으로 추정된다. 재발 방지로는 aws-node SA 에 IRSA 를 붙이고 노드 Role 에서 EC2 권한을 빼는 구성이 권장된다.