CNI Plugins (Calico, Cilium, Flannel) in Kubernetes
A friendly, step-by-step guide to the plug-ins that give every pod its network address and connect pods together: what a CNI plugin is, how it works, how Flannel, Calico and Cilium differ, and how to choose, secure and troubleshoot them.
Picture a brand-new city being built. Thousands of houses go up every day, and some are demolished the next morning. For the city to work, every house needs a street address, every street needs to connect to other streets, and someone must decide which neighbours may visit which houses. If nobody handles this, the residents are trapped inside their own buildings, unable to send a letter or receive a guest.
A Kubernetes cluster is such a city. Pods appear and disappear all the time, and every one of them needs an address and a road to every other pod. Kubernetes itself does not build these roads. It hands the job to a small piece of software called a CNI plugin. Flannel, Calico and Cilium are the three names you will hear most often.
In this guide we build the idea from zero. Every new word is explained the first time it appears, and every big idea comes with an everyday comparison so it sticks. By the end you will know what a CNI plugin does, how the three famous ones differ, how to choose between them, and how to keep your cluster network healthy and safe.
1What Are CNI Plugins?
To understand CNI plugins we first need a handful of simple words: pod, node, network, address and plugin.
Pod
A pod is the smallest unit Kubernetes runs. It holds one or more containers that live together and share one network address.
Node
A node is one computer in the cluster, either a physical machine or a virtual one. Many pods can run on one node.
IP address
An IP address is a number that identifies a device on a network, like a house number on a street. Packets of data are sent to these numbers.
Network
A network is a set of devices that can send data to one another. Roads, wires and radio waves all carry that data.
Interface
In CNI, the word interface means an agreed set of rules, a standard way for two pieces of software to talk to each other.
Plugin
A plugin is a small program that you attach to a bigger program to add a feature. The bigger program stays the same; the plugin can be swapped.
So what exactly is a CNI plugin?
CNI stands for Container Network Interface. It is a small, published standard that describes how a program that runs containers should ask another program to set up the network for those containers. The second program is the CNI plugin. When a new pod is created, the machinery on the node calls the plugin and says, in effect: “Here is a new pod. Please give it an address and connect it to the network.” When the pod is deleted, the machinery calls the plugin again and says: “Please take that address back and clean up.”
The important idea is separation. Kubernetes defines what must be true of the pod network. The CNI plugin decides how to make it true. Because the interface is standard, you can choose a simple plugin for a small cluster or a sophisticated one for a big cluster, without changing anything else in Kubernetes.
Think of a wall socket. The socket has a standard shape, so you can plug in a lamp, a kettle or a fan, and each one works. The building does not care which appliance you choose. CNI is the socket. Flannel, Calico and Cilium are three different appliances that all fit the same socket.
The three promises of the Kubernetes network
Kubernetes makes a few simple promises about the pod network. Any CNI plugin you choose must keep them. Almost everything else in this guide follows from these promises.
Every pod gets its own address
No two pods share an address. Each pod looks like a small, independent computer with its own number.
Pods talk to pods without tricks
Any pod can reach any other pod directly by address, even on another node, without address rewriting in between.
Nodes talk to pods without tricks
Agents on a node can reach the pods on that node directly, which is how health checks and other node services work.
A short history
Before container platforms agreed on a standard, every tool invented its own way of wiring up networks. Each new network product had to write separate glue for each container platform. The CNI standard, created in the middle of the 2010s and later adopted by the Cloud Native Computing Foundation, replaced this tangle with one small rulebook. Today Kubernetes and most other container platforms use it. Because it is only a few pages long, writing a plugin is straightforward, which is one reason the ecosystem grew so rich.
Kubernetes does not ship with a full pod network of its own. A brand-new cluster with no CNI plugin installed will have nodes that are not ready and pods that cannot start. Installing a CNI plugin is one of the first jobs after creating a cluster.
2The Problem CNI Plugins Solve
Containers are isolated by design. That is wonderful for safety and terrible for connection. Someone has to build the bridges.
Containers live in sealed rooms
Each pod runs inside its own private network space, a sealed room with its own doors, its own address list and its own view of the network. This isolation is a feature: one pod cannot accidentally listen to another pod’s traffic or clash over the same port number. But a sealed room is useless until you cut a door in the wall and connect it to a corridor.
Addresses run out or clash
Without a manager, two pods could pick the same address. Someone must hand out unique addresses and remember who holds which.
Cross-node roads are missing
Two pods on different nodes need a path between them. The physical network knows nothing about pod addresses unless someone teaches it.
Pods come and go
Pods are created and destroyed constantly. Networking must be set up in seconds and cleaned up completely, or addresses leak away.
Everyone can talk to everyone
By default any pod may talk to any other pod. Real systems need rules about who may talk to whom.
Different platforms, different needs
A small lab, a cloud provider and a private data centre each need a different way to build roads.
Blindness
When a call fails, you need to see where it was dropped. Plain networks make that difficult.
What people did before
| Old approach | How it worked | Why it hurt |
|---|---|---|
| Share the host address | Containers used the computer’s own address and different port numbers | Port clashes, and applications had to know which port they would get |
| Hand-built bridges and rules | Administrators wrote network scripts for every machine | Slow, error-prone and different on every machine |
| Product-specific glue | Each network product wrote its own integration for each platform | Endless duplicated work and lock-in |
| Address translation everywhere | Pod addresses were rewritten as traffic left a machine | Applications could not know their own true address |
flowchart LR
subgraph W["Without a CNI plugin"]
A1["Pod on node 1"] -.->|"No road"| B1["Pod on node 2"]
end
subgraph V["With a CNI plugin"]
A2["Pod on node 1"] -->|"Address and road provided"| B2["Pod on node 2"]
end
Reading Figure 1
The left half shows two pods on two nodes with a dotted arrow marked “No road”. Each pod exists, but nothing connects them, so a message from one never arrives at the other. The right half shows the same pods after a CNI plugin has done its work. The plugin has given each pod an address and prepared a path, so the solid arrow succeeds. The pods are identical in both halves. Only the plugin makes the difference.
Picture a new housing estate where builders finished all the houses but forgot the roads, street signs and post office. The houses are perfect, and yet nobody can visit anybody. A CNI plugin is the team that lays roads, paints numbers on doors and tells the post office where everybody lives, and keeps doing it each time a new house appears.
3Core Concepts You Need First
A few building blocks of networking appear again and again. Learn them once, and every plugin will make sense.
Network namespace
A private network space inside the operating system. Each pod has its own, with its own interfaces, addresses and rules. It is the sealed room from Chapter 2.
Virtual cable
A pair of connected virtual network ends. One end is placed inside the pod’s room, the other stays on the node. Data pushed into one end pops out of the other.
Bridge or router
A node-level device that joins the virtual cables of all pods on that node, so that pods on the same node can reach one another and the outside.
Address range
A block of addresses written as a start and a size, such as ten dot two forty-four dot zero dot zero slash sixteen. Each node receives a slice of the cluster’s range.
IP address management
Often shortened to IPAM. The job of handing out addresses from a range and taking them back. Every plugin needs one, either its own or a shared one.
Network policy
A Kubernetes object that states which pods may talk to which. It is only a rulebook. A plugin must exist that enforces it.
Two ways to build cross-node roads
The hardest job of a plugin is getting traffic from a pod on one node to a pod on another. Two broad styles exist, and nearly every plugin uses one or both.
| Style | Idea | Good at | Cost |
|---|---|---|---|
| Overlay | Wrap each pod packet inside an ordinary packet between nodes, like a letter inside an envelope, and unwrap it at the other end | Works on almost any underlying network with no special setup | Wrapping adds a little size and processing to every packet |
| Routed (native) | Teach the real network how to reach pod address ranges, so packets travel unwrapped | Fast, simple to inspect, no wrapping cost | The underlying network must allow it or be told the routes |
An overlay is like sending a small private letter inside a courier’s standard box. The courier does not care what is inside, and any courier will do, but the box adds weight. A routed network is like getting the postal service to learn your private street names, so the letter goes bare. It is lighter, but the post office must cooperate.
Where do pod addresses come from?
When the cluster is created, the administrator reserves a large address range for pods. That range is split into smaller slices, and each node receives one slice. When a pod is created on a node, the plugin picks an unused address from that node’s slice. Because slices never overlap, no two pods anywhere in the cluster can receive the same address. Some plugins let the cluster hand out slices; others manage pools themselves. The result is identical: unique addresses, no clashes.
Network policy: the rulebook and the enforcer
A network policy says things like “only pods labelled as the web tier may reach pods labelled as the database, and only on this port”. Kubernetes stores the policy, but Kubernetes does not enforce it. The enforcement is done by the CNI plugin. This is a crucial fact: on a plugin that does not implement network policy, the policy objects can be created without error and silently do nothing. We return to this in Chapter 9.
| Term | Plain meaning | Who owns it |
|---|---|---|
| Pod address | The number of one pod | Assigned by the plugin’s address manager |
| Node address | The number of one computer | Assigned by the infrastructure or the administrator |
| Service address | A stable virtual number in front of many pods | Kubernetes, made to work by the service proxy or the plugin |
| Network policy | The rules about who may talk to whom | Written by users, enforced by the plugin |
Do not confuse the pod network with the node network. Pods use one address range and nodes another. Choosing pod ranges that overlap with your company’s existing networks is one of the most common and most painful early mistakes.
4Architecture and Components
Several pieces cooperate to give a pod its network. It helps to see who talks to whom, from the moment Kubernetes decides to start a pod.
flowchart TB
API["Kubernetes control plane"] -->|"Pod placed on this node"| KL["Kubelet on the node"]
KL -->|"Create the pod sandbox"| RT["Container runtime"]
RT -->|"Call the plugin: add this pod"| CNI["CNI plugin program"]
CNI -->|"Ask for an address"| IPAM["Address manager"]
CNI -->|"Create virtual cable and routes"| NS["Pod network space"]
AG["Plugin agent on the node"] -->|"Keeps routes and rules up to date"| NS
AG -->|"Learns about pods and policies"| API
NS --> APP["Application containers"]
Reading Figure 2 piece by piece
Follow the arrows from the top. The control plane, which is the brain of Kubernetes, decides that a pod should run on a particular node. The kubelet on that node notices and asks the container runtime to create the pod. The runtime first creates an empty sealed room, called the pod sandbox, and then calls the CNI plugin program with a request to add this pod to the network.
The plugin program does the quick, one-time work: it asks the address manager for a free address, creates the virtual cable, places one end in the pod’s room, gives it the address and sets up the routes so packets know where to go. Then it reports success, and the runtime goes on to start the application containers.
Below and beside this flow sits the second half of most plugins: a long-running node agent. It is not part of the one-time set-up. Instead it runs all the time as a small program on every node, watching the cluster for changes such as new pods, moved pods, new nodes and new policies, and keeping the node’s routes and rules current. The plugin program is the quick installer; the agent is the caretaker.
The parts, one by one
Container runtime
The program that actually creates containers on a node. It is the one that calls the plugin. Popular runtimes follow the same CNI standard.
Plugin binary
A small executable stored in a known folder on every node. It receives a request, does its work and exits quickly.
Configuration file
A file in a known folder on every node that names the plugin and its settings. The runtime reads it to decide which plugin to call.
Node agent
A long-running helper, usually started as a daemon set so one copy runs on every node. It manages routes, rules and policies over time.
Address manager
Keeps track of which addresses are free and which are taken on each node, and gives them back when pods are deleted.
Data store or control channel
Some plugins keep shared state in the cluster’s own store or in a separate database, so every node’s agent shares one picture of the network.
Where the files live
Two folders on every node matter. One holds the plugin programs. The other holds the configuration file that says which plugin to use. When you install a plugin, its installer typically drops the program and the configuration file into these folders on every node. The runtime looks in the configuration folder, picks the first file in alphabetical order, and calls the plugin it names. That is why files in that folder are often given numbered names.
Think of a big hotel. The receptionist who checks in a guest quickly hands over a key and a room number: that is the plugin program. The night manager who walks the corridors, fixes broken lights and updates the guest list all night: that is the node agent. A great hotel needs both, and they need a shared guest register: the address manager.
When the plugin program works but pods cannot talk across nodes, suspect the agent side: routes, tunnels or rules that are not being updated. When pods cannot even start, suspect the plugin program, its configuration file or the address manager.
5How CNI Plugins Work Internally
Now let us open the box. We will look at the small conversation between the runtime and the plugin, and then at how a packet travels from one pod to another.
The conversation: four simple commands
The CNI standard defines a tiny vocabulary. The runtime sends the plugin one of a few commands, together with the details it needs, and the plugin replies with a result. The four commands are easy to remember.
| Command | Meaning | When it is sent |
|---|---|---|
| ADD | Connect this pod to the network and report its address | When a pod sandbox is created |
| DEL | Disconnect this pod and release its address | When a pod sandbox is removed |
| CHECK | Verify that the pod’s network is still as it should be | Occasionally, if the runtime supports it |
| VERSION | Report which versions of the standard the plugin understands | When the runtime needs to negotiate |
The details of each request, such as the pod’s identifier, the location of its private room and the network name, travel with the command. The plugin’s answer includes the address it assigned and the interfaces it created. Everything is plain, structured text, which is why plugins can be written in almost any language.
Chaining: several plugins in a row
The standard lets a configuration name several plugins in a list. The runtime calls them in order, passing the result of each to the next. A common arrangement uses a main plugin to create the connection and give the address, followed by small helper plugins that adjust bandwidth limits, enable port mappings or tune settings. Chaining is how features are added without rewriting the main plugin. Some advanced setups also let a pod have more than one network, using a special multiplexing plugin that calls several others.
flowchart LR
P1["Pod A on node 1"] --> V1["Virtual cable and node bridge"]
V1 --> Q{"Is the target pod on this node?"}
Q -->|"Yes"| P2["Pod B on the same node"]
Q -->|"No"| R{"How does this plugin cross nodes?"}
R -->|"Overlay"| T["Wrap packet and send through tunnel"]
R -->|"Routed"| RT["Send packet unwrapped along learned routes"]
T --> N2["Node 2 unwraps and delivers"]
RT --> N2
N2 --> P3["Pod C on node 2"]
Reading Figure 3
A message begins in Pod A. It leaves through the virtual cable and arrives at the node. The node asks the first question: is the target on this very node? If yes, the node simply hands it to the neighbour, and nothing leaves the machine. If no, the plugin’s style decides what happens. An overlay plugin wraps the packet in an outer packet addressed to the other node and sends it through a tunnel. A routed plugin sends it as it is, relying on routes that were previously taught to the network. Either way, the second node ends up holding the packet, removes any wrapping and delivers it to Pod C.
Same node
Fastest case. The packet crosses one virtual cable, the node’s bridge or routing table, and the neighbour’s cable. No physical wire is touched.
Different node, overlay
The packet is wrapped, travels over the ordinary node network like any other traffic, is unwrapped on arrival and delivered. It works anywhere the nodes can reach each other.
Different node, routed
Each node tells its neighbours, or the network, which pod ranges it owns. Packets then follow ordinary routes with no wrapping at all.
Out to the internet
Pod addresses are usually private and not routable on the internet, so the node rewrites the source address to its own as traffic leaves. This is the one place where address translation is normal.
Enforcement inside the node
Besides connecting pods, a plugin usually installs rules that decide which packets are allowed. Older plugins do this with the operating system’s classic packet-filtering tables. Newer ones, like Cilium, attach small programs to the kernel’s network path through a technology called eBPF, which lets safe, sandboxed programs run inside the operating system without changing it. We will meet the difference in Chapter 7.
Imagine a large office building. Delivering a memo to a colleague on your floor is easy: walk down the corridor. To reach another building, you either put the memo in a courier’s envelope (overlay), or you rely on a private road that the city has agreed to connect (routed). Security guards at each floor check badges: those are the rules the plugin installs.
The plugin program runs only at pod creation and deletion. It is not watching your cluster in between. Anything that must keep working over time, such as routes and rules, depends on the node agent staying healthy.
6Data Flow and Lifecycle
Let us follow one pod from birth to death and see what the network does at each stage.
sequenceDiagram
participant K as Kubelet
participant R as Runtime
participant C as CNI plugin
participant I as Address manager
participant A as Node agent
K->>R: Create pod sandbox
R->>C: ADD this pod
C->>I: Give me a free address
I-->>C: Address granted
C-->>R: Cable created, address set
R-->>K: Sandbox ready
K->>R: Start application containers
A->>A: Update routes and rules for the new pod
K->>R: Remove pod sandbox later
R->>C: DEL this pod
C->>I: Release the address
A->>A: Remove routes and rules
Reading Figure 4
The story runs from the top. The kubelet asks the runtime for a sandbox. The runtime asks the plugin to add the pod. The plugin asks the address manager for a free number, gets it, builds the virtual cable, and reports back. Only then does the kubelet start the application containers, which is why an application never starts without a network. Meanwhile the node agent quietly updates routes and rules so other nodes learn about the newcomer. At the end of life, the sequence reverses: the runtime calls DEL, the address returns to the pool and the agent removes the routes.
Six stages of a pod’s network life
Sandbox created
An empty private room exists, with nothing inside but a loopback connection to itself.
Plugin called
The runtime sends ADD. The plugin picks an address and builds the virtual cable.
Routes announced
The agent tells the rest of the cluster where the new address lives.
Traffic flows
The application starts, talks to services and to other pods, and receives requests.
Policy applied
Rules that match the pod’s labels are installed and enforced on its traffic.
Cleanup
On deletion, the plugin removes the cable, frees the address and the agent withdraws routes.
How services fit into the picture
Pods come and go, and their addresses change, so Kubernetes offers a stable virtual address called a service. A service is a fixed number in front of a changing group of pods. When a pod calls a service, something must translate the fixed number into the address of one healthy pod. Traditionally a component on every node called the service proxy does this, by installing rules that pick a pod at random. The CNI plugin’s job is different: it makes sure that once the real pod address is chosen, the packet can actually reach it. Some plugins, notably Cilium, can take over the service proxy job as well, so one system handles both the choosing and the delivery.
Understanding this split helps troubleshooting. If a service address fails but direct pod addresses work, look at the service proxy or its replacement. If direct pod addresses fail as well, look at the plugin. Two layers, two sets of suspects.
Service call, step by step
A pod calls a service name. The naming system returns the service’s fixed address. The node’s rules replace that address with one healthy pod’s real address. The plugin’s routes or tunnel carry the packet to the node holding that pod. The destination node delivers it through the pod’s virtual cable. The reply travels back the same way, and the rules translate the source so the caller sees the reply as coming from the service.
What if something goes wrong?
If the plugin fails during ADD, the runtime reports the failure to the kubelet, and the pod sandbox is torn down and retried. The pod shows a status such as container creating for a while, and the events mention that the network could not be set up. If cleanup fails during DEL, an address can stay reserved, called a leak, until a housekeeping process reclaims it. A cluster that churns through many short-lived pods can run out of addresses on a node if leaks accumulate, so good plugins track and reclaim these.
When a node restarts
The pods on it are recreated, and each goes through ADD again. Addresses may change, because a fresh pod is a new pod. That is why applications should find each other by service name, never by remembered pod address.
When a new node joins
It receives a slice of the address range, the agent starts on it, and other nodes’ agents learn the routes to reach it. New pods on it can join the network within moments.
When a policy changes
The agents notice the new or changed policy and update the rules on each node. Good plugins apply this change to running pods without restarting them.
Think of a hotel guest’s stay. Check-in assigns a room and a key card. During the stay, the key card opens only certain doors. At check-out, the room is cleaned and the card cancelled so the room can be given to someone else. If a guest forgets to check out properly, the room stays marked as taken until housekeeping notices.
Pod addresses are temporary. A replacement pod almost always gets a different address, so always use service names and let the cluster’s naming system find the current pods.
7Meet the Three: Flannel, Calico and Cilium
All three keep the promises from Chapter 1. They differ in philosophy, features and how they move packets. Let us meet each in turn.
flowchart TB
subgraph F["Flannel: simple overlay"]
F1["Pod"] --> F2["Node bridge"] --> F3["VXLAN tunnel"] --> F4["Other node"]
end
subgraph C["Calico: routed or overlay, plus rules"]
C1["Pod"] --> C2["Node routes"] --> C3["Learned routes or light tunnel"] --> C4["Other node"]
end
subgraph L["Cilium: kernel programs"]
L1["Pod"] --> L2["eBPF programs in the kernel"] --> L3["Routing or tunnel"] --> L4["Other node"]
end
Reading Figure 5
Each row shows the road a packet takes. Flannel’s path is short and easy to picture: the pod, a node bridge, a tunnel and the other node. Calico’s path uses ordinary routing, with routes learned from its own agent, and can fall back to a light tunnel when the underlying network will not carry pod routes. Cilium replaces much of the classic path with small programs running inside the kernel, deciding where packets go and whether they may pass.
Flannel: the simple one
Flannel was created to do one job with minimal fuss: give every node its own slice of pod addresses and connect the nodes with a simple overlay. Its default tunnel wraps pod packets in ordinary network packets, using a technology called VXLAN. It also offers other modes, such as routing directly between nodes on the same network, or encrypted tunnels using WireGuard.
Very simple
Few settings, few moving parts and easy to understand. A good choice for learning and small clusters.
Works almost anywhere
The overlay needs nothing special from the underlying network.
No network policy
Flannel by itself does not enforce network policies. To get policy, teams pair it with another component.
Few advanced features
There is little built-in observability, no rich security model and no advanced traffic handling.
Calico: the routing and policy specialist
Calico came from a networking-first mindset: treat pods as ordinary citizens of the network and route them like any other address. Its node agent, often called Felix, programs routes and rules on every node. A routing daemon shares pod ranges between nodes using a well-known internet routing protocol called BGP, so the real network learns where pods live and no wrapping is needed. When the network cannot carry those routes, Calico can switch to a light overlay.
Calico’s greatest fame is its network policy engine. It supports the standard Kubernetes policies and adds richer ones of its own, such as cluster-wide rules, ordering, explicit deny and rules based on more kinds of matching. It can enforce with classic packet filtering, or with an eBPF mode on modern kernels.
Mature policy
Rich, well-tested policy features, popular in security-conscious organisations.
Flexible modes
Pure routing, light tunnels or the eBPF mode, chosen to fit your network.
Scales well
Battle-tested in large clusters, with helper components to reduce load on the cluster’s store.
More to learn
More settings and concepts than Flannel, and routing knowledge helps when things go wrong.
Cilium: the kernel-powered one
Cilium is built on eBPF, the technology that lets small safe programs run inside the operating system’s kernel. Instead of long chains of packet-filtering rules, Cilium attaches programs directly to the network path. This can make lookups faster and gives Cilium deep visibility into traffic. It can also take over the job of the service proxy that normally handles Kubernetes service addresses, and it offers a rich observability tool called Hubble that shows who talked to whom.
A distinctive idea in Cilium is identity-based policy. Rather than tracking addresses, which change constantly, it gives each group of similar pods a numeric identity derived from their labels, and writes policy in terms of identities. It can also understand some application-level traffic, letting a rule say that a pod may call one web path but not another. Extra features include transparent encryption between nodes and connecting multiple clusters together.
Deep visibility
Built-in flow observability shows traffic and policy decisions in real time.
Identity-based policy
Rules stay valid as pods move and change addresses, and can reach up to application-level rules.
Rich feature set
Service handling, encryption, multi-cluster links and more, in one system.
Kernel requirements and complexity
It wants a reasonably modern kernel, and its power brings a steeper learning curve and more to operate.
Think of three delivery firms. Flannel is a small local courier: simple, reliable, one standard box. Calico is a national postal service: efficient roads, strict rules about who may deliver where. Cilium is a modern logistics company with scanners in every truck, seeing every parcel and deciding instantly what to do. Each is right for a different customer.
This article was written without live web research, and these products evolve quickly. Treat feature details, default modes and kernel requirements as a starting point, and confirm them against each project’s official documentation for the version you plan to run.
8Side by Side, and Beyond the Big Three
A single table cannot decide for you, but it shows the shape of the differences at a glance.
| Question | Flannel | Calico | Cilium |
|---|---|---|---|
| Main idea | Simple overlay for connectivity | Routing plus strong policy | Kernel-level programs with visibility |
| Cross-node method | Overlay tunnel by default, other modes available | Routing with BGP, or light tunnels | Tunnel or native routing |
| Network policy | Not by itself | Yes, standard and extended | Yes, standard and extended, identity-based |
| Observability | Minimal | Moderate | Rich, with flow visibility |
| Encryption between nodes | Available in some modes | Available with WireGuard | Available with WireGuard or IPsec |
| Kernel needs | Modest | Modest, higher for eBPF mode | Modern kernel recommended |
| Learning curve | Gentle | Moderate | Steeper |
| Typical fit | Learning, labs, small simple clusters | Security-focused and large clusters | Platforms wanting deep visibility and advanced features |
Other names you will meet
Cloud-provider plugins
Major clouds ship their own plugins that give pods real addresses from the cloud’s own virtual network. The AWS VPC plugin, for instance, gives pods addresses from the same network as the nodes, so pods are first-class citizens of the cloud network.
Canal-style combinations
Some setups pair one plugin for connectivity with another for policy, for example a simple overlay with a policy engine on top.
Multiplexers
A multiplexing plugin lets a pod attach to more than one network, useful for telecom and high-performance workloads.
Legacy options
Some once-popular plugins are no longer actively developed. Always check that a project is maintained before adopting it.
Cloud-native plugins versus portable plugins
A cloud plugin integrates tightly with one provider. Pods get real addresses from the virtual network, security groups and flow logs can see pod traffic, and no overlay is needed. The price is portability and limits: the number of addresses available may bound how many pods fit on a node, and moving to another cloud means changing the plugin. Portable plugins like the big three work everywhere, at the price of running their own network layer on top of the cloud’s. Many managed clusters offer a choice, and some teams run a portable plugin in a chained or overlay arrangement on top of the cloud’s own.
Choose portable when
You run in several clouds and on your own servers, or you want identical behaviour and policy everywhere.
Choose cloud-native when
You live in one cloud, want pods visible to native cloud networking tools, and value fewer moving parts.
Renting a flat that comes with the landlord’s own internet is convenient and tightly integrated, but you cannot take it with you. Bringing your own router works in every flat you ever rent, but you must set it up and look after it. Cloud plugins and portable plugins are those two choices.
9Network Policy and Security
By default every pod can talk to every other pod. That is convenient and dangerous. Network policy is how you close the doors that should never have been open.
Open by default
A fresh cluster behaves like an open-plan office with no walls. A compromised pod in a low-importance application can reach the database of an important one, simply because the network allows it. Attackers rely on this ease of movement, called lateral movement. Network policy turns the open office into rooms with locked doors.
How policies work in plain words
A policy selects a group of pods by their labels and then lists what is allowed to reach them, called ingress rules, and what they are allowed to reach, called egress rules. The key behaviour is this: once any policy selects a pod for a direction, everything not explicitly allowed in that direction is denied. Policies only add permissions; they never subtract, so several policies on one pod combine into one wider set of allowed traffic.
Start with default deny
Apply a policy to each namespace that selects all pods and allows nothing. Now everything is closed.
Allow what is needed
Add small policies that open just the paths each application requires, such as web tier to database on one port.
Remember name lookups
Pods need to reach the cluster’s naming service. A deny-all egress policy without an exception for it breaks almost everything.
Test and observe
Try allowed and forbidden paths. Use your plugin’s visibility tools to confirm the drops you expect.
| Capability | Standard Kubernetes policy | Extended policy (Calico, Cilium) |
|---|---|---|
| Select pods by label | Yes | Yes |
| Rules by namespace | Yes | Yes |
| Explicit deny rules | No, only allow | Yes |
| Cluster-wide policies | No, per namespace | Yes |
| Rule ordering and priority | No | Yes |
| Rules by domain name | No | Available in some editions or modes |
| Application-level rules | No | Cilium supports some |
A worked policy example in words
Imagine a shop with three tiers: a web tier, an orders tier and a database tier, each in its own group of pods with its own label. First, a default-deny policy closes every direction for all pods in the shop’s namespace. Second, a policy allows the outside world to reach the web tier on its public port. Third, a policy allows only the web tier to call the orders tier on its service port. Fourth, a policy allows only the orders tier to reach the database on its port. Fifth, a small egress policy lets every tier reach the cluster’s naming service, and lets the orders tier call one named payment provider outside. The result is a clear picture: traffic can flow down the chain and nowhere else. If a pod in the web tier is compromised, it cannot talk to the database directly, because no policy opens that door.
Notice how readable this is. Each policy is one sentence in plain language, tied to labels. When a new engineer asks how the shop is protected, the answer is a short list of sentences, not a maze of addresses and ports.
Other security topics
Encrypt traffic between nodes
Overlay and routed traffic normally crosses the node network unencrypted. Plugins can add encrypted tunnels so that snooping on the wire reveals nothing.
Host-network pods
Pods that share the node’s own network bypass much pod-level policy. Keep their number small and their purposes clear.
Who can change policy
Anyone able to edit policies can open or close doors for the whole cluster. Guard that permission carefully.
Trust the plugin’s images
The plugin’s agent runs with high privilege on every node. Use official sources, pin versions and keep them updated.
Egress control
Limit which outside places pods can call. This helps stop data theft after a break-in.
Log denied traffic
Record blocked connections so that attacks and mistakes are both visible.
An open cluster is like an apartment block where every door is unlocked and every resident has a master key. Default deny changes every lock at once. Individual policies then hand out keys only to the neighbours who really need them, and the building manager keeps a log of every attempted entry.
A policy that your plugin does not enforce will be accepted by Kubernetes and do absolutely nothing. Always test that a forbidden connection is really blocked, or you may be running with a false sense of safety.
10Choosing the Right Plugin
There is no best plugin, only the best fit for your platform, your people and your needs. A few questions get you most of the way.
flowchart TD
A["Which plugin should I choose?"] --> B{"Do I need network policy?"}
B -->|"No, learning or tiny lab"| C["Flannel is enough"]
B -->|"Yes"| D{"Do I want deep traffic visibility and identity rules?"}
D -->|"Yes, and my kernel is modern"| E["Cilium"]
D -->|"No, mature policy and routing are enough"| F["Calico"]
A --> G{"Am I locked to one cloud and want native pod addresses?"}
G -->|"Yes"| H["Consider the cloud provider plugin"]
Reading Figure 6
Begin with the top question about network policy. If you need no policy, for instance in a learning lab or a tiny personal cluster, the simplicity of Flannel is hard to beat. If you do need policy, the next question is about depth. If you want detailed visibility, identity-based rules and advanced features and you run a modern kernel, Cilium fits. If a mature, proven policy engine with flexible routing is enough, Calico fits. A separate branch reminds you that if you live in one cloud, the provider’s own plugin deserves a look for its native pod addresses.
The questions behind the chart
Where does it run?
Own servers, one cloud or several? Managed clusters may restrict your choices or come with a default.
What must be secured?
Regulated data or multi-team clusters usually need strong policy and auditing.
How big will it grow?
Hundreds of nodes and thousands of pods put scale, address planning and control-plane load in the spotlight.
What do our people know?
A network engineer may love Calico’s routing. A team keen on modern tooling may prefer Cilium. A small team may prefer Flannel’s simplicity.
What are our kernels?
Advanced modes need modern kernels. Check what your machine images provide.
How easily can we change later?
Swapping plugins in a live cluster is hard. Choose as if you will live with it for years.
A student laptop cluster
Learning how pods talk. Simplicity wins, and Flannel or the default of your local tool is fine.
A regulated company with many teams
Policy, auditing and encryption matter most. Calico or Cilium, chosen on your team’s skills and kernel support.
A platform team that wants visibility
They spend hours debugging network mysteries. Cilium’s flow visibility repays its learning curve.
A single-cloud product
The cloud plugin or a portable plugin layered on it, decided by address limits and policy needs.
Choosing a plugin is like choosing a vehicle. A bicycle is perfect for a short trip, a family car suits most people, and a specialised truck is right when you carry heavy loads. Buying the truck for a trip to the corner shop wastes money, and biking cross-country with a piano fails.
Whichever you choose, try it in a test cluster that mirrors production, including your policies and your traffic patterns, before you commit.
11Performance and Scaling
Networking sits on the critical path of every request. Small inefficiencies multiply when millions of packets flow each second.
Where the time goes
Wrapping and unwrapping
Overlays add extra headers to every packet and work at both ends. The overhead is small per packet and adds up under heavy load.
Packet size limits
Wrapping shrinks the room for data in each packet. If sizes are not adjusted, big packets are split or dropped, causing strange slowness.
Long rule lists
Classic packet filtering checks rules in sequence. Thousands of rules can slow every packet and slow rule updates.
Connection tracking
The kernel remembers every active connection. A busy node can fill this table and drop new connections.
Encryption
Encrypting traffic between nodes costs processing power, and is worth it where privacy matters.
Control-plane chatter
In big clusters, every agent watching for changes puts load on the cluster’s store. Plugins use helper components to soften this.
Ways to go faster
Routed modes avoid wrapping, so where the underlying network allows it, routing is usually faster than tunnelling. Kernel-program approaches like eBPF replace long rule lists with quick lookups, which helps in clusters with many services and policies. Taking over the service proxy function in the same layer removes another set of rules. Using the largest packet size the network supports, and setting the plugin’s packet size correctly, prevents fragmentation. Finally, sizing address slices sensibly avoids running out of addresses on busy nodes.
| Concern | Symptom | Typical remedy |
|---|---|---|
| Packet size mismatch | Small requests work, large ones hang or crawl | Set the plugin’s packet size to fit the tunnel overhead |
| Overlay overhead | Lower throughput and higher processor use than expected | Use a routed mode where possible |
| Huge rule lists | Slow policy updates, high processor use in the kernel | Use a kernel-program data path or reduce rules |
| Full connection table | Random dropped new connections under load | Raise the table size, reduce short connections |
| Address exhaustion | New pods stuck creating on a busy node | Larger slices per node or fewer pods per node |
Scaling out
When a cluster grows from ten nodes to a thousand, the shared state that all agents watch becomes a bottleneck. Plugins respond with caching proxies between agents and the store, with route reflectors that avoid every node talking to every other, and with careful batching of updates. Plan your address ranges for the size you may become, not the size you are, because changing them later means rebuilding.
Think of a road network. Wrapping every car in a protective bubble makes travel safe and flexible but adds weight. Building dedicated fast lanes removes that cost but needs the city’s cooperation. As the city grows, you need ring roads and traffic control, not just more cars on the same roads.
Do not tune blindly. Measure throughput, latency and processor use with a realistic test between pods on different nodes, before and after each change.
12Advantages, Disadvantages and Trade-offs
Every choice buys something and costs something. Here is an honest ledger for the CNI approach and for the three plugins.
Swappable network
One standard means you can pick the networking that suits you without changing Kubernetes.
Rich ecosystem
Many plugins compete, each with its own strengths, pushing the whole field forward.
Simple pod model
Every pod has its own address, so applications need no port juggling.
Policy and security
Modern plugins can lock down traffic and encrypt it.
Choice overload
Beginners face a bewildering list of options with no single obvious answer.
Hard to change later
Switching plugins in a live cluster is risky and often means rebuilding.
Deep debugging
Problems can hide in kernels, tunnels and rules, needing specialist knowledge.
Privileged agents
Node agents hold high power, making them attractive targets.
Trade-offs in plain words
The first trade-off is simplicity against features. Flannel is easy to grasp and hard to break, but gives you no policy and little visibility. Cilium gives a great deal, but you must understand and operate a more complex system. Calico sits in the middle. The right point on this line depends on how much you need and how much complexity your team can carry.
The second is overlay against routed. An overlay works everywhere and asks nothing of the network, at a modest performance cost. Routing is faster and easier to inspect but needs cooperation from the network, which may be hard in cloud or corporate environments.
The third is portability against integration. A cloud plugin integrates neatly but ties you to one provider. A portable plugin runs anywhere but adds its own layer. Decide how likely you are to move, and how much you value native integration today.
The fourth is maturity against novelty. Older techniques such as classic packet filtering are proven and widely understood. Newer kernel programs promise speed and insight but demand modern systems and newer skills. Neither is wrong; they suit different teams at different times.
Buying a phone plan is a similar trade. The cheap, basic plan is easy and enough for many. The premium plan offers extras that only some people use, and comes with a more complicated bill. The smart move is to buy what you will actually use, with a little room to grow.
13Monitoring, Logging and Troubleshooting
When the pod network breaks, everything above it breaks with it. A calm, layered routine finds the fault quickly.
Symptoms and where to look
| What you see | Likely meaning | Where to look first |
|---|---|---|
| Nodes show not ready, message about the network plugin not initialised | No plugin installed, or its configuration is missing | Plugin installation, configuration folder on the node |
| Pods stuck creating, events mention network setup failure | Plugin program failed during ADD | Pod events, plugin agent logs on that node |
| Pods on same node talk, different nodes do not | Cross-node path broken: tunnel, routes or firewall | Agent health, firewall between nodes, tunnel ports |
| Name lookups fail | Naming service pods unreachable or blocked by policy | Naming service pods, egress policies |
| Only large requests fail | Packet size mismatch | Plugin’s packet size against network limits |
| Traffic blocked unexpectedly | A policy is denying it | Policies that select the pod, plugin’s flow or drop logs |
| Traffic allowed that should be blocked | Plugin does not enforce policy, or no policy selects the pod | Plugin capabilities, policy selectors |
| Pods cannot get an address | Node slice exhausted or address manager unhealthy | Address usage per node, leaked addresses |
A layered troubleshooting routine
Work from the bottom up. First, check the nodes: are they ready, and can they reach one another on the node network? Second, check the plugin’s node agents: is one healthy on every node, and do its logs show errors? Third, test the same-node path, then the cross-node path, using a simple test pod in each place. Fourth, test name lookups separately, because failures there look like network failures. Fifth, review policies that could select the affected pods. Sixth, use your plugin’s own diagnostic and visibility tools, which often say plainly which rule dropped a packet.
Nodes and the underlay
Ready status, node-to-node reachability, and firewalls that might block tunnel or routing traffic between nodes.
Plugin agents
Healthy agent on every node, matching versions, and clean logs.
Pod-to-pod paths
Test pods on the same node and on different nodes, by address.
Services and names
Service addresses resolve and route correctly to healthy pods.
Policies
Which policies select the pod, and whether they allow the path.
External paths
Outbound translation, gateways and load balancers between the cluster and the world.
What to monitor all the time
Track agent health and restarts on every node, the number of free addresses per node, dropped packet counters, policy denials, connection table use, tunnel health and latency between nodes. Alert when agents crash, when free addresses run low, and when drops jump suddenly. Ship agent logs to a central place so that you can investigate after a node has gone. Plugins such as Cilium and Calico expose metrics that fit well into common dashboards, and Cilium’s flow tool shows conversations directly.
A worked example
A team sees that pods in one zone cannot reach pods in another, while pods within each zone are fine. Step one: nodes are ready. Step two: agents are healthy. Step three: same-node tests pass, cross-node tests fail only across zones. The team suspects the underlay and checks firewalls: a recent change blocked the tunnel’s port between the zones. Reopening it restores service. The routine narrowed a scary outage to one firewall rule in fifteen minutes.
Diagnosing a road problem, a good traffic officer checks the road surface first, then the traffic lights, then the signs, then individual vehicles. Guessing at the vehicle first, when a bridge has closed, wastes hours. The layered routine is the officer’s checklist.
Keep a permanent test pod image with basic network tools available, and know how to place a copy on a specific node. It makes each step of the routine a thirty-second job.
14Design Patterns and Anti-patterns
A pattern is a proven way of solving a repeated problem. An anti-pattern is a tempting habit that keeps causing pain.
Patterns worth adopting
Plan address ranges first
Reserve pod and service ranges that never overlap with company networks, and leave room for growth and future clusters.
Default deny, then allow
Close every namespace by default and open only the paths each application needs.
Policy as code
Keep policies in version control, review them like application code and deploy them with the application.
Test cluster first
Try plugin upgrades and policy changes in a mirror of production before touching the real thing.
Labels as the language of policy
Use clear, consistent labels for tiers and teams so that policies read like sentences.
Observe before you enforce
Watch real traffic flows first, then write policies that match reality.
Anti-patterns to avoid
Overlapping ranges
Pod ranges that collide with office or partner networks cause unreachable destinations that are very hard to diagnose.
Assuming policy works
Writing policies on a plugin that does not enforce them, then trusting them.
Choosing by fashion
Picking the newest or trendiest plugin without matching it to your kernels, skills and needs.
Skipping the upgrade plan
Upgrading the plugin cluster-wide in one step, with no rollback path.
Hard-coded pod addresses
Applications that remember a pod’s address break the first time that pod is replaced.
Everything on the host network
Bypassing the pod network for convenience skips policy and isolation.
Context
A company is building a shared Kubernetes platform for twelve teams. Security requires isolation between teams, and the platform team wants to see traffic when troubleshooting. Machine images use a modern kernel.
Options considered
Flannel for simplicity, Calico for mature policy and routing, and Cilium for policy plus flow visibility.
Decision
Adopt Cilium, with default-deny policies per team namespace and flow visibility enabled. Flannel is rejected because it lacks policy. Calico remains the fallback if kernel or skill constraints appear.
Consequences
The platform team must invest in learning the tool and its upgrade process. In return, teams get consistent isolation and faster troubleshooting. The decision will be reviewed after the first two upgrade cycles.
City planners lay out streets and reserve land for future roads before the first house is built. Planners who improvise street by street end up with dead ends and collisions that cost fortunes to fix later. Address planning is the map drawn before construction.
15Best Practices and Common Mistakes
This chapter gathers the advice into checklists you can keep beside your desk.
Best practices
Planning
Reserve generous, non-overlapping ranges for pods and services. Decide the plugin before creating the cluster. Confirm kernel versions and cloud limits. Document the choice and the reasons.
Security
Use default deny in every namespace and allow explicitly. Encrypt traffic between nodes where data is sensitive. Restrict who can edit policies. Keep the plugin’s images and agents patched and pinned.
Operations
Monitor agents, address usage, drops and tunnel health. Keep a test pod ready. Ship logs off the nodes. Rehearse plugin upgrades in a test cluster and upgrade nodes in small groups.
Applications
Use service names, never pod addresses. Design applications to retry brief network failures. Label workloads consistently so policies stay readable.
Common mistakes
| Mistake | Why it hurts | Better approach |
|---|---|---|
| Overlapping address ranges | Some destinations become unreachable | Plan ranges centrally before creating clusters |
| Writing policies on a plugin that ignores them | False sense of security | Choose an enforcing plugin and test blocks |
| Deny-all egress without name lookups | Applications lose the ability to find each other | Allow the naming service explicitly |
| Firewalls block tunnel or routing ports | Cross-node traffic fails while same-node works | Open the plugin’s required ports between nodes |
| Ignoring packet size | Large requests stall mysteriously | Set the correct size for the tunnel overhead |
| Changing plugins in place | Pods lose connectivity mid-migration | Plan a new cluster or a carefully staged migration |
| Skipping agent monitoring | Silent failures spread across nodes | Alert on agent crashes and restarts |
| Too few addresses per node | New pods cannot start on busy nodes | Size node slices to the pods you plan to run |
| Blaming the application first | Wastes time when the network is at fault | Use the layered routine from Chapter 13 |
A note on migrating between plugins
Changing the plugin of a running cluster is one of the riskiest operations in Kubernetes. Pods already have addresses and connections created by the old plugin, and the old and new plugins may disagree about ranges, tunnels and rules. Some projects document staged migration paths that run both plugins side by side for a while, moving nodes over in groups. Most teams find it safer to build a new cluster with the new plugin and move workloads across. Whichever route you take, rehearse it, plan a rollback and schedule downtime windows for critical systems.
Whenever you review a network change, ask three things: do the ranges overlap with anything, does the plugin enforce what we wrote, and how do we roll back?
16Real-World Usage Stories
These generic stories, based on common patterns rather than any specific company, show how the choices play out.
The start-up that outgrew its lab network
A small team began with Flannel on three nodes and was happy. As the company grew and started handling customer data, auditors asked for proof that the payment service could not be reached from other services. Flannel could not enforce policy. The team built a new cluster with a policy-capable plugin, moved workloads over one service at a time and kept the old cluster for a month as insurance. They learned to ask about policy needs on day one.
The overlapping ranges surprise
A company connected its new cluster to its office network and found that a handful of internal tools were unreachable from pods. The pod range they had picked, the plugin’s default, overlapped with a range used by the office. Every packet to those tools was treated as local to the cluster. Fixing this required rebuilding the cluster with a different range. Since then, the team’s first step for any cluster is a central address plan.
The mystery of the stalled uploads
Users could open pages but large file uploads hung. Health checks were green and small requests were fine. The cause was a packet size mismatch: the tunnel added a few bytes to each packet, so full-size packets exceeded the network’s limit and were dropped. Lowering the plugin’s packet size fixed uploads instantly. The team added a large-transfer test to its network checks.
The platform team that gained eyes
A platform team had spent countless hours guessing why services could not reach each other. After moving to a plugin with flow visibility, they could see each connection and the exact policy that dropped it. A category of ticket that once took hours began to take minutes, and application teams learned to check the flow view before asking for help.
The firewall change on a Friday
A network team tightened a firewall between availability zones and unknowingly blocked the plugin’s tunnel port. Pods within a zone kept working, and cross-zone calls failed. Because the on-call engineer followed the layered routine, the fault was found within twenty minutes. The teams later agreed to document the plugin’s required ports in the firewall change process.
Three worked scenarios: thinking like a designer
Scenario one: a training cluster for new hires
The goal is to teach basic Kubernetes to twenty new hires, using small clusters that are created and destroyed weekly. Policy is not needed, kernels are ordinary and the priority is easy setup. Flannel, or the default of the local cluster tool, wins. Adding a complex plugin would distract from the lesson and add failure modes for people who are still learning what a pod is.
Scenario two: a bank-style shared platform
Many teams share one cluster, and auditors require proof of isolation and encrypted internal traffic. Policy depth, encryption and audit logs matter more than simplicity. Calico or Cilium fits, with default-deny per namespace and encryption between nodes. The decision between them turns on the team’s routing skills, kernel versions and appetite for visibility tools.
Scenario three: a single-cloud web business
All workloads run in one cloud, and the team values seeing pod traffic in the cloud’s own flow logs and security tools. The provider’s plugin gives pods real addresses in the cloud network, which makes this natural. The team checks the address limits per node, plans larger subnets, and adds a policy layer if the provider’s plugin alone does not meet their isolation needs.
A short mental checklist for a new cluster
Before creating a cluster, pause and walk through a short list. State your needs in one sentence: policy, visibility, cloud integration or simplicity. Check the kernel versions your machine images provide. Choose pod and service ranges that overlap with nothing. Decide how nodes will reach each other and which ports the plugin needs open. Decide how you will test that policy really blocks. Decide how you will monitor agents and free addresses. Finally, write down how you would migrate away if you had to. Ten minutes on this list prevents most of the problems in this article.
17Frequently Asked Questions
Quick answers to the questions beginners ask most often.
This post was written without live web research. Please verify version-sensitive details, such as default modes, kernel requirements and feature availability, against each project’s official documentation.
18Summary and Key Takeaways
Let us close the loop, returning to the new city from the start of this article.
Just as a growing city needs someone to number the houses, lay the roads and decide who may visit whom, a Kubernetes cluster needs a CNI plugin. It gives each pod a unique address, connects pods across nodes, tears everything down cleanly when a pod ends, and, in most modern plugins, enforces rules about which pods may talk.
You met the problem of sealed rooms, the core building blocks, and the architecture of plugin program, node agent and address manager. You followed a pod’s network life and a packet’s journey, compared overlay and routed styles, and met Flannel, Calico and Cilium along with cloud-native alternatives. You learned about policy, performance, trade-offs, troubleshooting and the mistakes that cost teams the most.
Version drift and things to verify
Kubernetes networking changes steadily. Default modes, supported kernels, policy features and the maintenance status of individual plugins have all shifted over the years. Because this article was written without live web research, treat version-specific statements as a starting point. Before relying on a feature in production, read the official documentation for the exact version you will run, try the behaviour in a test cluster, and record the version in your team’s notes so upgrades prompt a re-check. Managed platforms add their own rules, so check what yours permits.
A small glossary to keep nearby
CNI
The standard that lets container platforms ask a plugin to set up networking.
Overlay
A network built by wrapping packets inside other packets between nodes.
Routed network
A design where the real network learns pod ranges, so packets travel unwrapped.
IPAM
The management of pod addresses: handing them out and taking them back.
Network policy
Rules about which pods may talk to which, enforced by the plugin.
eBPF
Small safe programs that run inside the kernel, used for fast, visible networking.
BGP
A protocol for sharing which address ranges each router can reach.
Node agent
The long-running helper on each node that keeps routes and rules current.
Key takeaways
Kubernetes sets the promises, plugins keep them
Every pod gets a unique address and can reach every other pod without tricks.
Two halves
A quick plugin program at pod creation, and a long-running agent that keeps the node current.
Flannel is simple, Calico is policy and routing, Cilium is kernel power
Choose by your needs, kernels, skills and platform.
Policy needs an enforcer
Policies on a plugin that ignores them do nothing. Test that blocks are real.
Plan addresses first
Overlapping or too-small ranges are the costliest early mistakes.
Troubleshoot in layers
Nodes, agents, pod paths, names, policies, then outside paths.
Look at your own cluster. Find out which plugin it runs, which address ranges it uses and whether your policies are really enforced. That small review teaches more than any article.