파드의 아웃바운드 트래픽 흐름
1. DNS 질의 (CoreDNS → 외부 DNS)
-
파드 안 애플리케이션이
api.github.com요청 → CoreDNS로 DNS 질의 -
CoreDNS가
/etc/resolv.conf에 지정된 상위 DNS(예: 구글 8.8.8.8, 클라우드 제공 DNS)로 포워딩 → IP 획득 후 파드에 응답→ 이렇게 해서 파드가 목표 서버의 IP 주소를 알게 됩니다.
2. CNI 플러그인의 역할 (네트워크 레벨 L3 + NAT)
-
파드 IP 특징: Pod는 클러스터 내부 전용의 사설 IP (예: 10.x, 192.168.x).
외부 인터넷에서 이 IP를 알지도 못하고 도달할 수도 없습니다.
-
*CNI 플러그인(Calico, Flannel, Cilium 등)**은 파드 네트워크를 관리합니다.
- 라우팅(L3): 파드 → 노드 인터페이스로 트래픽 전달
- NAT(Masquerade): iptables(or nftables)를 이용해 소스 IP를 Pod IP → Node IP로 변환
- 이 과정을 SNAT(Source NAT)라고 합니다.
- 외부에서 볼 때는 “노드에서 요청이 들어온 것”처럼 보입니다.
3. 외부 통신 (노드 IP로 송신)
- 변환된 패킷은 이제 노드의 공인 IP를 소스로 해서 인터넷을 나갑니다.
- 외부 서버(
api.github.com) 입장에서는 → 단일 노드 IP에서 요청이 온 것처럼 보임. - 응답이 돌아오면, 노드의 NAT 테이블이 이를 다시 찾아서 → 원래 파드로 전달합니다.
4. kube-proxy와의 관계
- kube-proxy는 **클러스터 내부 서비스(ClusterIP, NodePort, LoadBalancer 등)**로 인바운드/내부 요청을 분배하는 역할입니다.
- 즉,
파드 → 외부방향의 아웃바운드 요청에는 직접 개입하지 않습니다. - 아웃바운드는 CNI 플러그인 + iptables NAT가 핵심입니다.
🔹 트래픽 요약 흐름
[Pod] --DNS Query--> [CoreDNS] --forward--> [외부 DNS]
[Pod] --패킷--> [CNI 네트워크] --L3 라우팅--> [Node]
[Node] --SNAT(Masquerade)--> [Node Public IP]
[Internet] <---> [외부 서버(api.github.com)]
[Node] --DNAT(reverse)--> [Pod]
+-----------------+ +-------------+ +------------------+ +-------------------+
| Pod | | CoreDNS | | Node (NAT) | | External Server |
| (10.244.x.x IP) | | (ClusterIP) | | (Public IP 보유) | | api.github.com |
+-----------------+ +-------------+ +------------------+ +-------------------+
| | | |
| 1. DNS Query | | |
|----------------------->| | |
| | 2. Forward to 외부 DNS | |
| |------------------------>| (ex. 8.8.8.8) |
| |<------------------------| |
|<-----------------------| | |
| (IP 주소 응답) | | |
| | | |
| 3. 패킷 송신 | | |
|----------------------->| (CNI L3 라우팅) | |
| |------------------------>| |
| | | |
| | 4. SNAT (Pod→Node IP) | |
| |------------------------>|-------------------------->|
| | | 5. 요청 전달 |
| | | |
| | |<--------------------------|
| | 6. DNAT (역변환) | |
|<-------------------------------------------------| |
| 7. 응답 전달 | | |
| | | |
┌─────────────┐
│ Pod │ (예: 10.244.0.5)
│ App 프로세스 │
└──────┬──────┘
│
│ 패킷 생성 (src=10.244.0.5, dst=api.github.com)
▼
┌─────────────┐
│ CNI 계층 │ (가상 네트워크, veth pair, bridge 등)
│ L3 라우팅 │
└──────┬──────┘
│
│ 패킷 전달
▼
┌─────────────┐
│ Node │ (예: 192.168.0.10)
│ iptables NAT│
└──────┬──────┘
│
│ SNAT 수행
│ src=192.168.0.10 (공인/사설 IP) 로 변경
▼
┌─────────────┐
│ Internet │
│ 외부 서버 │ (예: api.github.com / 140.82.x.x)
└─────────────┘
🔹 추가 이해 포인트
-
Pod 간 통신(동일 클러스터 내부) → NAT 불필요 (CNI가 직접 라우팅)
-
Pod → 외부 인터넷 통신 → NAT 필요 (노드 공인 IP 사용)
-
외부 → Pod 직접 접근 → 불가능 (ClusterIP는 내부 전용).
이 경우 **Service(NodePort/LoadBalancer/Ingress)**가 필요합니다.
👉 질문 주신 정리 그대로 맞는데, 핵심 차이를 딱 정리하면:
- CoreDNS는 “도메인 → IP” 변환
- CNI + NAT는 “Pod 사설 IP → Node 공인 IP” 변환
- kube-proxy는 “외부에서 들어오는 요청 → 내부 파드 분배”
혹시 원하시면 제가 이 과정을 패킷 이동 다이어그램으로 텍스트 그림(Pod → Node → NAT → 외부) 만들어드릴까요?
Comments
💬 Sign in with GitHub to leave a comment. Comments are public and stored in GitHub Discussions.