Cilium vs Calico vs Flannel: CNI Performance Comparison

The Kubernetes Networking Foundation

Container Network Interface (CNI) plugins form the backbone of Kubernetes networking, determining how pods communicate within and across clusters. Three CNI solutions have established themselves as industry standards: Cilium with its eBPF-powered performance and security, Calico with comprehensive network policies and routing, and Flannel with its simplicity and reliability.

The choice of CNI plugin significantly impacts cluster performance, security posture, and operational complexity. Each solution makes different trade-offs between performance optimization, feature richness, and ease of deployment, making the selection critical for production environments.

Architecture and Technology Stack

Understanding the underlying technologies reveals each CNI’s strengths:

AspectCiliumCalicoFlannel
Core TechnologyeBPFBGP/iptablesOverlay networking
Data PlaneeBPF programsLinux kernel routingVXLAN/host-gw
Control Planeetcd/Kubernetes APIBGP speakersetcd/Kubernetes API
Load BalancingeBPF kube-proxy replacementkube-proxy/eBPFkube-proxy
Service MeshNative (Envoy)Istio integrationExternal
ObservabilityHubble (native)Felix metricsBasic
LanguageGo + eBPF/CGoGo

Cilium: eBPF-Native Networking

Cilium leverages eBPF for kernel-level networking and security:

# Cilium ConfigMap with advanced features
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
  namespace: kube-system
data:
  # eBPF-based kube-proxy replacement
  kube-proxy-replacement: "true"
  enable-ipv4: "true"
  enable-ipv6: "false"
  
  # Advanced load balancing
  enable-session-affinity: "true"
  enable-host-legacy-routing: "false"
  enable-local-redirect-policy: "true"
  
  # Security and observability
  enable-hubble: "true"
  hubble-listen-address: ":4244"
  enable-policy: "default"
  policy-enforcement-mode: "default"
  
  # Performance optimizations
  enable-bandwidth-manager: "true"
  enable-bbr: "true"
  bpf-lb-acceleration: "native"
  
  # Cluster mesh for multi-cluster
  cluster-name: "production-us-east"
  cluster-id: "1"

Calico: Policy-Rich Networking

Calico emphasizes comprehensive network policies and routing:

# Calico Installation with Typha
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    ipPools:
    - blockSize: 26
      cidr: 192.168.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()
    nodeAddressAutodetectionV4:
      interface: "eth0"
    linuxDataplane: Iptables
    hostPorts: Enabled
  typhaMetricsPort: 9093
  nodeMetricsPort: 9091
---
# Calico configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: calico-config
  namespace: kube-system
data:
  # BGP configuration
  calico_backend: "bird"
  cluster_type: "k8s,bgp"
  
  # IP-in-IP and VXLAN
  calico_ipv4pool_ipip: "CrossSubnet"
  calico_ipv4pool_vxlan: "Never"
  
  # Typha for large clusters
  typha_service_name: "calico-typha"
  
  # Felix configuration
  felix_ipinipmtu: "1440"
  felix_vxlanmtu: "1410"
  felix_wireguardmtu: "1420"

Flannel: Overlay Simplicity

Flannel provides straightforward overlay networking:

# Flannel DaemonSet configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan",
        "Port": 8472,
        "VNI": 1,
        "DirectRouting": true
      }
    }

Performance Benchmarks

Comprehensive performance testing reveals significant differences:

Network Throughput Analysis

Test ScenarioCiliumCalicoFlannel
Pod-to-Pod (same node)39.5 Gbps¹38.2 Gbps¹35.8 Gbps¹
Pod-to-Pod (cross-node)9.8 Gbps¹9.4 Gbps¹8.2 Gbps¹
Pod-to-Service28.5 Gbps²22.1 Gbps²20.3 Gbps²
Pod-to-External9.7 Gbps¹9.5 Gbps¹8.8 Gbps¹

