What Is CNI in Docker? A Complete Guide to Container Network Interface Plugins

What Is CNI in Docker? A Complete Guide to Container Network Interface Plugins

From a single bridge network to pluggable, production-grade networking — how CNI plugins work, why Docker's own model is different, and how the two worlds meet in real infrastructure.

Imagine you just moved into a new apartment building. Before you can get water, electricity, or internet, someone has to physically connect your unit to the building’s utility lines. Containers face the exact same problem the instant they are born: a freshly created container is like an apartment with no pipes and no wires. It cannot talk to other containers, it cannot reach the internet, and nothing outside can reach it either. Something has to lay down that “plumbing” — assign it an IP address, wire it into a virtual network, and set up the routing rules that let traffic flow in and out. That “something,” in a huge slice of the modern container world, is a small, specialized program called a CNI plugin. This guide walks through exactly what CNI is, how it works step by step, where it fits (and where it does not fit) in Docker specifically, and how to use it safely and correctly in real production systems.

1Core Concepts: What Container Networking Actually Solves

Before CNI makes sense, you need to understand the raw problem every container platform must solve.

A container, at its heart, is just an isolated process running on a host machine. Linux gives it isolation through two building blocks: namespaces (which give the process its own private view of things like network interfaces, process IDs, and mount points) and cgroups (which limit how much CPU, memory, and I/O it can consume). The network namespace is the one that matters here — when a container is created, Linux can give it a completely empty, private network stack: no interfaces, no routes, no IP address, nothing. It is a sealed room with no doors.

Someone has to open a door. That means: creating a virtual network interface inside the container’s namespace, connecting the other end of that interface to something on the host (usually a virtual bridge or switch), assigning an IP address to the container’s side, and adding routing rules so packets know where to go. This whole sequence is called network plumbing, and every container platform — Docker, Kubernetes, containerd, Podman — needs a consistent, repeatable way to do it every single time a container starts.

Everyday Analogy

Think of a shipping port. Every ship (container) that docks needs a crane operator to connect it to the port’s water, fuel, and cargo lines using the exact same standardized couplings, no matter which shipping company built the ship. CNI is that standardized coupling — a fixed “socket” that lets any container runtime plug into any networking solution, as long as both sides follow the same interface.

Two competing ideas emerged to standardize this plumbing: Docker built its own model called the Container Network Model (CNM), implemented through a library called libnetwork. Separately, CoreOS (the company behind rkt, an early Docker competitor) proposed a simpler, more minimal specification called the Container Network Interface (CNI). CNI was later donated to the Cloud Native Computing Foundation (CNCF) and became the networking standard used by Kubernetes and most of the container ecosystem outside Docker itself. Understanding both models — and how they differ — is the key to understanding this entire topic, because it explains why the question “what is CNI in Docker?” has a more nuanced answer than a simple one-line definition.

2What CNI Actually Is

CNI stands for Container Network Interface. Despite the name, it is not a piece of software you install and run — it is a specification, a contract. It defines, in very precise terms, how a container runtime (the software that creates and manages containers) should talk to a network plugin (the software that actually sets up networking) so the two can work together no matter who wrote either side.

The contract is deliberately tiny. A CNI plugin is just an executable binary that understands four operations, delivered as commands with a JSON configuration piped into its standard input:

Command

ADD

Attach a container’s network namespace to the network — create the interface, assign an IP, and set up routes.

Command

DEL

Tear everything down when the container is removed — release the IP, delete the interface, clean up routes.

Command

CHECK

Verify that a previously configured network is still correctly set up and healthy.

Command

VERSION

Report which versions of the CNI spec this particular plugin supports.

That’s it. Four verbs. Everything else — how the IP address is chosen, whether encryption is used, whether there is a firewall in front of the container — is left entirely up to whichever plugin implements those four verbs. This minimalism is exactly why CNI spread so widely: writing a new plugin is a small, well-defined task, so an entire ecosystem of networking vendors (Calico, Cilium, Flannel, Weave, AWS VPC CNI, Azure CNI, and dozens more) could all build compatible plugins independently, and any CNI-compatible runtime could use any of them interchangeably.

i
Key Distinction

CNI is a specification, not a product. “Installing CNI” really means installing a specific CNI-compliant plugin (like Calico) plus the small set of binaries and config files that let a runtime discover and invoke it.

3Docker’s Own Model: CNM, Not CNI

This is the part most tutorials skip, and it is the single most important fact in this whole guide.

