Packets in the Mesh
iptables vs eBPF service routing in Kubernetes
The measured result

Installing the rules for 10,000 services took 0.63s per sync, up from 0.03s at 100 - and kube-proxy pays that on every endpoint change. eBPF (Cilium) replaces the linear rule chain with an O(1) hash-map lookup whose cost stays flat.
O(n)
iptables sync (measured)
O(1)
eBPF lookup (cited)
100%
reproducible harness
What's inside
- The Kubernetes service data plane and the two costs that matter: data path and sync.
- How iptables expresses services as rule chains, and why both costs grow O(n).
- How eBPF (Cilium) uses hash-map lookups at kernel hooks to keep costs flat.
- A measured iptables sync-time curve, plus a cited comparison with IPVS and eBPF.
- A workload-driven framework for choosing a data plane, with four worked clusters.
- A protocol for measuring your own cluster, and full references.
Table of contents
- Preface
Preface
Sets up the book's narrow comparison of the three production Kubernetes service data planes (iptables, IPVS, eBPF/Cilium), states its audience, and is explicit about which figures in the book are measured directly versus cited from external sources.
- Chapter 1
The Service-Routing Problem
Frames how a Kubernetes Service's ClusterIP is translated to a live pod endpoint on every packet, defines data-path cost and sync cost as the two costs that must scale with cluster size, and previews how iptables, IPVS, and eBPF each answer the problem.
- Chapter 2
Inside the iptables Data Plane
Traces how kube-proxy's iptables mode turns each Service into netfilter rule chains and DNAT, and explains why both the per-packet lookup and the full-table sync via iptables-restore are linear in the number of services, plus the shared conntrack bottleneck.
- Chapter 3
Inside the eBPF Data Plane
Explains how Cilium attaches eBPF programs to kernel hooks that resolve services via an O(1) BPF hash-map lookup instead of a rule chain, keeping both data-path and sync costs flat, and notes extra capabilities like direct server return.
- Chapter 4
The Measured Comparison
Reports the harness's directly measured iptables-restore sync times across 100 to 10,000 services and places them alongside cited IPVS and eBPF figures in a single comparison table, marking clearly which cells are measured versus cited.
- Chapter 5
Choosing a Data Plane
Converts the cost comparison into an ordered decision framework built around cluster scale/churn, kernel availability, and operational maturity, then applies it to four representative cluster scenarios.
- Chapter 6
Conclusion: Measure Your Own Cluster
Recaps that data planes should be chosen by how their costs grow rather than raw speed, and lays out a five-step protocol for measuring sync time and tail latency on the reader's own cluster.
Who this is for
- Platform or SRE engineers who operate Kubernetes clusters
- Engineers choosing a CNI for their cluster
- Engineers debugging slow service/endpoint updates
- Readers who want to reason about which service data plane keeps up as a cluster's size and change rate grow
- Anyone comparing kube-proxy (iptables/IPVS) against Cilium's eBPF kube-proxy replacement
The preface says familiarity with Linux networking basics and with big-O reasoning is enough; where kernel mechanism is needed, the book builds it up from first principles.
How this was measured
The bench/ harness builds a Kubernetes-style nat table with 3 DNAT rules per service for service counts from 100 to 10,000, and times how long iptables-restore (nf_tables backend) takes to install that table atomically - the same operation kube-proxy performs on every sync - on an AMD Ryzen 7 5700X inside a privileged Alpine Docker container. This iptables sync curve is the only figure measured directly; the IPVS and eBPF (Cilium) numbers are cited from the projects' own documentation and published sources, because the IPVS kernel module is absent from Docker Desktop's WSL2 kernel and eBPF service routing needs a real multi-node cluster. The appendix provides a kind+Cilium recipe (installing Cilium in kube-proxy-replacement mode) so readers can reproduce the full three-way comparison themselves, and notes the measured iptables curve is a lower bound since production kube-proxy emits more rules per service and reloads the whole table on every change.
From the preface
A Kubernetes Service is a stable virtual address for a shifting set of pods. Something must translate that address into a real endpoint on every packet, and keep doing so as pods come and go. That something is the service data plane, and this book is about how it is built.
Frequently asked
What exactly does the benchmark measure?
It measures the wall-clock time for iptables-restore to install a Kubernetes-style nat table (3 DNAT rules per service) for service counts from 100 up to 10,000, on an AMD Ryzen 7 5700X inside a privileged Alpine container - the same table-install operation kube-proxy performs on every sync.
Are the IPVS and eBPF numbers measured the same way as the iptables numbers?
No. Only the iptables sync time is measured directly. The IPVS and eBPF (Cilium) figures are cited from the projects' own documentation and published sources, because the IPVS kernel module isn't present in Docker Desktop's WSL2 kernel and eBPF service routing needs a real multi-node cluster to reproduce faithfully.
Do I need to run the harness myself?
No - the measured results are reported in Chapter 4's table and figure. But the bench/ directory harness and the appendix's kind+Cilium recipe are included so readers can reproduce the iptables measurement, and the full iptables/IPVS/eBPF comparison, on their own cluster.
Is this beginner-friendly?
The preface targets a platform or SRE engineer who operates Kubernetes - someone choosing a CNI or debugging slow service updates - and assumes familiarity with Linux networking basics and big-O reasoning; where kernel mechanism is needed, it's built up from first principles.
Does the book cover all of Kubernetes networking?
No. The preface states the comparison is deliberately narrow: rather than surveying Kubernetes networking as a whole, it follows one packet through the service data plane and asks how routing cost grows as a cluster adds services.
Which data plane does the book say is best?
None universally. Chapter 5 turns the comparison into a decision framework based on cluster scale/churn, kernel availability, and operational maturity, and the conclusion states plainly: "There is no fastest data plane, only one matched to a cluster's scale and constraints."
Convinced? Get the full book.