Notiz

Cilium und eBPF: kube-proxy ersetzen und iptables aus dem Kubernetes-Netzwerk entfernen

Alle sehen eBPF als Tempogewinn, doch der eigentliche Wert ist eine Entscheidungsregel: wo sich der Ersatz von kube-proxy lohnt und wo iptables noch gewinnt.

kube-proxy ist die unsichtbarste Komponente in Kubernetes: Sie verwandelt still die virtuelle IP eines Service in die Adresse eines konkreten Pods. Solange es nur ein paar Dutzend Services gibt, denkt niemand an sie. Die Probleme beginnen bei Skalierung — und 2026 hat dieser alte Mechanismus endlich einen ernsten Grund, ersetzt zu werden.

Warum der iptables-Modus an eine Grenze stößt

Im Standardmodus läuft kube-proxy für jedes einzelne Paket linear durch eine iptables-Regelkette. Unter ~1000 Services ist das unsichtbar; darüber wächst der CPU-Aufwand proportional zur Größe des Katalogs. Schlimmer als die Skalierung ist jedoch die Blindheit. iptables wählt einen Backend-Pod zufällig — der Kernel „wirft eine gewichtete Münze“ — und die Routing-Entscheidung sieht weder Latenz noch die Tiefe der Verbindungsschlange noch den Health-Zustand des Pods. Der Verkehr landet auf einem überlasteten Pod oder überquert eine Availability Zone, selbst wenn direkt daneben auf demselben Knoten ein gesunder Pod sitzt. Unter Last entartet das zu Retries → kaskadierenden Ausfällen → P99-Spitzen.

1.36 entfernte IPVS, und nftables behebt das Falsche

Kubernetes 1.36 hat den IPVS-Modus von kube-proxy entfernt — für alle, die einst um konstanter Lookup-Zeit willen von iptables zu IPVS geflohen sind, haben sich die Optionen verengt. Seit 1.31 läuft kube-proxy auf einem nftables-Backend: Das behebt Skalierung und Geschwindigkeit der Regel-Updates, lässt aber die Wurzel des Problems unberührt. Entscheidungen fallen weiterhin auf L4 und bleiben blind gegenüber dem Anwendungszustand.

Wie eBPF die Regeln ändert

Cilium ersetzt kube-proxy mit einem einzigen Flag — kubeProxyReplacement: true. Statt eine Regelkette zu durchlaufen, bekommt man einen Lookup mit konstanter Zeit in einem kompilierten eBPF-Programm im Kernel. Das mentale Modell ist einfach: iptables fragt „welche Regel passt zu diesem Paket?“, eBPF antwortet „ich weiß bereits, was zu tun ist“.

Der zentrale Trick ist socket-LB. Klassisches kube-proxy macht DNAT am Paket nach connect(), und jedes Paket durchläuft conntrack. Cilium schreibt das Ziel auf Syscall-Ebene um — bevor das Paket überhaupt existiert. Kein conntrack, kein SNAT-Overhead, geringere Latenz. Maglev Consistent Hashing bindet ein 5-Tupel (Quell-/Ziel-IP, Quell-/Ziel-Port, Protokoll) fest an denselben Pod — entscheidend für Cache-Schichten wie Redis, wo zufällige Backend-Auswahl Anfragen verstreut und die Hit-Rate ruiniert. Ein Nebeneffekt beim Debugging: tcpdump auf der Pod-Seite zeigt das bereits umgeschriebene Ziel statt der Service-ClusterIP — das Erste, was irritiert.

Wo es sich lohnt und wo nicht

Der ehrliche Gegenpunkt zählt mehr als das Marketing. Auf einem Cluster mit 1–3 Knoten kann kube-proxy auf iptables Cilium bei reinem Pod-zu-Pod-Verkehr in der Latenz schlagen: Der eBPF-Overhead rechnet sich nicht bei einer kleinen conntrack-Tabelle aus ein paar hundert Services. Cilium ist zudem teurer im Betrieb — es benötigt einen Linux-Kernel ≥5.x, bringt mehr Stellschrauben mit, und eBPF-Vorfälle sind schwerer zu debuggen als das Lesen von iptables-Regeln.

Die Entscheidungsregel: Der Ersatz von kube-proxy durch eBPF ist gerechtfertigt ab ≥5 Knoten, ≥100 Services oder wenn man L7-Policies, Observability über Hubble oder Cluster Mesh ausdrücklich braucht. Es ist eine bewusste Wahl für Last, kein „standardmäßig immer“.

Womit anfangen

Prüfen Sie zuerst die Kernel-Version (≥5.x) auf jedem Knoten — das ist eine harte Voraussetzung, keine Empfehlung. Rollen Sie es über Canary-Knoten aus: Netzwerkprobleme auf Kernel-Ebene sind beängstigender als das Debuggen von iptables. Schalten Sie Hubble von Tag eins an ein — Flow-Sichtbarkeit verwandelt „das Paket ist irgendwo verschwunden“ in „der Datapath hat das Paket aus diesem konkreten Grund verworfen“, und das zahlt sich schon beim ersten Vorfall aus. Auf einem Bare-Metal-Stack (kubeadm + Cilium mit kubeProxyReplacement=true) ist dieses Set längst Standard.

Und umgekehrt: Wenn Sie keine L7-Policies, kein Mesh und keine fortgeschrittene Observability brauchen, bleibt Calico + kube-proxy völlig ausreichend. Das Leitprinzip für die Netzwerkschicht ist dasselbe wie überall in der Infrastruktur — zahlen Sie nicht im Betrieb für Fähigkeiten, die Sie nie nutzen.

© 2026 axyi.ru · CC BY 4.0