eBPF Dataplane

How does an eBPF dataplane route Services without iptables? The CNI agent attaches eBPF programs to kernel hooks and keeps Service and endpoint state in BPF maps. A connection to a ClusterIP is then looked up in constant time and rewritten to a backend at the socket, before the first packet is built: connect-time load balancing, not per-packet DNAT. As the agent implements Services itself, kube-proxy and its iptables chains can be removed entirely.

Play the animation 5 steps, animated, best on a wide screen

eBPF Dataplane diagram: An eBPF dataplane can replace kube-proxy

eBPF Dataplane, step by step

  1. Rather than relying on iptables Service rules, the CNI agent attaches small eBPF programs directly to kernel hooks, at the socket layer and on the network interfaces. A connection that takes this path traverses no Service rule chain.

    Play from step 1
  2. Service and endpoint state lives in BPF maps, kept in sync from the API by the agent. A lookup of 10.96.0.20 returns the backend set, here 10.244.2.7 and 10.244.3.9, as a constant-time hash lookup no matter how many Services exist.

    Play from step 2
  3. When the client calls connect to the ClusterIP, the socket-level eBPF program looks the address up in the map and rewrites the destination to a chosen Pod right there, before the packet is even built. This is connect-time load balancing, not per-packet DNAT.

    Play from step 3
  4. The connection then goes straight to the Pod address, 10.244.2.7, carrying the client source IP unchanged. Because the socket was already connected to that backend, the packet needs no DNAT on the way out and no connection-tracking reversal on the way back.

    Play from step 4
  5. Because the whole dataplane is eBPF programs plus maps, kube-proxy and its iptables chains can be removed entirely, which Cilium offers, as does Calico in its eBPF mode. Lookups stay constant-time as the cluster grows to thousands of Services.

    Play from step 5

Sources