https://docs.tigera.io/calico/latest/about/kubernetes-training/about-networking
About Networking | Calico Documentation
Learn about networking!
docs.tigera.io
https://nangman14.tistory.com/108
Kubernetes 환경에서 발생하는 DNS Query Failed 이슈와 NodeLocal DNSCache를 이용한 해결
Kubernetes 환경에서 서비스를 운영하다보면 예상치 못한 이슈를 종종 발견하게 됩니다. 특히 대규모의 트래픽을 부담해야 하거나 구동 중인 애플리케이션이 많은 경우처럼 Cluster의 크기가 거대해
nangman14.tistory.com
쿠버네티스 Service(ClusterIP)는 가상 IP(VIP)를 사용한다. 이 VIP로 전송된 패킷이 실제 Pod IP로 도달하기까지의 과정은 리눅스 커널의 규칙(iptables, Route Table)에 의해 결정된다.
본 문서는 핵심 네트워크 이론과 기본 문법을 먼저 정리하고, curl <Service-IP> 명령 수행 시 발생하는 패킷의 여정을 커널 로그를 통해 단계별로 검증한다.
핵심 이론
단순한 개념 정의가 아니라, 실제 운영 환경에서 장애를 유발하는 커널 레벨의 동작 원리를 먼저 짚는다.
(1) 계층별 역할 분담 (OSI 7 Layer)
- L3 (Network Layer): CNI(Calico)의 영역이다. ip route 테이블을 조작하여 파드 간 통신 Routing을 생성한다.
- L4 (Transport Layer): kube-proxy(iptables)의 영역이다. Service VIP를 실제 Pod IP로 변환(DNAT)한다. 이 과정에서 NAT 트래픽이 과도할 경우 conntrack 테이블이 가득 차 패킷 드랍이 발생할 수 있다.
리눅스 Conntrack 테이블

- 리눅스 conntrack 테이블은 Netfilter가 네트워크 연결 상태를 추적하는 커널 해시테이블이다.
- 각 TCP/UDP/SCTP 연결을 5-tuple(srcIP:srcPort-dstIP:dstPort:proto)로 식별하고 상태를 기록한다.
- Stateful firewall, NAT의 핵심으로, ESTABLISHED,RELATED 패킷은 자동 허용하고 리턴트래픽은 자동 DNAT/SNAT 처리한다
(2) Overlay Network (Calico -> IPIP)
도커를 공부한 사람이면 도커 브릿지 네트워크에 대해서 들어봤을 것이다.

도커 Bridge 네트워크
- 각 호스트에서 docker0 브릿지 생성 → 컨테이너 veth pair를 브릿지에 붙인다.
- 호스트 간 통신 불가하다. 호스트1 컨테이너가 호스트2 컨테이너 접근하려면 외부 라우터 필요하므로 분산 시스템에서는 비효율적이다.
Overlay 네트워크 동작
- VXLAN 터널링: 호스트1 eth0 ↔ 호스트2 eth0 간 VXLAN 패킷으로 컨테이너 트래픽 캡슐화.
- 각 호스트의 CNI가 VTEP(VXLAN Tunnel End Point) 역할 → 컨테이너 IP(overlay 네트워크 CIDR)를 직접 라우팅.
- 컨테이너가 같은 L2 도메인처럼 동작하지만 실제로는 L3 오버레이가 되는 방식이다
VXLAN 패킷 구조

- 물리 네트워크(Underlay) 위에 가상의 네트워크(Overlay)를 깐다.
- 원본 패킷(Inner)을 다른 패킷(Outer)으로 감싸서(Encapsulation) 보낸다.
(3) NAT와 DNS 장애의 상관관계

