- Published on
EKS Pod 간 통신 불가? CNI·SGP·NACL 점검법
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
EKS에서 Pod 간 통신이 안 될 때 가장 흔한 함정은 "Kubernetes 네트워크 문제"로 뭉뚱그려 보다가, 실제 원인인 VPC 레벨 제어(보안그룹, NACL)나 CNI 설정을 놓치는 것입니다. 특히 AWS VPC CNI를 쓰는 EKS는 Pod IP가 VPC의 Secondary IP로 할당되기 때문에, 이슈의 절반은 Kubernetes 내부가 아니라 AWS 네트워킹 계층에서 발생합니다.
이 글은 Pod A -> Pod B 통신이 실패하는 상황을 기준으로, 원인을 CNI -> SGP(또는 Node SG) -> NACL/라우팅 순서로 좁히는 실전 점검 루트를 정리합니다.
- 같은 노드의 Pod끼리만 통신 실패/성공하는지
- 다른 노드의 Pod끼리만 통신 실패/성공하는지
- DNS만 실패하는지, TCP/ICMP까지 전부 실패하는지
이 3가지만 먼저 분류해도 디버깅 시간이 크게 줄어듭니다.
1) 증상 분류: 먼저 “어디까지” 안 되는지 확인
1-1. 최소 재현용 디버그 Pod 준비
네트워크 문제는 애플리케이션 컨테이너가 아니라 진단 전용 Pod로 확인하는 게 빠릅니다.
kubectl run netshoot -it --rm \
--image=nicolaka/netshoot \
--restart=Never -- bash
대상 Pod의 IP를 확인합니다.
kubectl get pod -o wide
1-2. DNS, L3, L4를 단계적으로 테스트
- DNS 확인
nslookup kubernetes.default.svc.cluster.local
- Pod IP로 L3/L4 확인(서비스가 열려있다는 가정)
# TCP 포트 확인
nc -vz 10.0.12.34 8080
# HTTP 확인
curl -sv http://10.0.12.34:8080/health
만약 Service로는 되는데 Pod IP로는 안 된다면, kube-proxy/iptables 계층 또는 보안그룹/SGP 정책 차단 가능성이 큽니다. 반대로 Pod IP는 되는데 Service가 안 되면, Endpoints/Selector/kube-proxy를 의심하세요.
2) EKS 네트워킹 핵심: AWS VPC CNI 구조 이해
EKS 기본 CNI인 aws-vpc-cni는 Pod에게 VPC IP를 직접 할당합니다.
- Node(EC2)의 ENI에
Secondary IP를 붙임 - Pod는 그
Secondary IP를 사용 - 따라서
Pod -> Pod트래픽도 VPC 라우팅/보안정책의 영향을 직접 받음
이 구조 때문에 다음이 자주 발생합니다.
- Pod IP 고갈로 새 Pod가 뜨지 않거나, 특정 노드에서만 통신 이상
- Security Group 규칙이
Node SG기준으로만 열려 있어 Pod 단위 제어(SGP)에서 막힘 - NACL이
Ephemeral Port를 막아 리턴 트래픽이 드랍됨
3) CNI 점검: IP 할당/라우팅/노드별 이상 유무 확인
3-1. aws-node 상태 확인
kubectl -n kube-system get ds aws-node -o wide
kubectl -n kube-system get pods -l k8s-app=aws-node -o wide
크래시/재시작이 많거나 특정 노드에서만 aws-node가 비정상이라면, 그 노드에서 뜬 Pod들끼리 또는 외부 통신이 이상해질 수 있습니다.
로그도 확인합니다.
kubectl -n kube-system logs -l k8s-app=aws-node --tail=200
3-2. Pod가 실제로 어떤 IP를 받았는지, 노드의 ENI 여유가 있는지
Pod IP가 VPC 대역인지 확인합니다.
kubectl get pod -A -o wide | head
노드에서 ENI/IP가 부족하면 Pod가 뜨더라도 네트워크가 불안정하거나, 특정 노드에만 장애가 집중됩니다. EKS에서는 인스턴스 타입별로 ENI 및 IP 한도가 정해져 있습니다.
운영에서 자주 쓰는 대응은 다음 중 하나입니다.
- 노드 인스턴스 타입 상향(ENI/IP 한도 증가)
- 노드 수 확장(스케줄링 분산)
prefix delegation활성화(가능한 환경에서 IP 효율 개선)
3-3. ENABLE_POD_ENI / WARM_IP_TARGET 등 환경변수 확인
aws-node 데몬셋의 환경변수 설정이 의도치 않게 바뀌면, 특정 시점 이후부터 통신/할당 문제가 생길 수 있습니다.
kubectl -n kube-system describe ds aws-node | sed -n '1,200p'
특히 WARM_IP_TARGET, MINIMUM_IP_TARGET는 IP 선할당 전략을 바꾸므로, 트래픽 급증/스케일아웃 시점에만 문제가 터지는 패턴을 만들 수 있습니다.
4) SGP(Security Group for Pods) 점검: “Pod 단위 SG”가 트래픽을 막는 경우
4-1. SGP가 켜져 있는지 확인
SGP는 Pod에 별도 보안그룹을 적용하는 기능입니다. 켜져 있으면 Node SG를 열어도 Pod 트래픽이 막힐 수 있습니다.
대표적인 증상:
- 같은 네임스페이스/같은 노드에서도 특정 Pod만 통신 불가
- 노드 SG는 넉넉히 열려 있는데 Pod 단위로만 차단
클러스터 애드온/설정에 따라 다르지만, 보통은 다음을 확인합니다.
- 해당 Pod에 어떤 SG가 붙었는지(라벨/어노테이션 또는 CRD 기반)
- 붙은 SG 인바운드/아웃바운드에
상대 Pod CIDR또는상대 SG가 허용돼 있는지
4-2. Pod에 붙은 보안그룹 확인(개념적 체크)
환경마다 SGP 적용 방식이 달라 kubectl만으로 100% 동일하게 보긴 어렵습니다. 다만 공통적으로 다음을 확인하면 원인을 좁힐 수 있습니다.
SecurityGroupPolicy리소스 존재 여부
kubectl get securitygrouppolicies.vpcresources.k8s.aws -A
kubectl describe securitygrouppolicies.vpcresources.k8s.aws -A | sed -n '1,200p'
- 대상 Pod가 정책 셀렉터에 매칭되는지
kubectl get pod mypod -n myns --show-labels
4-3. SGP에서 가장 많이 놓치는 규칙
- 인바운드만 열고 아웃바운드를 제한해
응답 트래픽이 막힘 - 허용 대상을
CIDR로 잘못 지정(예: 노드 서브넷만 열고 Pod 대역을 누락) Pod -> Pod는 되는데Pod -> CoreDNS가 막혀 DNS만 실패
DNS만 실패할 때는 CoreDNS Pod IP 또는 CoreDNS가 위치한 노드/서브넷으로의 통신이 막혔는지부터 확인하세요.
5) NACL 점검: “리턴 트래픽”이 드랍되는 전형적인 케이스
보안그룹(SG)은 stateful이라 응답 트래픽이 자동 허용되지만, NACL은 stateless라 인바운드/아웃바운드 모두 명시적으로 열어야 합니다.
Pod 간 통신에서 NACL이 문제일 때 흔한 패턴은 이렇습니다.
- SYN은 나가는데 SYN-ACK가 돌아오지 않음
- 특정 서브넷 간 통신만 실패
- 특정 포트만 실패(특히
Ephemeral Port범위)
5-1. NACL에서 확인할 것
- 양쪽 서브넷의 NACL 규칙
- 인바운드/아웃바운드 모두 허용인지
Ephemeral Port(대개1024-65535)가 열려 있는지
예를 들어 Pod A가 8080으로 접속해도, 클라이언트 측 소스 포트는 임의의 high port가 됩니다. NACL이 이 구간을 막으면 "요청은 갔는데 응답이 안 오는" 형태가 됩니다.
6) 라우팅/서브넷/노드 보안그룹(Node SG) 기본 점검
SGP를 쓰지 않는다면 기본적으로 Node SG가 Pod 트래픽의 관문이 됩니다.
6-1. Node SG에서 확인할 것
- 노드 간 통신 허용(자기 자신 SG 참조 인바운드 허용이 일반적)
- 노드가 속한 서브넷 대역 간 라우팅 정상 여부
실무에서 자주 보는 실수:
- 워커 노드 SG 인바운드에
클러스터 CIDR이 아니라관리자 사무실 IP만 열어둠 - 서로 다른 노드 그룹이 서로 다른 SG를 쓰는데, SG 간 참조 규칙이 빠짐
7) Kubernetes 레벨에서 놓치기 쉬운 원인: NetworkPolicy
EKS 자체는 기본적으로 NetworkPolicy를 강제하지 않지만, Calico 등 네트워크 플러그인/정책 엔진을 붙이면 Pod 간 통신이 정책으로 막힐 수 있습니다.
다음으로 빠르게 확인합니다.
kubectl get networkpolicy -A
kubectl describe networkpolicy -n myns | sed -n '1,200p'
특히 default deny가 있으면, 허용 정책이 없는 Pod는 전부 막힙니다.
8) 현장용 체크리스트: 10분 안에 원인 좁히기
아래 순서대로 보면 대부분의 케이스가 잡힙니다.
kubectl get pod -o wide로 통신 실패 Pod들의 노드/서브넷 분포 확인- 디버그 Pod에서
curl/nc로Pod IP직접 타격 aws-node상태/로그 확인(특정 노드만 이상한지)- SGP 사용 여부 확인, 해당 Pod에 정책이 매칭되는지 확인
- Node SG 규칙에서
SG self-reference또는 상호 SG 허용 확인 - 양쪽 서브넷 NACL에서
Ephemeral Port포함 인/아웃바운드 허용 확인 - NetworkPolicy 존재 여부 및 default deny 확인
9) 트러블슈팅에 유용한 커맨드 모음
9-1. Endpoints가 제대로 잡혔는지
Service로는 안 되는데 Pod IP로는 된다면 이것부터 봅니다.
kubectl get svc -n myns
kubectl get endpoints -n myns myservice -o yaml
9-2. CoreDNS 상태
DNS만 이상하면 CoreDNS가 건강한지부터 확인합니다.
kubectl -n kube-system get deploy coredns
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide
kubectl -n kube-system logs deploy/coredns --tail=200
10) 마무리: “CNI, SGP, NACL”을 한 묶음으로 보자
EKS에서 Pod 간 통신 문제는 Kubernetes 리소스만 보고 해결하기 어렵습니다. AWS VPC CNI 구조상 Pod가 VPC의 일급 시민이기 때문에, 다음 3가지를 세트로 점검해야 합니다.
- CNI: IP 할당/노드별 ENI·IP 여유/
aws-node상태 - SGP: Pod 단위 SG가 의도치 않게 트래픽을 차단하는지
- NACL: stateless 특성으로 인해 응답 트래픽이 드랍되는지
비슷한 클라우드/Kubernetes 운영 이슈를 다룬 글로는, 장애 상황에서 원인 범위를 빠르게 좁히는 관점에서 Azure AKS에서 Pod가 Terminating에 멈출 때 해결법, EKS 운영에서 IAM/인증 계층 복구 경험을 정리한 EKS OIDC Provider 삭제로 IRSA 전부 실패했을 때 복구, 배포 파이프라인에서 상태 불일치를 빠르게 해소하는 Argo CD Sync 실패 - OutOfSync·Degraded 해결법도 함께 보면 운영 관점의 디버깅 루틴을 잡는 데 도움이 됩니다.
원하시면 다음 정보를 기준으로 당신의 환경에 맞춘 체크 순서(예: SGP 사용 여부, 프라이빗 서브넷/NAT 구성, 노드 그룹 분리 여부)를 더 구체화해 드릴 수 있습니다.
- CNI 모드(
prefix delegation사용 여부) - SGP 사용 여부
- 통신 실패가
같은 노드에서도 발생하는지 - 실패 대상이
Pod IP인지Service인지 - NACL 커스텀 적용 여부