[CloudNeta] EKS 워크샵 스터디 (2) - EKS Networking - iptables NAT 체인 정리

이 문서는 [[2주차 - EKS Networking]] 실습 중 확인한 iptables -t nat 규칙의 체인별 역할을 정리합니다.

iptables NAT 체인 정리

EKS 워커 노드의 iptables -t nat 테이블에는 AWS VPC CNI가 관리하는 체인과 kube-proxy가 관리하는 체인이 공존합니다.

AWS VPC CNI 체인

체인 역할
AWS-SNAT-CHAIN-0 VPC 외부로 나가는 트래픽의 출발지를 노드 IP로 SNAT. VPC 내부(192.168.0.0/16)는 RETURN으로 건너뜀
AWS-CONNMARK-CHAIN-0 파드에서 외부로 나간 트래픽에 0x80 마크를 찍어둠. 돌아오는 응답 패킷을 추적하기 위함

kube-proxy 체인

체인 역할
KUBE-SERVICES 진입점. ClusterIP로 들어온 패킷을 해당 Service의 KUBE-SVC-* 체인으로 분기
KUBE-SVC-* Service 단위 체인. --probability로 여러 파드에 균등 분배 (로드밸런싱)
KUBE-SEP-* Service Endpoint 체인. 실제 파드 IP:Port로 DNAT 수행
KUBE-NODEPORTS NodePort 타입 Service 트래픽 처리. NodePort Service가 없으면 비어있음
KUBE-MARK-MASQ 헤어핀 트래픽[1]0x4000 마크를 찍음
KUBE-POSTROUTING 0x4000 마킹된 패킷에 MASQUERADE 적용
KUBE-KUBELET-CANARY kubelet 활성 상태 확인용 빈 체인[2]
KUBE-PROXY-CANARY kube-proxy 활성 상태 확인용 빈 체인[2:1]

패킷 흐름 예시

Service 접근 시

예: coredns Service(10.100.0.10:53)에 DNS 요청

PREROUTING
  → KUBE-SERVICES (ClusterIP 매칭)
    → KUBE-SVC-TCOU7JCQXEZGVUNU (kube-dns:dns 체인)
      → (50%) KUBE-SEP-A66D6VN7ZJSNMAM6 → DNAT 192.168.10.233:53
      → (50%) KUBE-SEP-WB6TFUZR7TOT5QYJ → DNAT 192.168.2.141:53

KUBE-SVC-*에서 --probability로 2개 파드에 50%씩 분배합니다. 파드가 3개면 33%/33%/34% 식으로 분배됩니다.

파드 → VPC 외부(인터넷) 통신 시

POSTROUTING
  → KUBE-POSTROUTING (0x4000 마크 없으면 RETURN)
  → AWS-SNAT-CHAIN-0
    → 목적지가 VPC 내부(192.168.0.0/16)? → RETURN (SNAT 안 함)
    → 목적지가 VPC 외부? → SNAT --to-source <노드 IP>

VPC 내부 통신은 파드 IP 그대로, 외부 통신만 노드 IP로 SNAT됩니다.

파드 → VPC 내부 통신 시

POSTROUTING
  → AWS-SNAT-CHAIN-0
    → 목적지가 192.168.0.0/16 → RETURN

SNAT 없이 파드 IP 그대로 통신합니다. VPC CNI의 핵심 장점입니다.

용어 정리

용어 의미
SNAT (Source NAT) 패킷의 출발지 IP를 변환. 파드 IP → 노드 IP
DNAT (Destination NAT) 패킷의 목적지 IP를 변환. ClusterIP → 파드 IP
MASQUERADE SNAT의 동적 버전. 나가는 인터페이스의 IP로 자동 SNAT
CONNMARK 연결(connection)에 마크를 찍어 응답 패킷을 추적
RETURN 현재 체인을 빠져나가 상위 체인으로 돌아감 (규칙 스킵)

  1. 헤어핀 트래픽: 파드가 자기 자신이 속한 Service의 ClusterIP로 요청을 보내, 결국 자기 자신에게 돌아오는 경우. 출발지/도착지가 같아지므로 MASQUERADE로 출발지를 노드 IP로 바꿔야 응답이 정상 라우팅됩니다. ↩︎

  2. CANARY 체인은 규칙이 비어있으며, 해당 컴포넌트가 iptables 규칙을 정상적으로 관리하고 있는지 확인하는 용도입니다. 이 체인이 존재하면 "해당 컴포넌트가 살아있다"는 의미입니다. ↩︎ ↩︎