K8s 통신은 NAT에 크게 의존한다.
- SNAT (Source NAT): Pod가 외부와 통신할 때 Node IP로 마스커레이딩(Masquerading)한다. 이때 포트 고갈이나 conntrack 이슈 발생 시, 외부 DNS 질의(UDP)가 실패하여 Unknown Host 에러가 발생한다.
- DNAT (Destination NAT): Service VIP를 Pod IP로 변환하는 기술로, 아래 분석 과정의 핵심이다.
리눅스 커널 iptables, ip route 기본 문법
로그 분석에 앞서, 패킷 제어의 핵심인 iptables와 ip route의 기초 문법을 정리한다.
(1) iptables 문법 기초 (Netfilter)
리눅스 커널 방화벽이자 패킷 조작 도구다. K8s Service의 LoadBalancing과 DNAT가 여기서 수행된다.
- A (Append): 규칙을 추가한다.
- s (Source) / d (Destination): 출발지 IP / 목적지 IP.
- j (Jump): 조건이 맞으면 어디로 갈지 타겟을 정한다.
- DNAT: 목적지 주소를 바꾼다. (Destination NAT)
- SNAT: 출발지 주소를 바꾼다. (Source NAT)
- MASQUERADE: 나가는 인터페이스의 IP로 변장한다. (동적 SNAT)
- 체인이름: 다른 체인(규칙 묶음)으로 이동한다.
(2) ip route 문법 기초
패킷의 이동 경로를 지정하는 라우팅 테이블이다. CNI(Calico)가 Pod IP의 경로를 설정하는 주 무대다.
- default via <GW>: 기본 게이트웨이. 모르는 곳은 다 여기로 보낸다.
- <IP> dev <Interface>: 특정 IP로 가기 위한 인터페이스 지정.
- scope link: 해당 대역이 직접 연결(L2)되어 있음을 의미(게이트웨이 불필요).
3. 분석 환경 및 시나리오
Calico CNI (IPIP)로 minikube 클러스터를 띄운 모습이다.

이제 위 이론들이 실제 커널에서 어떻게 동작하는지 로그로 확인한다.
서비스를 띄웠는데 10.109.60.134로 올라간것을 확인할 수 있다.

파드의 IP는 Calico(CNI)가 가상 IP 10.244.120.67로 할당해준것을 볼 수 있다.

실제로 컨테이너 내부 VNIC에 해당 IP를 할당 받은것을 알수 있다 서브넷 마스크 /32인것을 봐서 해당 서브넷에 이웃이 없고 기본 게이트웨이로 던질 수 밖에 없게 한다.
그리고 외부의 인터페이스 17이다. 파드의 11번은 → 노드의 17번을 가리킨다.

4. kube-proxy와 iptables (목적지 변환)
클라이언트가 Service IP로 요청을 보내면, 호스트의 iptables 규칙이 패킷을 가로챈다.
패킷 흐름은 KUBE-SERVICES → KUBE-SVC-xxx → KUBE-SEP-xxx 순서로 진행된다.
생성한 서비스에 대한 iptables 조회

KUBE-SERVICES 포착
목적지(-d)가 Service VIP(10.109.60.134)인 경우, KUBE-SVC-... 체인으로 점프(-j)한다. 아직 목적지 IP는 변경되지 않았다.
로드밸런싱: KUBE-SVC (Service Chain)
- A KUBE-SVC-BE5LIK4X2OAKIEFX -m comment --comment "default/numbers-api -> 10.244.120.67:80" -j KUBE-SEP-E4SSCTGR3GJGHN43
- 해석: 로드밸런싱을 담당하는 체인이다. Pod가 여러 개일 경우 statistic mode random을 통해 확률적으로 분기된다. 본 케이스는 단일 Pod이므로 즉시 KUBE-SEP-... 체인으로 이동한다.
DNAT 수행: KUBE-SEP (Service EndPoint)
핵심 단계다. 가상 IP가 실제 IP로 변환된다.
- A KUBE-SEP-E4SSCTGR3GJGHN43 -p tcp -m comment --comment "default/numbers-api" -m tcp -j DNAT --to-destination 10.244.120.67:80
- j DNAT: Destination NAT를 수행한다.
- -to-destination 10.244.120.67:80: 패킷의 목적지를 실제 Pod IP로 덮어쓴다.
- 결과: 패킷의 목적지는 이제 10.109.60.134가 아닌 10.244.120.67이다. Service(kube-proxy)의 역할은 여기서 종료된다.
5. CNI(Calico)와 Route Table (경로 탐색)
목적지 IP는 변경되었으나, 리눅스 커널은 사설 IP인 Pod의 위치를 알지 못한다. 이때 CNI(Calico)가 사전에 설정해 둔 Routing Table이 사용된다.
라우팅 테이블 조회

