Also at Deasil Works · txn2 · Plexara
Profiles GitHub · X · LinkedIn
Theme Light · Auto · Dark
Professional notes by Craig Johnston
long-form, short-form, working drafts · since 2008
VOL. XIX · MMXXVI
130 NOTES IN PRINT
FOLIO CXXX 2026-07-25 · 8 MIN · SHORT-FORM

Cilium: One eBPF Data Plane for Networking, Security, and Encryption

The CNI that replaced Weave Net, kube-proxy, and a hand-rolled WireGuard overlay with a single component

Diagram · folio cxxx
flowchart TB
  POD1["pod"] -->|eBPF data plane| CIL["Cilium agent<br>per node"]
  CIL -->|WireGuard| CIL2["Cilium agent<br>other node"]
  CIL2 --> POD2["pod"]
  CIL --> HUB["Hubble<br>flow visibility"]
  POL["CiliumNetworkPolicy<br>identity-based"] -.-> CIL

When you built the cluster, one cilium install gave it pod networking, replaced kube-proxy, and encrypted traffic between nodes, three jobs the 2020 edition did with three separate pieces. This post is the deeper look at why Cilium is the networking choice in 2026, what its eBPF data plane buys you, and how to use the security and observability that come with it.

This series rebuilds my 2020 Apress book, Advanced Platform Development with Kubernetes, for 2026. The approach behind it comes from building and running data platforms in production for more than twenty years.

§Weave Net Is Gone

The 2020 book’s cluster used Weave Net for its pod network, a reasonable and popular choice at the time. Weave Net is not a choice anymore. Weaveworks, the company behind it, shut down in 2024, and the project went unmaintained. This is a different flavor of the lock-in story than the relicensing ones, and in some ways a more common one: a project that depended on a single company that stopped existing. The result for anyone who built on it is a critical piece of infrastructure with no one maintaining it and no security patches coming.

The protection is the same as it is against relicensing: build on projects with broad, durable backing rather than a single company’s continued health. Cilium is a CNCF graduated project, the highest maturity tier, with a large contributor base and adoption across the major clouds and vendors. It is not going to vanish because one company has a bad year. That durability is worth weighing as heavily as any technical factor, because the network is not a thing you want to be re-platforming under duress.

§eBPF, and Why It Replaced iptables

Cilium’s distinguishing technology is eBPF, and it is worth understanding at a high level because it is why the rest of this works. eBPF lets you run small, safe, sandboxed programs inside the Linux kernel, attached to events like a packet arriving on an interface. Instead of the kernel’s behavior being fixed and configured from outside, you load programs that make decisions in the data path itself, at kernel speed.

The older way of doing Kubernetes networking, the way kube-proxy worked, was to translate every Service into a pile of iptables rules. On a busy cluster that pile grows into thousands of rules the kernel walks for every connection, and it gets slow and hard to observe. Cilium does the same routing and load balancing as eBPF programs, which scale far better and, because they are programs rather than opaque rule chains, can be instrumented. When you installed Cilium with kubeProxyReplacement=true, you turned off kube-proxy entirely and handed service routing to eBPF. That is one of the three old jobs folded into one component, and it is faster than what it replaced.

§One Component, Three Old Jobs

Look at what the cluster build collapsed. The 2020 setup needed a CNI plugin for pod networking, kube-proxy for service routing, and, in a security-conscious build, a separately installed and hand-configured WireGuard overlay to encrypt traffic between nodes across an untrusted network. That book spent a careful section wiring up WireGuard by hand, generating keys, writing peer configs, and maintaining the mesh.

Cilium is all three. It is the CNI, giving pods their addresses and routing their traffic. It is the service proxy, replacing kube-proxy. And it does the encryption, which is the next section. Three components, three sets of failure modes, and a section of manual key management became one install and a couple of flags. This is the boring-infrastructure thesis: the hard, error-prone work got absorbed into a mature component that does it correctly so you do not have to.

§Transparent Encryption

Private networking on a shared cloud is not something to fully trust, which is why the book encrypted inter-node traffic at all. Cilium does it with WireGuard, the same modern, fast protocol, but without any of the manual work. The flags from the cluster build turned it on.

cilium install \
  --set encryption.enabled=true \
  --set encryption.type=wireguard