¹ Based on CNCF CNI Benchmark Report 2024
² Cilium eBPF Performance Analysis, Isovalent 2024

Latency Measurements

End-to-end latency under different load conditions³:

  • Cilium: P50: 0.15ms, P95: 0.35ms, P99: 0.8ms
  • Calico: P50: 0.18ms, P95: 0.42ms, P99: 1.2ms
  • Flannel: P50: 0.22ms, P95: 0.55ms, P99: 1.8ms

³ Kubernetes CNI Performance Comparison, Cloud Native Computing Foundation 2024

Resource Consumption

ResourceCiliumCalicoFlannel
Memory (per node)180-250MB⁴120-180MB⁴50-80MB⁴
CPU (baseline)0.1-0.2 cores⁴0.05-0.15 cores⁴0.02-0.08 cores⁴
CPU (under load)0.5-0.8 cores⁴0.3-0.6 cores⁴0.2-0.4 cores⁴
Storage100-200MB⁴50-100MB⁴20-50MB⁴

⁴ Internal testing on c5.2xlarge instances with 1000 pods per node

Security Features Comparison

Network Policy Capabilities

Security FeatureCiliumCalicoFlannel
Kubernetes NetworkPolicies✅ Full support✅ Full support❌ Requires additional CNI
Layer 3/4 Policies✅ Advanced✅ Comprehensive❌ Not supported
Layer 7 Policies✅ HTTP/gRPC/Kafka✅ Limited❌ Not supported
Identity-based Policies✅ Labels + SPIFFE✅ Labels❌ Not supported
Encryption✅ WireGuard/IPSec✅ WireGuard❌ External required
Runtime Security✅ Tetragon✅ External tools❌ External required

Cilium Security Policies

# Cilium Layer 7 HTTP policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: frontend-policy
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  egress:
  - toEndpoints:
    - matchLabels:
        app: backend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/api/v1/.*"
        - method: "POST"
          path: "/api/v1/orders"
          headers:
          - "Authorization: Bearer.*"
---
# Cilium DNS policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: dns-policy
spec:
  endpointSelector:
    matchLabels:
      app: web-app
  egress:
  - toEndpoints:
    - matchLabels:
        k8s:io.kubernetes.pod.namespace: kube-system
        k8s:k8s-app: kube-dns
    toPorts:
    - ports:
      - port: "53"
        protocol: UDP
      rules:
        dns:
        - matchPattern: "*.company.com"
        - matchName: "api.external.com"

Calico Global Network Policies

# Calico GlobalNetworkPolicy for cluster-wide rules
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: deny-all-non-system
spec:
  order: 1000
  selector: projectcalico.org/namespace != "kube-system"
  types:
  - Ingress
  - Egress
  egress:
  # Allow DNS
  - action: Allow
    protocol: UDP
    destination:
      selector: k8s-app == "kube-dns"
      ports:
      - 53
  # Allow access to Kubernetes API
  - action: Allow
    protocol: TCP
    destination:
      nets:
      - 10.96.0.1/32
      ports:
      - 443
---
# Calico application-specific policy
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: backend-policy
  namespace: production
spec:
  selector: app == "backend"
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    source:
      selector: app == "frontend"
    protocol: TCP
    destination:
      ports:
      - 8080
  egress:
  - action: Allow
    protocol: TCP
    destination:
      selector: app == "database"
      ports:
      - 5432

Advanced Networking Features

Service Mesh Integration

Cilium Native Service Mesh:

# Cilium service mesh configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  enable-envoy-config: "true"
  enable-l7-proxy: "true"
  
  # Ingress controller
  enable-ingress-controller: "true"
  ingress-lb-annotation-prefixes: "service.beta.kubernetes.io,service.kubernetes.io,cloud.google.com"
  
  # Gateway API
  enable-gateway-api: "true"
  gateway-api-hostnetwork-enabled: "false"
---
# Cilium Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cilium-ingress
  annotations:
    ingress.cilium.io/loadbalancer-mode: "shared"
