Cilium and eBPF, explained without the marketing
Where the kernel stops forwarding your packets the old way, what you gain, and what you lose the ability to troubleshoot.
Every vendor has decided that eBPF is the future of networking, and they are not wrong, but their explanations tend to skip the part that matters to someone who actually debugs networks for a living: what's different, specifically, and what breaks when it does.
eBPF — extended Berkeley Packet Filter — is a way to run sandboxed programs inside the Linux kernel without modifying kernel source or loading a kernel module. The kernel verifies the program before running it, which is why vendors can ship eBPF programs in production without the normal risk profile of kernel code. The programmes can attach to network events: packet receive, packet transmit, socket operations, and so on.
What Cilium replaces
A standard Kubernetes CNI builds on top of iptables. When a packet arrives destined for a service, the kernel walks a chain of iptables rules to find the matching DNAT rule, rewrites the destination, and forwards it. This works. It's also O(n) with the number of services — every rule gets evaluated in sequence.
Cilium replaces this with eBPF maps. A map is a hash table in kernel memory. When Cilium programs the dataplane for a service, it writes an entry into a map: service VIP → set of backend pods with weights. When a packet arrives, the eBPF program does a single hash lookup. The cost is constant regardless of how many services you have.
# Inspect Cilium's service map directly
cilium service list
# ID Frontend Service Type Backend
# 1 10.96.0.1:443 ClusterIP 10.0.1.14:6443 (1)
# 2 10.96.10.0:80 ClusterIP 10.0.0.5:8080 (1), 10.0.0.6:8080 (2)
# Dump the BPF map underlying service 2
cilium bpf lb listAt scale — thousands of services — the difference between O(n) iptables and O(1) BPF maps is measurable in forwarding latency. Below a few hundred services you won't notice.
The visibility trade-off
iptables is verbose and inspectable. You can iptables -L -n -v and read exactly what the kernel will do with a packet. Every match, every jump, every counter. Network engineers have been doing this for twenty years.
eBPF programs are not inspectable in the same way. Cilium gives you cilium monitor, which taps into the BPF programs and shows you decisions in real time — drops, policy hits, connection events. It's more useful than tcpdump for the high-level view. But when you want to know why a packet was dropped at the BPF layer, you're reading Cilium documentation and Hubble output rather than a raw rule list.
The first time a policy denied traffic in a Cilium cluster I'd just migrated from Calico, I spent forty minutes looking for the iptables rule. It wasn't there. The rule was in a BPF map. Hubble showed it immediately. Know your tools before you're on-call.
Hubble
Hubble is Cilium's observability layer. It sits in the eBPF datapath and records every flow decision: source, destination, policy verdict, drop reason. You can query it in real time from the CLI or through the Hubble UI.
For a network engineer, Hubble fills the role that NetFlow or sFlow plays in a traditional environment. You can answer "is traffic actually flowing between these two pods" without needing tcpdump on every node. That's valuable enough to justify Cilium on its own if your cluster is big enough that per-node debugging is painful.
When iptables is still the answer
If you have an existing cluster with complex network policy that your team understands, migrating to Cilium carries real risk and real work. The performance gains don't matter below a few hundred services. The observability improvements matter immediately, but Hubble requires learning.
Cilium makes most sense for new clusters where you'll benefit from the operational model from day one, or clusters at a scale where iptables performance is measurable. If you're evaluating it, run both in staging and compare cilium monitor against your existing debugging workflow before you commit.