Every Cilium agent generates its own key pair, publishes the public half through a Kubernetes resource, and the agents form an encrypted mesh among themselves automatically. There are no keys for you to generate, distribute, or rotate, and no peer configuration to maintain as nodes come and go. Confirm it is live and carrying traffic with one command.

cilium encrypt status

The entire WireGuard chapter from the 2020 book is now a setting. Hand-maintained key meshes drift and break quietly, leaving you with unencrypted traffic you thought was protected. Letting the data plane own it is both less work and more trustworthy.

§Network Policy as Identity, Not IP

A flat network where every pod can reach every other pod is the default, and it is not what you want for a platform running databases, secrets, and multiple teams’ workloads. Cilium enforces network policy, and it does so by identity rather than by IP address, which is the right model for Kubernetes because pods are ephemeral and their IPs are meaningless. A CiliumNetworkPolicy is written in terms of labels, the identity of a workload, so a rule like “only the API can reach the database” stays correct as pods churn.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: only-api-to-postgres
  namespace: data
spec:
  endpointSelector:
    matchLabels:
      cnpg.io/cluster: platform-pg
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: api
      toPorts:
        - ports:
            - { port: "5432", protocol: TCP }

Cilium can enforce at layer 7 as well, allowing only specific HTTP methods or paths between services, which is the kind of fine-grained control that used to require a service mesh. Moving toward a default-deny posture, where nothing talks to anything unless a policy allows it, is how you turn a flat cluster into a segmented one, and on a platform you own it is a few manifests rather than a product you buy.

§See Everything With Hubble

eBPF’s other gift is observability, and Cilium exposes it through Hubble, which you enabled with the cluster. Because the data plane is programs in the kernel rather than opaque rule chains, Cilium can report every flow: which service talked to which, whether a policy allowed or dropped it, and what the request was. hubble observe streams it live, and the Hubble UI draws a real-time service map of the platform.

hubble observe --namespace data --verdict DROPPED

That command shows you exactly what your network policies are blocking, which is the difference between writing a policy and trusting it. When a connection fails, you do not guess; you watch the flow and see the verdict. This visibility, baked into the network itself, is one of the strongest reasons to run Cilium, and it is the kind of thing the cloud networking layers keep hidden behind their own dashboards.

§Operating the Network

Owning the network means its security and visibility are yours to run, and Cilium makes both routine.

Segment toward zero trust. Start permissive to get the platform working, then tighten with CiliumNetworkPolicy until each workload reaches only what it must. The database accepts only its application, the gateway reaches only the services it fronts, and the rest is denied. Identity-based rules stay correct through every deploy and scale event.

Watch the flows. Hubble is your network’s logs and metrics: live flows for debugging, a service map for understanding, and Prometheus metrics that the monitoring stack in the next post scrapes.

Hand out addresses to the gateway. Cilium’s load-balancer IP management and L2 or BGP announcement are what gave the Gateway a reachable address without a cloud load balancer. That is the same Cilium doing one more job, assigning and announcing service IPs on infrastructure you own.

§When Something Is Wrong

Pods on different nodes cannot reach each other. Run cilium connectivity test, which exercises cross-node paths and reports exactly what fails, and confirm the firewall allows Cilium’s VXLAN and WireGuard UDP ports from the cluster build.

Services do not resolve or load-balance. With kube-proxy replaced, Cilium needs to know the API server’s address; confirm k8sServiceHost and k8sServicePort were set at install, since without them service routing has no anchor.

A connection is blocked unexpectedly. A network policy. hubble observe --verdict DROPPED shows the dropped flow and which policy denied it, turning a mystery into a line you can read.

Encryption looks off. cilium encrypt status reports the WireGuard state and key count per node; a node missing from the mesh points at the agent on that node.

§What You Have

A single, mature, eBPF data plane carrying your pod traffic, routing your services faster than iptables could, encrypting everything between nodes with no key management, enforcing identity-based security policy, and showing you every flow through Hubble. It replaced three separate pieces from the old way of doing this, including one that no longer exists, and it does their combined job better.

Next I make the whole platform visible, standing up the monitoring stack, Prometheus, Grafana, Loki, and OpenTelemetry, that every component so far has been quietly exposing metrics for.

← back to all notes