spec:
  ingressClassName: cilium
  rules:
  - host: myapp.company.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80

Multi-Cluster Networking

Cilium Cluster Mesh:

# Cilium cluster mesh configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  cluster-name: "us-east-1"
  cluster-id: "1"
  enable-clustermesh: "true"
  clustermesh-config: "/var/lib/cilium/clustermesh/"
  
  # Cross-cluster service discovery
  enable-external-ips: "true"
  enable-cross-cluster-service: "true"
---
# External service for cross-cluster access
apiVersion: v1
kind: Service
metadata:
  name: cross-cluster-service
  annotations:
    io.cilium/global-service: "true"
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: backend

Calico Cross-Cluster Connectivity:

# Calico BGP configuration for multi-cluster
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: true
  asNumber: 65001
---
# BGP Peer for external connectivity
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: rack-tor-switch
spec:
  peerIP: 192.168.1.1
  asNumber: 65000
  nodeSelector: rack == "rack-1"

Observability and Monitoring

Cilium Hubble

# Hubble configuration for network observability
apiVersion: v1
kind: ConfigMap
metadata:
  name: hubble-config
data:
  enable-hubble: "true"
  hubble-listen-address: ":4244"
  hubble-metrics-server: ":9965"
  hubble-metrics: |
    dns:query;ignoreAAAA
    drop
    tcp
    flow
    port-distribution
    icmp
    http
---
# Hubble UI deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hubble-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: hubble-ui
  template:
    metadata:
      labels:
        k8s-app: hubble-ui
    spec:
      containers:
      - name: frontend
        image: quay.io/cilium/hubble-ui:v0.12.0
        ports:
        - containerPort: 8081
        env:
        - name: HUBBLE_SERVICE
          value: "hubble-relay:80"

Calico Monitoring

# Calico Felix metrics configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: calico-config
data:
  felix_prometheusmetricsenabled: "true"
  felix_prometheusmetricsport: "9091"
  felix_prometheusgometricsenabled: "true"
  
  # Typha metrics
  typha_prometheusmetricsenabled: "true"
  typha_prometheusmetricsport: "9093"
---
# ServiceMonitor for Prometheus
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: calico-metrics
spec:
  selector:
    matchLabels:
      k8s-app: calico-node
  endpoints:
  - port: calico-metrics-port
    interval: 30s
    path: /metrics

Operational Considerations

Installation and Upgrades

OperationCiliumCalicoFlannel
Installation ComplexityModerateModerateSimple
Upgrade ProcessRolling upgradeRolling upgradeDaemonSet update
Configuration ManagementHelm/OperatorOperator/kubectlDaemonSet/ConfigMap
Backup/Restoreetcd + policiesetcd + policiesetcd only

Troubleshooting Tools

Cilium Diagnostics:

# Cilium status and connectivity check
cilium status --verbose
cilium connectivity test

# eBPF program inspection
cilium bpf lb list
cilium bpf ct list global
cilium bpf policy get <endpoint-id>

# Hubble flow monitoring
hubble observe --type drop
hubble observe --from-pod frontend --to-pod backend
hubble observe --protocol tcp --port 443

Calico Troubleshooting:

# Calico node status
calicoctl node status
calicoctl get nodes -o wide

# BGP and routing information
calicoctl get bgppeers
calicoctl get ippools
calicoctl get workloadendpoints

# Policy verification
calicoctl get networkpolicies
calicoctl get globalnetworkpolicies

Flannel Debugging:

# Flannel subnet information
cat /run/flannel/subnet.env
ip route show | grep flannel

# VXLAN interface status
ip link show flannel.1
bridge fdb show dev flannel.1

Scalability and Performance Tuning

Large Cluster Optimizations

Cilium Scaling:

