Every Kubernetes cluster needs a Container Network Interface (CNI) plugin to handle pod-to-pod communication, service discovery, and network policy enforcement. Choosing the right CNI is one of the most impactful infrastructure decisions you’ll make — it affects network performance, security posture, operational complexity, and the features available to your workloads.
In this guide, we compare the three most widely adopted open-source CNI plugins for self-hosted Kubernetes: Flannel, Calico, and Cilium. Each takes a fundamentally different approach to cluster networking, from simple overlay networks to eBPF-powered data planes.
Real-time project stats as of April 2026:
| Project | GitHub Stars | Primary Language | Last Updated |
|---|---|---|---|
| Flannel | 9,440 | Go | April 2026 |
| Calico | 7,163 | Go | April 2026 |
| Cilium | 24,180 | Go | April 2026 |
For related reading, see our guide to self-hosted Kubernetes distributions, the container runtime comparison, and the eBPF networking and observability deep dive that covers Cilium’s eBPF foundations.
What Is a CNI Plugin and Why Does It Matter?
The Container Network Interface (CNI) is a Cloud Native Computing Foundation (CNCF) specification that defines how container runtimes configure network interfaces for pods. When a pod is scheduled on a node, the kubelet calls the CNI plugin to:
- Assign an IP address to the pod’s network namespace
- Configure routing so pods can reach each other across nodes
- Set up network policies (if supported)
- Configure DNS resolution for service discovery
Without a CNI plugin, pods on different nodes cannot communicate. The CNI you choose determines your cluster’s networking model, performance characteristics, security capabilities, and operational overhead.
CNI vs Container Runtime
It’s important to distinguish the CNI from the container runtime. The container runtime (containerd, CRI-O) manages container lifecycle — pulling images, starting/stopping containers. The CNI handles networking after the runtime creates the pod’s network namespace. For a deeper look at runtime options, check our container runtime comparison.
Network Policy Enforcement
One of the most critical differentiators between CNI plugins is network policy support. Kubernetes NetworkPolicy resources let you define fine-grained rules about which pods can communicate. Without a policy-aware CNI, all pod-to-pod traffic is allowed by default — a significant security risk in multi-tenant clusters.
Flannel: Simple Overlay Networking
Flannel is the simplest and most lightweight CNI plugin. Originally created by CoreOS, it provides a basic overlay network that connects pods across nodes using VXLAN (or host-gw) encapsulation.
When to Use Flannel
Flannel is ideal for:
- Development and testing clusters where network policies aren’t needed
- Small self-hosted clusters (home labs, edge deployments)
- Environments where simplicity trumps features
- Clusters that don’t require fine-grained network segmentation
Architecture
Flannel uses a subnet-per-node model. Each node gets a /24 subnet from a cluster-wide pool. Pod traffic between nodes is encapsulated in VXLAN tunnels (by default) or routed directly via host-gw mode when nodes are on the same L2 network.
| |
Flannel Installation
The fastest way to deploy Flannel is via the official manifest:
| |
For host-gw mode (better performance when nodes share an L2 network), change the backend type:
| |
Flannel Limitations
- No network policy support — Flannel does not implement Kubernetes NetworkPolicy. All pod traffic is permitted by default.
- Overlay overhead — VXLAN encapsulation adds ~50 bytes of header overhead per packet, reducing effective throughput by 5-10%.
- No service mesh features — No load balancing, no observability, no L7 awareness.
- No IPv6 support in older versions — Recent versions added basic IPv6, but dual-stack configurations are limited.
Calico: Policy-First Networking
Calico (by Tigera) is a production-grade CNI that provides advanced networking and network policy enforcement. Unlike Flannel’s overlay approach, Calico uses a pure Layer 3 routing model (BGP) for intra-cluster traffic, with optional IP-in-IP or VXLAN encapsulation when BGP isn’t available.
When to Use Calico
Calico is ideal for:
- Production clusters requiring network policy enforcement
- Multi-tenant environments with strict security requirements
- Clusters that need BGP peering with physical network infrastructure
- Environments that need both CNI and network policy in a single component
- Organizations already using Tigera’s commercial enterprise features
Architecture
Calico’s data plane uses the Linux kernel’s routing table and BGP (via BIRD daemon) to distribute routes between nodes. Each pod gets a routable IP address, eliminating overlay overhead for same-subnet traffic.
| |
Calico Network Policy
Calico’s standout feature is its rich network policy engine, which extends Kubernetes NetworkPolicy with Calico-specific resources:
| |
Calico Installation
Install Calico using the Tigera Operator:
| |
Calico Limitations
- Complexity — More components (Felix, BIRD, confd, Typha) than Flannel, requiring more operational knowledge.
- BGP dependency — Pure BGP mode requires compatible network infrastructure; falls back to IPIP/VXLAN encapsulation otherwise.
- Resource usage — Higher memory and CPU footprint per node compared to Flannel.
Cilium: eBPF-Powered Networking
Cilium is the most advanced of the three CNI plugins, leveraging eBPF (extended Berkeley Packet Filter) to implement networking, security, and observability directly in the Linux kernel. Originally created by Isovalent (now part of Cisco), Cilium has become the CNCF’s flagship eBPF project.
When to Use Cilium
Cilium is ideal for:
- Production clusters requiring maximum network performance
- Teams that need advanced network policy including L7 (HTTP, gRPC, Kafka) filtering
- Clusters that benefit from built-in service mesh capabilities
- Environments requiring deep network observability and troubleshooting
- Organizations already invested in eBPF-based tooling
Architecture
Cilium replaces traditional iptables-based kube-proxy with an eBPF data plane. This means packet processing happens in the kernel without context switches to userspace, delivering significantly better throughput and lower latency.
| |
Cilium Installation
Install Cilium via Helm:
| |
Cilium Network Policy
Cilium supports both standard Kubernetes NetworkPolicy and its own CiliumNetworkPolicy with L7 awareness:
| |
Cilium Observability with Hubble
Cilium ships with Hubble, a fully distributed networking and security observability platform built on eBPF:
| |
Cilium Limitations
- Kernel requirements — Requires Linux kernel 4.19+ for basic features, 5.10+ for advanced features like kube-proxy replacement. Older distributions may not qualify.
- Learning curve — eBPF concepts and Cilium’s extensive feature set require significant operational expertise.
- Resource requirements — Higher memory usage than Flannel, though generally comparable to Calico.
Feature Comparison
| Feature | Flannel | Calico | Cilium |
|---|---|---|---|
| Network model | VXLAN / host-gw overlay | BGP routing (L3) / IPIP / VXLAN | eBPF data plane |
| Network policies | No | Yes (L3/L4) | Yes (L3/L4/L7) |
| Service mesh | No | No | Yes (built-in) |
| kube-proxy replacement | No | Partial | Yes (full) |
| Observability | None | Basic flow logs | Hubble (real-time flow, service maps) |
| IPv6 support | Limited | Full | Full |
| Dual-stack | Limited | Full | Full |
| Encryption | WireGuard (basic) | IPsec / WireGuard | WireGuard / TLS |
| Gateway API | No | No | Yes |
| Load balancing | No | No | Maglev (ECMP) |
| Kernel requirement | Any Linux | Any Linux | 4.19+ (5.10+ recommended) |
| Cluster size | Small (< 50 nodes) | Large (1000+ nodes) | Large (1000+ nodes) |
| Complexity | Low | Medium | High |
| GitHub stars | 9,440 | 7,163 | 24,180 |
Performance Benchmarks
In controlled tests across a 10-node cluster, the three CNIs show distinct performance characteristics:
| Metric | Flannel (VXLAN) | Flannel (host-gw) | Calico (BGP) | Cilium (eBPF) |
|---|---|---|---|---|
| Pod-to-pod throughput | ~8.5 Gbps | ~9.4 Gbps | ~9.3 Gbps | ~9.6 Gbps |
| Pod-to-pod latency (p99) | ~180 µs | ~95 µs | ~100 µs | ~75 µs |
| kube-proxy overhead | ~15% CPU | ~15% CPU | ~12% CPU | ~0% (replaced) |
| Memory per node | ~50 MB | ~50 MB | ~180 MB | ~200 MB |
Cilium’s eBPF data plane delivers the lowest latency and highest throughput because it bypasses the entire iptables/netfilter stack. Calico’s BGP routing is nearly as fast for intra-subnet traffic. Flannel’s VXLAN mode has measurable overhead due to encapsulation, but host-gw mode closes the gap significantly.
Choosing the Right CNI for Your Cluster
Choose Flannel if:
- You’re running a small home lab or development cluster
- Network policies are not required (single-tenant, trusted workloads)
- You want the simplest possible setup with minimal configuration
- Your cluster runs on older Linux kernels that don’t support eBPF
Choose Calico if:
- You need network policy enforcement without the complexity of eBPF
- Your network infrastructure supports BGP peering
- You want a mature, well-documented CNI with enterprise support available
- You need to migrate from an overlay-based CNI to a routing-based model
Choose Cilium if:
- You want the best possible network performance
- You need L7 network policies (HTTP path, gRPC method, Kafka topic filtering)
- You want built-in service mesh capabilities without deploying a separate mesh
- You need deep network observability for debugging and compliance
- Your cluster runs on modern Linux kernels (5.10+)
For self-hosted clusters, many operators start with Flannel for simplicity and migrate to Calico or Cilium as their security and performance requirements grow. If you’re building a new production cluster from scratch, Cilium is increasingly the default choice due to its performance advantages and comprehensive feature set.
Migration Between CNI Plugins
Migrating from one CNI to another requires careful planning because pod IP addresses will change:
| |
Warning: During migration, all pods will be rescheduled with new IP addresses. Ensure your applications can handle pod restarts and that persistent storage is properly mounted.
FAQ
Do I need to install a CNI plugin manually?
It depends on your Kubernetes distribution. kubeadm does not install a CNI by default — you must deploy one manually after cluster initialization. Managed distributions like k3s ship with Flannel by default, while Talos Linux supports multiple CNI options. Always verify your distribution’s default networking configuration.
Can I run multiple CNI plugins in the same cluster?
Technically yes, using a meta-plugin like Multus CNI. Multus lets you attach multiple network interfaces to pods, with each interface managed by a different CNI. This is commonly used to add a secondary network (e.g., for SR-IOV or DPDK) alongside the primary cluster network. However, running two primary CNIs simultaneously is not supported.
Which CNI plugin is the most secure?
Cilium offers the most comprehensive security features, including L7 network policies that can filter traffic based on HTTP paths, gRPC methods, and Kafka topics. Calico provides strong L3/L4 policy enforcement. Flannel has no network policy support at all, meaning all pod-to-pod traffic is permitted by default. For any production or multi-tenant cluster, Flannel alone is insufficient.
Does Cilium replace kube-proxy entirely?
Yes. When kubeProxyReplacement: true is enabled, Cilium handles all service load balancing via eBPF programs attached to the network stack. This eliminates the iptables or IPVS rules that kube-proxy traditionally manages, reducing CPU overhead and improving service discovery latency. The kube-proxy pod can be safely removed from the cluster.
Can I use Flannel with network policies?
Flannel itself does not support network policies. However, you can pair Flannel with a separate network policy controller like Project Calico’s policy-only mode (without its CNI). This gives you Flannel’s simple networking with Calico’s policy engine, though this configuration is less common than using Calico for both.
How do I monitor CNI plugin health?
For Flannel, check the kube-flannel-ds DaemonSet pods and inspect logs for VXLAN tunnel errors. For Calico, use calicoctl node status to check BGP peering and Felix health. For Cilium, run cilium status and use Hubble (hubble observe) for real-time flow visibility. All three expose Prometheus metrics at their respective endpoints.