kube-proxy

정의

- Service IP -> Pod IP 변환 규칙을 관리하는 컴포넌트

- 각 Node에 DaemonSet으로 배포

하는 일

1. API 서버를 watch하여 서비스가 Service/EndpointSlice 변경 감지

2. DNAT 규칙 등록 (Service ClusterIP -> 실제 Pod IP)

3, LB 규칙 등록 (백엔드 Pod 여러 개일 때 분산)

4. NodePort 규칙 등록

5. SNAT/MASQUERADE 규칙 등록 (Pod -> 외부 통신, NodePort 크로스 노드)

6. Service/Pod 삭제 시 규칙 정리

Service 통신 흐름

1. Pod이 "mey-service"로 DNS 질의

2. coreDNS가 ClusterIP "10.3.241.152" 응답

3. Pod이 "10.3.241.152:80"으로 패킷 전송

4. 패킷이 "veth -> eni0 -> 호스트 커널"로 올라감

5. netfilter가 iptables 규칙 확인 -> DNAT으로 목적지를 "10.0.2.2:8080"으로 변환

6. 커널 라우팅 테이블 확인 -> "10.0.2.0/24 -> Node B(192.168.60.3)"

7. eth0을 통해 Node B로 전송

8. Node B의 eth0 -> cni0 브리지 -> veth -> 목적지 Pod 도달

동작 모드

[ userspace (v1.2 이전) ]
1. netfilter가 패킷을 kube-proxy 프로세스로 리다이렉트

2. kube-proxy가 직접 백엔드 Pod 선택하고 새 연결 생성하여 전달

3. 커널 -> 유저스페이스 -> 커널 왕복으로 컨텍스트 스위칭 오버헤드 큼
[ iptables (기본) ]
1. kube-proxy는 규칙만 등록하고 트래픽 경로에서 빠짐

2. netfilter가 커널에서 바로 DNAT 처리

3. random 확률 기반 로드밸런싱만 가능
[ IPVS ]
1. 커널의 IPVS 모듈이 DNAT + 로드밸런싱 처리

2. 해시 테이블(O(1))로 대규모 성능 우수

3. rr, lc, wrr, wlc, sh, dh 등 다양한 알고리즘 지원

4. 단 SNAT은 여전히 iptables 필요

DNAT이 필요한 이유

- Service IP는 가상 IP라 실제 네트워크에 존재하지 않음

- Pod는 죽으면 IP가 바뀌므로 고정되 Service IP를 두고 뒤에서 실시간으로 살아있는 Pod IP로
	변환

SNAT이 발생하는 경우

1. Pod -> 클러스터 외부 통신
	- 출발지를 노드 IP로 변환 (외부는 Pod CIDR을 모르므로)

2. NodePort 크로스 노드
	- 요청 도착 노드와 Pod이 다른 노드에 있을 때 출발지 요청 도착 노드 IP로 변환
		=> 안하면 4-tuple 불일치로 패킷 drop