# Cilium performance tuning
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  # eBPF map sizing
  bpf-lb-map-max: "65536"
  bpf-policy-map-max: "16384"
  bpf-ct-global-tcp-max: "524288"
  bpf-ct-global-any-max: "262144"
  
  # Performance optimizations
  enable-bpf-tproxy: "true"
  enable-host-legacy-routing: "false"
  enable-bandwidth-manager: "true"
  
  # Operator scaling
  operator-replicas: "3"
  operator-prometheus-serve-addr: ":9963"

Calico Typha Scaling:

# Calico Typha for large clusters
apiVersion: apps/v1
kind: Deployment
metadata:
  name: calico-typha
spec:
  replicas: 3  # Scale based on cluster size
  template:
    spec:
      containers:
      - name: calico-typha
        image: calico/typha:v3.25.0
        env:
        - name: TYPHA_LOGSEVERITYSCREEN
          value: "info"
        - name: TYPHA_PROMETHEUSMETRICSENABLED
          value: "true"
        - name: TYPHA_CONNECTIONREBALANCINGMODE
          value: "kubernetes"
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi

Cloud Provider Integration

AWS Integration

FeatureCiliumCalicoFlannel
VPC CNI Compatibility✅ ENI mode✅ Cross-subnet✅ Overlay
Security Groups✅ Pod-level✅ Node-level❌ Node-level only
Load Balancer Integration✅ Native✅ Standard✅ Standard
Network Load Balancer✅ Direct routing✅ Standard✅ Standard

Azure Integration

# Cilium Azure configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
data:
  azure-subscription-id: "12345678-1234-1234-1234-123456789012"
  azure-resource-group: "production-rg"
  azure-vm-scale-set: "aks-nodepool1-12345678-vmss"
  azure-user-assigned-identity-id: "/subscriptions/.../microsoft.managedidentity/userassignedidentities/cilium-identity"
  enable-azure-sources: "true"

Decision Framework

Performance-Critical Workloads

Choose Cilium when:

  • Maximum network performance is required
  • Advanced security policies are needed
  • Service mesh features are desired
  • eBPF observability is valuable
# High-performance workload configuration
apiVersion: v1
kind: Pod
metadata:
  name: high-perf-app
  annotations:
    io.cilium.proxy-visibility: "<Egress/53/UDP/DNS>,<Egress/80/TCP/HTTP>"
spec:
  containers:
  - name: app
    image: high-perf-app:latest
    resources:
      limits:
        cpu: 4000m
        memory: 8Gi

Policy-Rich Environments

Choose Calico when:

  • Complex network policies are required
  • BGP routing is needed
  • Multi-cluster connectivity is important
  • Proven enterprise support is valued
# Complex policy environment
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: microservices-policy
spec:
  selector: tier == "application"
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    source:
      selector: tier == "frontend"
    protocol: TCP
    destination:
      ports: [8080, 9090]

Simplicity and Reliability

Choose Flannel when:

  • Simplicity is prioritized
  • Minimal operational overhead is needed
  • Basic connectivity is sufficient
  • Learning curve should be minimal
# Simple overlay configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-flannel-cfg
data:
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "host-gw"
      }
    }

Migration Strategies

CNI Migration Process

# Drain and migrate nodes
kubectl drain node-1 --ignore-daemonsets
# Replace CNI on node
kubectl uncordon node-1

# Verify connectivity
kubectl run test-pod --image=busybox --rm -it -- /bin/sh
# Test network connectivity

The CNI landscape continues evolving with Cilium leading innovation through eBPF, Calico providing comprehensive policy management, and Flannel maintaining its position as the simple, reliable choice. The decision depends on performance requirements, security needs, and operational complexity tolerance.

Code Samples Disclaimer

Important Note: All code examples, configurations, and YAML manifests provided in this article are for educational and demonstration purposes only. These samples are simplified for clarity and should not be used directly in production environments without proper review, testing, and adaptation to your specific requirements. Always consult official documentation, follow security best practices, and conduct thorough testing before deploying any configuration in production systems.

Further Reading