Classic Docker Engine — the docker run, docker network create world most people picture when they hear “Docker” — does not use CNI by default. Docker built and uses its own model, the Container Network Model (CNM), implemented by an internal library called libnetwork. When you run docker network create mynet or attach a container to the default bridge network, you are watching CNM in action, not CNI.

CNM organizes networking around three concepts instead of CNI’s four commands:

CNM ConceptWhat It Means
Network SandboxThe isolated network stack for one container (its namespace, interfaces, routes, DNS config)
EndpointA virtual network interface that joins a sandbox to a network — like a network card
NetworkA group of endpoints that can freely communicate — e.g. a bridge network or overlay network

Docker ships built-in CNM drivers for common cases: bridge (the default, a private virtual switch on a single host), host (the container shares the host’s network stack directly, no isolation), overlay (a virtual network spanning multiple hosts, used by Docker Swarm), macvlan (gives a container its own MAC address on the physical network, as if it were a real device), and none (no networking at all). These drivers are conceptually similar in purpose to CNI plugins — they both “plumb” a container into a network — but they speak a completely different internal protocol and cannot be swapped for a CNI plugin without extra glue.

CNM (Docker Native)

  • Built into Docker Engine, zero extra install
  • Simple for single-host use cases
  • Tightly integrated with Docker Swarm

CNI (External Standard)

  • Not natively spoken by Docker Engine
  • Requires a runtime that understands CNI (Kubernetes, containerd directly)
  • Huge, vendor-neutral plugin ecosystem

So where does the question “CNI in Docker” come from, if Docker Engine does not speak CNI? Three real situations explain it, and they are the reason this topic causes so much confusion online.

4The Three Places CNI Actually Meets Docker

1. Kubernetes Running on Top of Docker (Historical)

For years, the most common way to run Kubernetes was with Docker Engine as the container runtime underneath it, via a compatibility shim called dockershim. In this setup, Kubernetes itself — not Docker — called the CNI plugin to wire up pod networking, while Docker was only responsible for pulling images and running the container processes. People described this whole stack loosely as “CNI in Docker,” even though Docker’s own daemon never invoked CNI directly; Kubernetes did. Kubernetes removed dockershim in version 1.24 (2022), so this exact arrangement is now legacy, though it explains most of the historical documentation and StackOverflow answers still floating around.

2. containerd — The Engine Underneath Docker — Speaks CNI Natively

Modern Docker Engine is actually built on top of a lower-level runtime called containerd (Docker donated it to the CNCF in 2017). Containerd has first-class, built-in CNI support and uses it directly when it is driven by Kubernetes (via the CRI, Container Runtime Interface) or by other CNI-aware tooling — completely bypassing Docker’s own CNM layer. So the containerd process sitting underneath your Docker installation is fully CNI-capable, even though the Docker CLI and daemon layered on top of it are not the ones invoking those plugins in a typical docker run.

3. Docker Swarm and Third-Party CNI Bridges

A small number of third-party and experimental projects exist to bridge CNI plugins into Docker Swarm or plain Docker networking, letting a CNI plugin like Calico or Weave manage IP address allocation and policy for Docker containers via a custom network driver plugin (Docker does support pluggable network drivers through its own plugin API — a different mechanism from CNI, but often confused with it because the vendor is the same, e.g. “Weave Net” ships both a Docker network plugin and a CNI plugin from one codebase).

!
Common Misconception

“Docker uses CNI” is only true indirectly, through containerd or through Kubernetes sitting on top of Docker-family runtimes. A plain docker run on a developer laptop is using CNM/libnetwork, full stop.

5Architecture and Components of a CNI Setup

A working CNI installation is made of a handful of concrete pieces sitting on disk, not one monolithic program. Understanding each piece makes debugging real clusters dramatically easier.

Binary

CNI Plugin Executable

A single compiled binary (e.g. calico, bridge, flannel) placed in a well-known directory, typically /opt/cni/bin.

Config

Network Configuration File

A JSON file in /etc/cni/net.d/ describing which plugin(s) to run and with what parameters for a given network.

Runtime

Container Runtime / Orchestrator

The caller — containerd, CRI-O, or Kubernetes’ kubelet — that invokes the plugin at the right lifecycle moment.

Store

IPAM Data Store

Wherever IP address allocation state is tracked — local files, etcd, or a cloud provider’s IP address management service.

