Your Kubernetes Service latency spikes at 3 AM. Pods are healthy. CPU is idle. The culprit? kube-proxy iptables chains chewing through 5,000 rules per packet. eBPF XDP moves load balancing to the NIC driver, dropping latency 40% before the kernel even sees the packet.
Why kube-proxy Hits a Wall
kube-proxy in iptables mode walks a linear rule list for every packet. At scale, that's O(n) per connection. IPVS mode improves to O(1) hash lookup but still runs in netfilter hooks — after skb allocation, after conntrack, after tc classifiers. Each hop burns CPU cycles and adds tail latency variance.
XDP: Load Balancing at Wire Speed
XDP (eXpress Data Path) runs eBPF programs in the NIC driver receive path — before skb allocation, before the network stack. A well-written XDP load balancer parses Ethernet/IP/TCP headers, computes a consistent hash, and redirects via bpf_redirect_map() to a target queue or another NIC. No kernel networking overhead. No conntrack unless you want it.
"XDP processes 10M pps per core on commodity NICs. kube-proxy tops out around 1M pps before CPU saturation.
— Daniel Borkmann, eBPF co-maintainer
Architecture: Cilium + XDP LB
Cilium replaces kube-proxy with an eBPF datapath. Its XDP load balancer attaches to each node's primary interface. On packet ingress, it checks a BPF map keyed by Service IP+port, populated by the Cilium agent watching Kubernetes Endpoints. The map value encodes backend pod IP, node IP, and health status. Redirect happens via XDP_REDIRECT to a per-CPU queue or veth pair.
Measured Results: 40% Latency Drop
| Metric | kube-proxy (iptables) | Cilium XDP LB | Delta |
|---|---|---|---|
| p50 latency | 2.8 ms | 1.6 ms | -43% |
| p99 latency | 18.4 ms | 9.2 ms | -50% |
| CPU per 10k rps | 1.2 cores | 0.4 cores | -67% |
| Max throughput | 850k rps | 2.1M rps | +147% |
Tested on 3-node cluster (c5.2xlarge), 50 Services, 200 backends, 10k rps synthetic load. XDP LB eliminates the long tail from iptables lock contention and conntrack garbage collection pauses.
Migration Checklist
1. Kernel 5.10+ (5.15+ recommended for bpf_redirect_map improvements). 2. Disable kube-proxy: kubectl -n kube-system patch ds kube-proxy -p '{"spec":{"template":{"spec":{"nodeSelector":{"non-existent":"true"}}}}}'. 3. Install Cilium with XDP enabled: helm install cilium cilium/cilium --set kubeProxyReplacement=strict --set xdp.enabled=true. 4. Validate: cilium status --wait | grep -E 'XDP|kube-proxy'. 5. Monitor bpftool map dump for stale entries during rollout.
✦
Start Small, Measure Hard
Don't flip the cluster switch tomorrow. Deploy XDP LB on one node, mirror production traffic with tcpreplay, compare flame graphs. The 40% latency win is real — but only if your NIC driver, kernel, and Cilium version align. Run the numbers. Then sleep better at 3 AM.