- 10.244.120.67: 목적지 Pod IP (/32 Host Route).
- dev cali693e13cd073: 해당 IP로 가기 위해서는 cali693... 인터페이스로 패킷을 전송해야 한다.
- 의미: Calico는 Pod 생성 시마다 호스트 라우팅 테이블에 해당 Pod로 향하는 경로를 개별적으로 등록한다.
6. Veth Pair (IPIP 방식을 사용한 Pod 내부 진입)

호스트의 cali693... 인터페이스에 전달된 패킷은 어떻게 격리된 네트워크 네임스페이스(Pod) 내부로 진입하는가?
Veth Pair(Virtual Ethernet Pair)가 호스트와 컨테이너를 연결하는 파이프 역할을 수행한다.
ip link 명령어를 통해 인터페이스 인덱스(Index)를 대조하여 연결 관계를 증명했다.
호스트(Node) 측 인터페이스

- 인덱스 번호는 17번이다.
- @if11은 "연결된 반대편 인터페이스 인덱스가 11번임"을 의미한다.
Pod 내부 인터페이스

- Pod 내부 eth0의 인덱스는 11번이다.
- @if17은 "연결된 반대편 인터페이스 인덱스가 17번임"을 가리킨다.
노드의 17번은 → 파드의의 11번을 가리킨다.
즉 노드 17 ↔ 파드 11번이 연결된것이므로 오버레이네트워크 파이프가 생성된것이다.
- 커널이 Routing Table을 참조하여 패킷을 17번 인터페이스(cali...)로 보낸다.
- 패킷은 Veth Pair를 타고 Pod 내부의 11번 인터페이스(eth0)로 전달된다.
- 애플리케이션이 요청을 수신한다.
정리
- DNS: Service 이름을 VIP로 변환.
- Service (iptables): VIP를 목적지로 설정 시 커널이 DNAT(목적지 변환) 수행.
- CNI (Calico): 변환된 Pod IP를 Routing Table에서 찾아 해당 인터페이스(cali...)로 전달.
- Veth Pair: 파이프를 통해 Pod 내부(eth0)로 진입.
이 흐름 중 어느 한 곳이라도 끊기면 장애가 발생한다. Connection Refused가 iptables 문제인지, Timeout이 Route 문제인지 구분할 수 있는 시야, 그것이 엔지니어의 핵심 역량이다.
'System Engineering > Kubernetes (쿠버네티스)' 카테고리의 다른 글
| Embedded iPaaS 아키텍처를 위한 멀티 테넌시 격리 전략과 쿠버네티스 리소스 제어 (1) | 2025.12.27 |
|---|---|
| [istio] 쿠버네티스 이스티오 설치 및 프로필과 애드온 설정 (3) | 2025.08.08 |
| [istio] 쿠버네티스 이스티오와 envoy 프록시 개념과 동작 원리 (2) | 2025.08.08 |
| [minikube] 쿠버네티스 헬름(helm) 개념과 사용법, helm 차트 편집 방법 (1) | 2025.08.07 |
| [minikube] 쿠버네티스 스테이트풀셋(StatefulSet) 개념과 용도 (2) | 2025.08.06 |
댓글