Plugins are frequently chained. A single network configuration file can list several plugins that run in sequence, each one enriching the result of the previous one. A very common chain looks like: a main plugin (e.g. bridge or calico) creates the interface and wires it to the network, an IPAM plugin (e.g. host-local or whereabouts) hands out the IP address, and one or more meta plugins (e.g. portmap, bandwidth, tuning) apply extra behavior like port forwarding or traffic shaping on top.

graph TB
    RT["Container Runtime
(containerd / kubelet)"] -->|invokes with JSON config| MAIN["Main Plugin
e.g. Calico / Bridge"] MAIN --> IPAM["IPAM Plugin
e.g. host-local"] IPAM -->|assigns IP| MAIN MAIN --> META1["Meta Plugin
portmap"] META1 --> META2["Meta Plugin
bandwidth"] META2 --> NS["Container Network Namespace"] MAIN -.->|creates veth pair| BR["Host Bridge / Overlay"] BR --> HOSTNET["Host Network Stack"]
Fig. 1 — A chained CNI plugin invocation from runtime to container namespace
?
What an interviewer may ask

“Why does CNI separate the main plugin from the IPAM plugin instead of bundling address allocation into every plugin?” — Strong answer: separation of concerns. IP address management is a genuinely independent problem (avoiding collisions, respecting subnets, integrating with cloud IPAM services), so letting any main plugin delegate to any IPAM plugin avoids every network plugin author reinventing address allocation, and lets operators swap allocation strategies without touching the networking logic itself.

6Internal Working: What Happens Inside a Plugin Call

When the runtime decides a container needs networking, it does not open a persistent connection to a daemon — it simply executes the plugin binary as a short-lived process, exactly once per operation, and communicates with it through three channels: environment variables, standard input, and the exit code.

1

Runtime creates the network namespace

Before calling any plugin, the runtime creates an empty Linux network namespace for the new container — the “sealed room” from Chapter 1.

2

Runtime sets environment variables

Variables like CNI_COMMAND=ADD, CNI_CONTAINERID, CNI_NETNS (path to the namespace), and CNI_IFNAME (desired interface name, usually eth0) are exported for the plugin to read.

3

Runtime pipes the JSON config to stdin

The network configuration file’s JSON content (plugin type, subnet, MTU, any custom fields) is written to the plugin process’s standard input.

4

Plugin performs the actual networking work

The plugin enters the given namespace, creates a virtual ethernet (veth) pair — one end stays on the host, the other is moved inside the container namespace — and wires the host end to a bridge, an overlay tunnel, or a physical interface.

5

Plugin delegates to IPAM if chained

If an IPAM plugin is configured, the main plugin invokes it the same way it was invoked — same environment-variable-and-stdin pattern — and receives back an assigned IP address and gateway.

6

Plugin returns structured JSON on stdout

The plugin prints a JSON result describing the interfaces created and IPs assigned, which the runtime parses and stores for later use (e.g. to answer kubectl get pod -o wide).

Because every step is stateless and process-based, CNI plugins are unusually easy to test in isolation — you can literally invoke one by hand from a shell with the right environment variables set, which is exactly how experienced engineers debug broken pod networking in production.

7Data Flow and Lifecycle of a Networked Container

Zooming out from a single plugin call, here is the full lifecycle a container’s network identity moves through, from birth to death, in a CNI-managed environment such as Kubernetes.

sequenceDiagram
    participant U as Operator/Scheduler
    participant KB as Kubelet
    participant CR as containerd
    participant CNI as CNI Plugin
    participant NS as Pod Netns
    U->>KB: Schedule Pod on Node
    KB->>CR: Create sandbox (pause container)
    CR->>NS: Create empty network namespace
    KB->>CNI: ADD (via CRI networking call)
    CNI->>NS: Create veth pair, assign IP, set routes
    CNI-->>KB: Return interface + IP JSON
    KB->>CR: Start application containers in same netns
    Note over NS: Pod is now reachable
    U->>KB: Delete Pod
    KB->>CNI: DEL
    CNI->>NS: Remove veth, release IP, clean routes
    KB->>CR: Destroy sandbox
    
Fig. 2 — End-to-end lifecycle of a pod’s network identity, from scheduling to teardown

Notice a subtle but important detail: all containers inside one Kubernetes pod share a single network namespace, created once by a special lightweight “pause” or “sandbox” container. CNI’s ADD is only called once per pod, not once per container inside it — this is why every container in a pod can reach each other over localhost and shares the same IP address. Docker, running standalone, has no equivalent “pod” concept by default — each container normally gets its own namespace unless you explicitly ask it to share one with --network container:<name>.

“CNI’s entire lifecycle boils down to two verbs that must be perfectly symmetric: whatever ADD wires up, DEL must be able to fully unwind.”

8Types of CNI Plugins and the Major Vendors

Not all CNI plugins do the same job. They generally fall into a few families, and production clusters often run several together.

Type

Interface Plugins

Create the actual network interface: bridge, macvlan, ipvlan, ptp (point-to-point veth pair), host-device.

Type

IPAM Plugins

Hand out IP addresses: host-local (simple local subnet allocation), dhcp, cloud-native options like AWS or Azure IPAM.

Type

Meta / Chained Plugins

Add extra behavior on top of an existing interface: portmap (NAT port forwarding), bandwidth (traffic shaping), firewall, tuning (sysctl adjustments).

Type

Full Networking Solutions

Complete, opinionated networking stacks that combine interface creation, IPAM, and policy in one product: Calico, Cilium, Flannel, Weave Net, AWS VPC CNI, Azure CNI.

PluginPrimary FocusNotable Trait
FlannelSimple overlay networkingVery easy to set up; minimal feature set, no native network policy
CalicoNetworking + Network PolicyUses BGP for routing; strong, fine-grained security policy engine
CiliumeBPF-based networkingBypasses traditional iptables, offers deep observability (Hubble) and L7-aware policy
Weave NetOverlay networkingAutomatic mesh discovery, encrypted traffic option, also ships a Docker plugin
AWS VPC CNINative cloud IP addressingAssigns real VPC IPs directly to pods, avoiding double-NAT overhead
Everyday Analogy

Choosing among these plugins is like choosing a phone carrier. All of them get a call connected (basic connectivity), but they differ wildly in coverage strategy (overlay vs. native routing), whether they offer a security add-on (network policy), and how much visibility they give you into call quality (observability tooling).

9Using CNI Plugins Where Docker Is Involved: Practical Setups

Given everything above, here is how CNI shows up in real, working infrastructure that includes Docker somewhere in the stack.

Setup A — Kubernetes with containerd (No Docker Daemon at All)

This is the modern default. Nodes run containerd directly (no Docker Engine installed), the kubelet calls containerd through the CRI, and containerd invokes the configured CNI plugin from /opt/cni/bin using the config in /etc/cni/net.d/. “Docker” as a daemon is entirely absent; only the underlying OCI image format and containerd — both technologies Docker helped create — remain in the picture.

Setup B — Legacy Kubernetes with Docker + dockershim

On older clusters (pre-1.24) or systems that reintroduced Docker compatibility via cri-dockerd, Docker Engine still runs containers, but Kubernetes’ CNI networking logic operates independently of Docker’s own bridge network — Kubernetes disables Docker’s default bridge involvement for pod traffic and lets the CNI plugin own the pod’s interface entirely.

Setup C — Plain Docker Engine, CNM Only

A developer running docker compose up or docker run on a single machine is using CNM/libnetwork end to end: bridge, overlay, or macvlan drivers, no CNI binaries involved, no /etc/cni/net.d directory consulted.

ADR-014 — Network Model Choice Decision
Context

A team is deciding whether to run workloads on plain Docker/Swarm or migrate to Kubernetes with a CNI plugin.

Decision

If the workload needs multi-host scheduling, fine-grained network policy, or a large plugin ecosystem, adopt Kubernetes with a CNI plugin like Calico. If the workload is a small, single-host set of services, Docker’s native CNM is sufficient and avoids unnecessary operational complexity.

Consequences

Choosing CNI brings a steeper learning curve and more moving parts (binaries, config files, IPAM state) but unlocks portability across runtimes and a far richer security policy model than CNM offers out of the box.

10Advantages, Disadvantages, and Trade-offs

Advantages of CNI

  • Vendor-neutral standard adopted across the whole cloud-native ecosystem
  • Minimal interface (four commands) keeps plugins simple to build and audit
  • Chaining lets you compose small, focused plugins instead of one giant one
  • Huge existing ecosystem: Calico, Cilium, Flannel, cloud-provider plugins
  • Decouples the runtime from the networking implementation entirely

Trade-offs and Costs

  • Not natively understood by plain Docker Engine — extra layers needed
  • Operational surface grows: binaries, JSON configs, IPAM state to manage
  • Different plugins have very different performance and feature profiles, adding a real evaluation burden
  • Debugging spans multiple processes and namespaces, raising the troubleshooting bar
  • Version skew between plugin and runtime CNI spec support can cause subtle breakage
4
CNI VERBS TOTAL
2017
CONTAINERD DONATED TO CNCF
1.24
K8S VERSION THAT REMOVED DOCKERSHIM

11Security Considerations

Because a CNI plugin runs with elevated privileges — it manipulates network namespaces and host routing tables — its security posture matters as much as any other cluster component. Several concerns deserve attention.

Privilege scope. CNI plugins typically need CAP_NET_ADMIN and similar Linux capabilities to create interfaces and modify routes. A compromised or malicious plugin binary effectively has host-level networking control, so plugin binaries should only ever be sourced from trusted, verified distributions and pinned to specific, checksummed versions.

Network policy enforcement. Plain connectivity plugins like early Flannel provide no isolation between pods by default — any pod can talk to any other pod. Plugins such as Calico and Cilium add a NetworkPolicy engine, letting operators define allow-lists of which pods, namespaces, or IP ranges may communicate, which is the container-world equivalent of firewall rules and is essential for any multi-tenant or regulated environment.

Encryption in transit. Overlay networks send container traffic across regular host networking, which may traverse untrusted segments. Options like WireGuard-based encryption (available in Calico and Cilium) or Weave Net’s built-in encrypted mesh protect data as it crosses between hosts.

!
Common Trap

Teams frequently install a CNI plugin purely for connectivity and assume network segmentation “just works.” Without an explicit NetworkPolicy resource, most plugins default to fully open pod-to-pod traffic — the isolation has to be deliberately configured, not assumed.

?
What an interviewer may ask

“How would you restrict a payment-processing pod so only the checkout service can reach it?” — Strong answer: deploy a CNI plugin that supports NetworkPolicy (e.g. Calico), then write a policy selecting the payment pod’s labels as the target and the checkout service’s labels as the only allowed ingress source, denying all other traffic by default.

12Monitoring, Logging, and Metrics

Because CNI plugins run as short-lived, one-shot processes, traditional “check if the daemon is alive” monitoring does not directly apply — the plugin binary itself no longer exists moments after it runs. Observability instead focuses on three layers.

Layer

Invocation Logs

The container runtime and kubelet log every CNI ADD/DEL call, including failures, timing, and the JSON result — the first place to look when a pod is stuck in “ContainerCreating.”

Layer

Control-Plane Metrics

Full solutions like Calico and Cilium run a persistent agent per node (separate from the CNI binary itself) that exposes Prometheus metrics: interface counts, policy evaluation latency, dropped packet counts.

Layer

Data-Plane Visibility

Tools like Cilium’s Hubble give live, per-flow visibility into which pods are talking to which, at which protocol and port, invaluable for both debugging and security auditing.

A healthy operational habit is to track pod network setup latency as a first-class SLO-adjacent metric — a rising trend in ADD call duration is often the earliest signal of IPAM exhaustion (running out of assignable addresses in a subnet) long before pods start failing outright.

13Design Patterns and Anti-patterns

Good Patterns

  • Chain a minimal main plugin with a dedicated IPAM plugin rather than one monolithic plugin
  • Pin exact plugin binary versions in infrastructure-as-code, never “latest”
  • Default-deny NetworkPolicy, then explicitly allow required paths
  • Separate the pod CIDR range clearly from node and service CIDR ranges to avoid overlap

Anti-patterns

  • Running two full CNI networking solutions on the same cluster simultaneously (route conflicts, duplicate IPAM)
  • Manually editing /etc/cni/net.d configs by hand on live nodes instead of through configuration management
  • Choosing an overlay-heavy plugin for a latency-critical workload without benchmarking native-routing alternatives
  • Ignoring MTU mismatches between overlay tunnels and the underlying physical network, causing silent packet fragmentation

14Best Practices and Common Mistakes

Plan your IP space before you deploy. Pod CIDR, service CIDR, and node CIDR ranges must never overlap with each other or with any existing corporate network the cluster needs to reach — this single planning step prevents the majority of “mysteriously unreachable” incidents reported by teams new to CNI.

Match the plugin to the environment, not the hype. A cloud-native IPAM plugin that assigns real VPC addresses (like AWS VPC CNI) removes a layer of NAT overhead on cloud infrastructure but can exhaust the available IP pool faster on smaller subnets; an overlay plugin like Flannel is simpler to reason about but adds encapsulation overhead. Benchmark under realistic load rather than assuming.

Keep CNI binaries and cluster components in version lockstep. The CNI spec itself has evolved (notably from 0.x to 1.0.0), and mismatched plugin/runtime versions have historically caused ADD calls to silently fail or misinterpret configuration fields.

!
Common Mistake

Assuming a “network policy” written for one plugin automatically works after switching to another. Some plugins implement the standard Kubernetes NetworkPolicy resource plus their own extended CRDs (like Calico’s GlobalNetworkPolicy) — a migration between plugins should always include a full policy audit.

15Real-World and Industry Examples

Large-Scale SaaS Platforms on Cilium

Organizations running very high pod density per node have increasingly adopted Cilium specifically because its eBPF-based data path avoids the iptables rule-count explosion that traditional netfilter-based plugins suffer from at scale, keeping packet processing latency predictable as the cluster grows into the thousands of nodes.

Regulated Industries and Calico Network Policy

Financial services and healthcare platforms commonly standardize on Calico specifically for its mature, fine-grained NetworkPolicy and GlobalNetworkPolicy engine, which lets security teams express compliance-driven segmentation (e.g. “only the audit-log service may reach the database tier”) as version-controlled, reviewable policy objects.

Cloud-Native Startups on Managed Kubernetes

Teams on managed services like Amazon EKS or Azure AKS frequently rely on the cloud provider’s own CNI plugin (AWS VPC CNI, Azure CNI) specifically because it assigns pods real addresses from the cloud’s native IP space, simplifying integration with existing VPC-based security groups, load balancers, and on-prem connectivity that predates the Kubernetes adoption.

16Frequently Asked Questions

Q1Does Docker Engine support CNI out of the box?
No. Docker Engine uses its own Container Network Model (CNM) through libnetwork. CNI shows up only when containerd (the runtime under Docker) or Kubernetes is driving the networking directly, bypassing Docker’s own network layer.
Q2Is CNI the same thing as a Docker network driver plugin?
No, they are separate plugin systems with different interfaces, even though some vendors (like Weave) ship both from one product so they can be used in either world.
Q3Can I run Calico or Cilium with plain Docker Engine?
Not directly through CNI in a standalone Docker Engine setup — those tools are built for CNI-aware runtimes. They are typically used with Kubernetes, where containerd or CRI-O invokes them as CNI plugins.
Q4What replaced dockershim in modern Kubernetes?
Kubernetes now talks directly to CNI-native runtimes such as containerd or CRI-O through the Container Runtime Interface (CRI), removing the need for the Docker-compatibility shim entirely.
Q5Why do CNI plugins need to be chained instead of doing everything in one binary?
Chaining follows the Unix philosophy of small, composable tools — a main plugin, an IPAM plugin, and optional meta plugins can each be developed, tested, and swapped independently rather than duplicating logic across every plugin.
Q6Does using CNI mean losing Docker’s simplicity?
For a single-host developer workflow, plain Docker’s CNM remains simpler and is usually the right choice. CNI earns its extra complexity specifically at multi-host, orchestrated scale, where its policy engine, plugin ecosystem, and portability across runtimes pay off.

17Summary and Key Takeaways

Key Takeaways

  • CNI is a specification, not a product — a small, four-verb contract (ADD, DEL, CHECK, VERSION) that lets any container runtime work with any compatible networking plugin.
  • Docker Engine itself uses CNM/libnetwork, its own separate networking model, not CNI, for standard docker run and docker network workflows.
  • containerd — the engine underneath Docker — is CNI-native, which is why CNI appears in the Docker “family” even though the Docker daemon layer does not speak it directly.
  • Kubernetes is the primary consumer of CNI in practice, invoking plugins through containerd or CRI-O via the Container Runtime Interface.
  • Plugins are commonly chained: a main plugin for interface creation, an IPAM plugin for address allocation, and meta plugins for extras like port mapping.
  • Security is not automatic — network segmentation between pods requires explicit NetworkPolicy configuration on a plugin that supports it, such as Calico or Cilium.
  • Choose deliberatelyoverlay simplicity (Flannel), policy depth (Calico), eBPF performance and observability (Cilium), or native cloud IP integration (AWS/Azure CNI) — the right choice depends on scale, security requirements, and infrastructure.