규모의 벽 — iptables에서 IPVS·eBPF로 (직접 IPVS 모드로 전환해 실측)

부제: "Service" 추상은 그대로다 — 바뀌는 건 커널이 그걸 구현하는 방법뿐


B1에서 ClusterIP는
KUBE-SERVICES ▸ KUBE-SVC(확률 분기) ▸ KUBE-SEP(DNAT)라는 iptables 룰
뭉치였다. 잘 도는데, 한 가지 약점이 있다. 룰이 서비스 수에 비례해 선형으로
쌓인다.
서비스가 수십 개면 문제없지만, 수천 개가 되면 룰을 위에서부터
순차로 검사하는 iptables는 갱신도 조회도 느려진다. 이게 규모의 벽이다.

그래서 kube-proxy에는 다른 모드가 있다. 이번 편은 개념만 말하지 않고, 실제로
이 클러스터의 kube-proxy를 IPVS 모드로 전환해
무엇이 달라지는지 떠서 봤다.
(확인 후 원래 iptables 모드로 되돌렸다.)


한 줄 정의부터

개념 한 줄 정의
iptables 모드 룰이 선형(O(n)) — 서비스가 많아지면 갱신·조회가 느려짐(B1)
IPVS 모드 커널 L4 로드밸런서. 해시(O(1)) + rr·wrr·lc 등 스케줄러
kube-ipvs0 IPVS 모드에서 ClusterIP들이 실제로 바인딩되는 더미 인터페이스
eBPF(Cilium) iptables를 걷어내고 커널에 프로그램을 직접 심어 LB·정책·관측

iptables·IPVS·eBPF 비교 — 자료구조·복잡도·LB 방식·ClusterIP 실재


실제로 IPVS 모드로 전환해 보기

kube-proxy의 ConfigMap에서 mode: ipvs로 바꾸고 재시작하면 kube-proxy가 IPVS
Proxier로 뜬다. (이 클러스터 커널은 /proc/net/ip_vs가 있어 IPVS를 지원했다.)

실제 콘솔 — IPVS 모드 kube-proxy 로그, /proc/net/ip_vs 테이블, ClusterIP의 kube-ipvs0 바인딩

세 가지가 눈에 띈다.

  • ① IPVS Proxier로 뜬다 — 로그에 "Using ipvs Proxier", 그리고 스케줄러를
    안 정하면 rr(round-robin)이 기본이라고 찍힌다.
  • /proc/net/ip_vs — 우리 ClusterIP(10.96.142.236:80, 16진수
    0A608EEC:0050)가 가상 서버(VIP) 로 올라가고, 그 아래 실서버 3개
    (10.244.0.24/25/26:80)가 weight 1로 매달린다. B1의 "확률 0.333→0.5→나머지"
    트릭이 사라지고, 커널 IPVS가 rr로 균등 분배한다. 조회는 해시라 O(1)
    서비스가 아무리 많아져도 일정하다.
  • ③ ClusterIP가 실재한다/proc/net/fib_trie를 보면 10.96.142.236
    /32 host LOCAL, 즉 더미 인터페이스 kube-ipvs0에 실제로 바인딩돼 있다.
    B1의 iptables 모드에서 ClusterIP가 "아무 데도 없는 NAT 룰"이었던 것과 정확히
    대비된다. IPVS 모드에선 ClusterIP가 실재하는 로컬 주소다.

그다음 — eBPF가 iptables를 걷어낸다

IPVS도 결국 커널의 NAT 부수효과를 위해 iptables를 조금은 쓴다. 더 나아간 답이
eBPF(대표적으로 Cilium)다. eBPF는 커널에 작은 프로그램을 직접 주입
서비스 로드밸런싱·네트워크 정책·관측을 한 곳에서 처리한다. kube-proxy 자체를
없애는 kube-proxy-free 구성도 가능하다.

여기서 이 시리즈의 갈래가 하나로 모인다. eBPF는 관측 갈래(C)에서 다룰
auto-instrumentation
의 그 eBPF와 같은 뿌리다 —
커널에 프로브를 심어 소스 수정 없이 트래픽·호출을 관찰하는 기술. 네트워킹에서는
로드밸런싱으로, 관측에서는 추적으로 쓰일 뿐이다.


정리

  • iptables 모드는 O(n): 서비스가 많아지면 느려지는 규모의 벽.
  • IPVS 모드는 O(1) 해시 + rr 스케줄러, ClusterIP가 kube-ipvs0에 실제
    바인딩
    된다(실측으로 확인).
  • eBPF(Cilium)는 iptables를 걷어내고 커널에 직접 프로그램을 심는 다음 단계.
  • 무엇을 쓰든 "Service" 추상은 그대로다 — 개발자가 쓰는 방식은 안 바뀌고,
    커널이 그걸 구현하는 방법만 규모에 따라 갈린다.

다음 편(B3)에서는 네트워킹에서 한 걸음 더 안쪽 — namespace와 cgroup으로 OS를
나누는 격리의 실제
— 로 들어간다. A1에서 맛본 "컨테이너=namespace+cgroup"을
QoS 등급까지 확장한다.


참고

  • Kubernetes Docs — Virtual IPs and Service Proxies (IPVS mode)
  • Cilium Docs — kube-proxy replacement (eBPF)
  • 실측: docker-desktop 클러스터에서 mode: ipvs로 전환 후 /proc/net/ip_vs·/proc/net/fib_trie 덤프(확인 뒤 iptables 모드로 복구)

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다