Skip to content

Calico Explanation

What this page covers

How Calico works internally: the per-node agents (Felix, BIRD, confd), the control-plane helpers (Typha, kube-controllers, the Tigera Operator), the five data planes, the tiered policy model, the Goldmane/Whisker flow-log pipeline, Calico Ingress Gateway, and the security model. Commands live in How-to Guides; look-up tables (ports, versions, Felix keys, sizing) live in Reference. Facts checked against Calico Open Source 3.32 docs and release notes (latest patch v3.32.2, 2026-08-29).

Overview

Project Calico is a CNI plugin and policy engine that gives Kubernetes pods Layer 3 networking and network policy, and extends the same policy model to VMs, bare-metal hosts and OpenStack. Routing between nodes is either native (BGP, no encapsulation) or overlaid (VXLAN or IP-in-IP). Policy and routes are programmed by one of five data planes: standard Linux (iptables), nftables, eBPF, Windows HNS, or the userspace VPP data plane. On Kubernetes, the Tigera Operator installs everything into the calico-system namespace (manifest installs use kube-system).

Calico is the open-source base of Tigera's product line. Calico Open Source (Apache 2.0) is the upstream. Calico Enterprise (self-managed) and Calico Cloud (SaaS) add a management UI, multi-cluster federation, DNS policy, egress gateways, WAF and compliance features. See Reference: Editions.


How It Works

Felix agent, BIRD BGP, Typha fan-out proxy, and pluggable data plane internals.

The diagram below shows the components of an operator-based Calico Open Source 3.32 install and how state flows from the Kubernetes API to the kernel.

graph TB
    subgraph CP["Control plane (calico-system / tigera-operator)"]
        OP["Tigera Operator<br/>(reconciles Installation, APIServer,<br/>Goldmane, Whisker, GatewayAPI CRs)"]
        API["Kubernetes API server<br/>(crd.projectcalico.org or native v3 CRDs)"]
        CAPI["calico-apiserver<br/>(aggregated API, deprecated in 3.32)"]
        KC["calico-kube-controllers<br/>(policy, namespace, SA, WEP, node,<br/>IPAM GC, LoadBalancer IPAM)"]
        TYPHA["Typha<br/>(cache + fan-out, TCP 5473)"]
        GM["Goldmane<br/>(flow aggregator, gRPC 7443)"]
        WH["Whisker<br/>(web UI, 8081)"]
    end

    subgraph N1["Node: calico-node DaemonSet"]
        FELIX["Felix<br/>(policy, routes, flow logs)"]
        CONFD["confd<br/>(renders BIRD config)"]
        BIRD["BIRD<br/>(BGP, TCP 179)"]
        CNI["Calico CNI + calico-ipam<br/>(invoked by kubelet)"]
        DP["Data plane<br/>(iptables / nftables / eBPF)"]
    end

    OP -->|"deploys + upgrades"| TYPHA
    OP -->|"deploys"| GM
    OP -->|"deploys"| WH
    CAPI -->|"serves projectcalico.org/v3"| API
    KC -->|"syncs labels, GC IPs"| API
    API -->|"single watch"| TYPHA
    TYPHA -->|"deduplicated updates"| FELIX
    TYPHA -->|"BGP config"| CONFD
    CONFD -->|"bird.cfg"| BIRD
    FELIX -->|"programs rules + routes"| DP
    FELIX -->|"flow updates"| GM
    GM -->|"flow stream"| WH
    CNI -->|"allocate from IPAM blocks"| API
    BIRD <-->|"iBGP / eBGP"| PEER["Other nodes, route reflectors, ToR"]

Felix

Felix is the primary per-node agent. It runs inside the calico-node container on every node and is responsible for:

  • Endpoint management: programs routes and interface configuration for local workloads (veth pairs for pods, host endpoints for host interfaces).
  • Policy enforcement: translates Calico and Kubernetes policy into iptables or nftables rules (standard data planes), or into eBPF programs and maps (eBPF data plane).
  • Route programming: writes per-endpoint routes into the Linux kernel FIB so the kernel forwards traffic to the correct workload.
  • Status reporting and flow logs: reports health and endpoint status, and (since 3.30) streams flow data to Goldmane.

Felix watches the datastore (through Typha on Kubernetes) for endpoints, policies and IP pools, and reacts in real time. It re-checks its own state periodically (for example routeRefreshInterval, default 90 s) so that another process cannot silently break Calico's rules.

BIRD

BIRD is an open-source internet routing daemon that runs inside calico-node. Its responsibilities:

  • Route distribution: reads the routes Felix programs into the kernel FIB and advertises them to BGP peers.
  • BGP peering: maintains BGP sessions with other Calico nodes (full mesh by default), route reflectors, or top-of-rack (ToR) routers.
  • Topology flexibility: supports full-mesh, route-reflector and ToR peering; since 3.31 each BGPPeer can override the local AS number (localASNumber), and 3.32 extended BGPFilter with community, AS-path and priority matching and actions.

BIRD is not used in VXLAN-only mode

When Calico runs with VXLAN encapsulation and BGP disabled (bgp: Disabled in the operator Installation), BIRD does not run. Felix programs VXLAN routes directly from IPAM block data. IP-in-IP still needs BGP to distribute routes.

confd

confd is a small template renderer inside calico-node. It watches the datastore for BGP-related configuration (IP pools, node-to-node mesh setting, AS numbers, BGPPeer, BGPFilter) and regenerates BIRD's configuration when it changes, then triggers a BIRD reload.

Typha

Typha sits between the datastore (usually the Kubernetes API server) and the per-node Felix and confd processes. Its purpose is scale:

  • Connection multiplexing: one datastore watch per Typha replica instead of one per node, which cuts API-server load from O(nodes) to O(Typha replicas).
  • Event deduplication and filtering: Typha caches the full datastore state and drops updates that Felix does not need, which also reduces Felix CPU.
  • Deployment: a Deployment that the operator always installs and autoscales. Manifest installs add it for clusters over 50 nodes.

When to use Typha

Calico recommends Typha for every cluster that uses the Kubernetes API datastore. With an etcd v3 datastore Typha is redundant and not recommended, because etcd already handles many clients. Sizing guidance is in Reference: Sizing and scalability.

Without Typha every Felix agent watches the API server directly; with Typha a few replicas absorb the watch load.

flowchart TB
    subgraph Without["Without Typha"]
        API1["kube-apiserver"] --> F1["Felix node 1"]
        API1 --> F2["Felix node 2"]
        API1 --> FN["Felix node N"]
    end

    subgraph With["With Typha (operator default)"]
        API2["kube-apiserver"] --> T1["Typha replica 1"]
        API2 --> T2["Typha replica 2"]
        T1 --> FA["Felix A"]
        T1 --> FB["Felix B"]
        T2 --> FC["Felix C"]
        T2 --> FD["Felix D"]
    end

kube-controllers

calico-kube-controllers is a Deployment (one replica by default) that watches the Kubernetes API and keeps Calico's view consistent:

  • Policy, namespace and ServiceAccount controllers: sync Kubernetes policy, namespace labels and ServiceAccount labels so Calico selectors can match on them.
  • Workload endpoint controller: keeps pod labels on Calico workload endpoints up to date.
  • Node controller: cleans up Calico node data and leaked IPAM allocations when nodes are deleted, and can create automatic host endpoints (with HostEndpointTemplate since 3.30).
  • LoadBalancer IPAM controller (since 3.30): allocates LoadBalancer Service IPs from Calico IP pools.

Calico API server and native v3 CRDs

Calico's user-facing API group is projectcalico.org/v3. Historically it was served by calico-apiserver, a Kubernetes aggregated API server that validates requests and stores objects in the backing crd.projectcalico.org/v1 CRDs. That is what let kubectl apply work on Calico resources without calicoctl.

Calico 3.32 added native v3 CRDs (tech preview): the operator registers projectcalico.org/v3 resources directly as CRDs, and a validating webhook plus MutatingAdmissionPolicy resources take over the defaulting and tier-RBAC checks the API server used to do. A DatastoreMigration controller copies data from the aggregated API to the native CRDs in place. The aggregated API server is deprecated in 3.32. The unreleased next release notes say new installs will default to native v3 CRD mode (requires Kubernetes 1.32 or later).

Why the change

The aggregated API server needed host-networked pods and a strict ordering between CRDs and the API server, which caused install friction on managed platforms such as EKS and AKS. Native CRDs remove that dependency (3.32 release notes).

CNI plugin and IPAM

  • CNI plugin: the kubelet invokes it when a pod is created. It creates the veth pair, moves one end into the pod network namespace, and calls the IPAM plugin. Since 3.32.2 the default CNI config declares cniVersion 1.0.0.
  • Calico IPAM: allocates addresses from IPPool resources in blocks (default /26, 64 addresses) that are affine to a node, which keeps route tables small. When a pool is full, nodes can borrow addresses from other blocks, and since 3.32 IPAM reclaims empty blocks from other nodes before giving up. 3.32 also added persistent IPs for KubeVirt VMs.

Tigera Operator

The Tigera Operator (quay.io/tigera/operator) owns the lifecycle of an operator-based install. It reconciles a small set of operator.tigera.io/v1 custom resources (Installation, APIServer, Goldmane, Whisker, GatewayAPI and others) into Deployments, DaemonSets, RBAC and certificates, and reports health through TigeraStatus. Its version numbering is separate from Calico's (Calico v3.32.2 ships operator v1.42.6). Development moved into the projectcalico/calico monorepo; the old tigera/operator repository only serves the release-v1.41 to release-v1.44 branches.


Data Planes

Calico separates the control plane (Felix, BIRD, Typha) from the packet-processing data plane. The table summarizes the options; detailed requirements are in Reference: Data plane matrix.

Data Plane Options

Data Plane How It Works Best For
iptables (default) Felix writes iptables chains and ipsets; kube-proxy handles Services Widest compatibility, legacy kernels
nftables (GA in 3.31) Felix writes nftables tables and sets; pairs with kube-proxy in nftables mode Newer kernels (5.13+), atomic rule updates, clusters moving off iptables
eBPF Felix attaches eBPF programs (TCX where available, else TC) and replaces kube-proxy Performance, source-IP preservation, DSR, Maglev
VPP FD.io Vector Packet Processor in userspace, optionally with DPDK High throughput, IPsec/WireGuard acceleration, memif interfaces
Windows HNS Host Networking Service rules on Windows nodes Windows worker nodes

Standard Linux (iptables) data plane

The default data plane. Felix renders policy into iptables chains, uses ipsets for selector-matched IP groups, and programs routes; kube-proxy (iptables, IPVS or nftables mode) handles Service load balancing. The sequence below shows cross-node pod traffic in BGP mode without encapsulation.

sequenceDiagram
    participant PodA as Pod A (Node 1)
    participant Felix1 as Felix (Node 1)
    participant FIB1 as Kernel FIB (Node 1)
    participant BIRD1 as BIRD (Node 1)
    participant BIRD2 as BIRD (Node 2)
    participant FIB2 as Kernel FIB (Node 2)
    participant Felix2 as Felix (Node 2)
    participant PodB as Pod B (Node 2)

    Note over BIRD1,BIRD2: Control plane (before traffic flows)
    Felix1->>FIB1: Program route for Pod A /32 to local veth
    BIRD1->>BIRD2: BGP UPDATE, advertise Node 1 IPAM block
    BIRD2->>FIB2: Install route, Node 1 block via Node 1
    Felix2->>FIB2: Program route for Pod B /32 to local veth
    BIRD2->>BIRD1: BGP UPDATE, advertise Node 2 IPAM block
    BIRD1->>FIB1: Install route, Node 2 block via Node 2

    Note over PodA,PodB: Data path
    PodA->>FIB1: Packet leaves pod veth, egress policy in iptables
    FIB1->>FIB2: Route lookup via Node 2, forwarded unencapsulated
    FIB2->>PodB: Route lookup to local veth, ingress policy in iptables

nftables data plane

The nftables data plane became generally available in Calico 3.31 (tech preview since 3.29). It targets the nftables kube-proxy mode that Kubernetes introduced as beta in 1.31, so the cluster's kube-proxy must also run in nftables mode. It needs Linux 5.13 or later with nft 1.0.1 or later. Felix's nftablesMode defaults to Auto, and since 3.32 Calico can auto-detect nftables versus iptables from the kube-proxy configuration. nftables replaces rule chains atomically and uses native sets and maps, which avoids some of the linear-chain and lock-contention costs of iptables.

eBPF data plane

Calico's eBPF data plane replaces iptables with eBPF programs attached to the TC or TCX hooks of each interface, and replaces kube-proxy.

graph LR
    subgraph Path["Pod traffic path"]
        POD["Pod veth (cali*)"] -->|"egress"| TC_IN["TC/TCX program<br/>on workload iface"]
        TC_IN -->|"policy + NAT"| ROUTE["FIB lookup"]
        ROUTE -->|"same node"| DEST["Destination pod veth"]
        ROUTE -->|"remote node"| TUN["Host iface or vxlan.calico<br/>(TC/TCX program)"]
    end

    subgraph Maps["BPF maps"]
        NAT_MAP["NAT frontend + backend<br/>(Services)"]
        POL_MAP["IP sets<br/>(selector members)"]
        CT_MAP["Conntrack<br/>(LRU hash since 3.31)"]
        RT_MAP["Routes"]
    end

    TC_IN -->|"lookup"| NAT_MAP
    TC_IN -->|"policy check"| POL_MAP
    TC_IN -->|"track flow"| CT_MAP
    ROUTE -->|"lookup"| RT_MAP

    subgraph CTLB["Connect-time load balancer"]
        SOCK["cgroup socket hook"] -->|"rewrites connect() to backend"| DIRECT["Backend pod IP<br/>(no per-packet NAT)"]
    end

Key characteristics:

  • Bypasses iptables: packets are handled by eBPF programs, skipping iptables chains and most netfilter conntrack overhead. Policy is compiled into eBPF programs that consult IP-set maps populated from label selectors.
  • Connect-time load balancing: a cgroup socket hook rewrites connect() to a Service ClusterIP into a backend IP, so pod-to-Service traffic needs no per-packet NAT. The default bpfConnectTimeLoadBalancing is TCP (UDP is NATed per packet).
  • kube-proxy replacement: handles ClusterIP, NodePort, LoadBalancer and external IPs, and preserves client source IPs. Direct server return (bpfExternalServiceMode: DSR) avoids the extra hop for external traffic.
  • Recent additions: operator-driven install and switch-over that disables kube-proxy automatically (3.31), LRU conntrack map (3.31), QoS controls in eBPF (3.31), Maglev consistent-hash load balancing for external traffic (3.32, DSR only), TCP RST to clients when a backend pod disappears (3.32), and Service traffic distribution / topology-mode support (3.32).

eBPF data plane requirements

Linux kernel 5.10 or later, or RHEL 8.4 with kernel 4.18.0-305 or later (Red Hat backported the features). x86-64 or arm64 only, Kubernetes API datastore only (not etcd), no GKE, no IP-in-IP (use VXLAN), no SCTP, and no mixing eBPF nodes with iptables or Windows nodes in one cluster. See Reference: Kernel and platform requirements.

VPP data plane

The VPP data plane runs FD.io's Vector Packet Processor in userspace on each node, with Calico plugins for Service load balancing and policy. It gives higher throughput (especially with WireGuard or IPsec), native Service handling without kube-proxy, and memif interfaces and the VPP host stack for network-heavy pods. VPP nodes can coexist with Linux or eBPF nodes in one cluster. Only operator-based installs are supported. The projectcalico/vpp-dataplane README still describes the integration as "in incubation status" (checked 2026-09).

Windows data plane

On Windows nodes, Felix programs the Windows Host Networking Service (HNS). Calico for Windows supports BGP and VXLAN networking and Calico policy; the operator can install it (3.32 renamed the Windows containers to node, felix and confd).


Network Policy Model

Calico implements Kubernetes NetworkPolicy and adds its own richer resources in projectcalico.org/v3.

Kubernetes NetworkPolicy

Calico fully implements the Kubernetes NetworkPolicy resource:

  • Namespaced: each policy applies to pods in one namespace.
  • Ingress and egress rules: restrict traffic by pod selector, namespace selector, IP block (CIDR), and port/protocol.
  • Default deny: a policy that selects pods and has no rules denies all traffic not explicitly allowed.

Calico NetworkPolicy (projectcalico.org/v3)

Calico's namespaced NetworkPolicy adds capabilities beyond the Kubernetes standard:

  • Policy ordering: the order field sets evaluation priority; lower values are evaluated first.
  • Explicit actions: rules can Allow, Deny, Log, or Pass (hand the decision to the next tier).
  • ServiceAccount selectors: match traffic by source or destination ServiceAccount.
  • Port ranges and named ports.
  • HTTP match criteria: L7 rules on HTTP methods and paths when Application Layer Policy (Dikastes) is enabled.

GlobalNetworkPolicy (projectcalico.org/v3)

GlobalNetworkPolicy is cluster-scoped. It can apply across all namespaces, to host interfaces, and to non-Kubernetes workloads:

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: default-deny
spec:
  selector: projectcalico.org/namespace not in {'kube-system', 'calico-system'}
  types:
  - Ingress
  - Egress

Key capabilities:

  • Cross-namespace enforcement: one policy can govern pods in every namespace.
  • Host endpoint policy: protects host interfaces (physical NICs) and node-level traffic.
  • Pre-DNAT policy: evaluates rules before DNAT, so policy can match the original destination of NodePort and LoadBalancer traffic.
  • Apply-on-forward and DoS mitigation: policy for forwarded traffic through hosts.

NetworkSet and GlobalNetworkSet name groups of CIDRs (partner ranges, known-bad IPs) that policies can select by label:

apiVersion: projectcalico.org/v3
kind: GlobalNetworkSet
metadata:
  name: known-bad-ips
  labels:
    role: blocked
spec:
  nets:
  - 198.51.100.0/24
  - 203.0.113.0/24

Policy Tiers

Tiers group policies and define evaluation order; they are part of Calico Open Source. Tiers are evaluated from the lowest order to the highest. Within a tier, a policy's Pass action (or a tier defaultAction: Pass) hands the packet to the next tier; if a tier's policies select an endpoint but take no action, the packet is dropped.

Built-in tiers in 3.32:

Tier Order Contents
kube-admin 1,000 (fixed, default action Pass) Kubernetes ClusterNetworkPolicy with tier: Admin
user-defined tiers your choice (for example 100 to 900,000) Calico policies for security, platform or application teams
default 1,000,000 (fixed) Kubernetes NetworkPolicy and Calico policies with no tier
kube-baseline 10,000,000 (fixed, default action Pass) Kubernetes ClusterNetworkPolicy with tier: Baseline

The operator also creates a calico-system tier (named allow-tigera before 3.32) that holds policies protecting Calico's own components.

The flowchart shows how a packet moves through the tiers.

flowchart TB
    Packet["Packet to or from endpoint"] --> KA["kube-admin tier<br/>(ClusterNetworkPolicy Admin)"]
    KA -->|"Pass or no match"| SEC["User tier: security<br/>(order 100)"]
    SEC -->|"Pass"| PLAT["User tier: platform<br/>(order 200)"]
    PLAT -->|"Pass"| DEF["default tier<br/>(K8s NetworkPolicy, order 1,000,000)"]
    DEF -->|"no policy selects endpoint"| KB["kube-baseline tier<br/>(ClusterNetworkPolicy Baseline)"]
    KA -->|"Accept or Deny"| VERDICT["Verdict"]
    SEC -->|"Allow or Deny"| VERDICT
    PLAT -->|"Allow or Deny"| VERDICT
    DEF -->|"Allow or Deny"| VERDICT
    KB -->|"Allow, Deny, or default"| VERDICT

Tiers let platform teams enforce a baseline (for example, deny all external egress) that application teams, who only have RBAC on their own tier, cannot override.

ClusterNetworkPolicy

Calico 3.32 implements the upstream SIG-Network ClusterNetworkPolicy (policy.networking.k8s.io/v1alpha2), including named ports and network peers. It gives cluster admins Accept/Deny/Pass rules in the Admin and Baseline tiers that namespace owners cannot override. Support for the older AdminNetworkPolicy and BaselineAdminNetworkPolicy resources was removed in 3.32; convert them before upgrading, because 3.32 does not enforce them.

Staged policies

Since 3.30, StagedNetworkPolicy, StagedGlobalNetworkPolicy and StagedKubernetesNetworkPolicy let you preview a policy. Felix evaluates it without enforcing it, and flow logs in Whisker show what the staged policy would have done. When the result looks right, you apply the same spec as the non-staged kind.

RBAC for policy management

Calico uses Kubernetes RBAC to control who can create, change or read policies per tier, using the tier.networkpolicies and tier.globalnetworkpolicies pseudo-resources:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: tier-default-reader
rules:
- apiGroups: ['projectcalico.org']
  resources: ['tiers']
  resourceNames: ['default']
  verbs: ['get']
- apiGroups: ['projectcalico.org']
  resources: ['tier.networkpolicies']
  resourceNames: ['default.*']
  verbs: ['get', 'list']

The resourceNames scoping patterns are listed in Reference: Tier RBAC resource names. In manifest installs without the API server, a validating admission webhook (added in 3.32) enforces the same tier RBAC.


Observability: Goldmane and Whisker

Calico 3.30 added open-source flow logs. Two operator-managed components provide them, both still tech preview in 3.32:

  • Goldmane (calico/goldmane): a flow-aggregation service. Felix on each node sends flow updates to it, and Goldmane aggregates them into a cluster-wide view exposed through a gRPC API (mTLS required, port 7443). It can also emit aggregated flows to an external endpoint, which is how Calico Cloud Free Tier receives data.
  • Whisker (calico/whisker + calico/whisker-backend): an in-cluster web console that streams flow logs from Goldmane. It can filter by policy, namespace, pod, verdict and reporter (3.32), and shows staged-policy ("pending") actions. It is reachable only by port-forward by default, and Calico installs policies that deny other ingress to it.

A flow log is an aggregate: all connections that share source, destination, action and policy trace in an interval (Felix's flowLogsFlushInterval) become one record with packet and byte counters.

The sequence below shows how a denied connection reaches the Whisker UI.

sequenceDiagram
    participant Pod as Client pod
    participant Felix as Felix (node)
    participant GM as Goldmane (calico-system)
    participant WB as whisker-backend
    participant UI as Whisker UI (browser via port-forward)

    Pod->>Felix: Connection hits Deny rule in tier security
    Felix->>Felix: Aggregate flow with policy hit and counters
    Felix->>GM: Stream flow update over mTLS gRPC
    GM->>GM: Merge per-node flows into cluster-wide buckets
    UI->>WB: Open live stream with filters
    WB->>GM: gRPC Stream request with filter
    GM-->>WB: Matching flows, action deny
    WB-->>UI: Render flow row with policy trace

Sensitive data

Goldmane and Whisker hold workload names, labels and traffic patterns. Calico's docs advise against exposing them externally without extra authentication (for example, Calico Ingress Gateway plus an auth layer).

Upgraded clusters (from 3.29 or earlier) do not get Goldmane and Whisker automatically; you apply the Goldmane and Whisker custom resources (see How-to Guides).


Calico Ingress Gateway

Calico Ingress Gateway is Tigera's hardened build of the upstream Envoy Gateway project, an implementation of the Kubernetes Gateway API. The Tigera Operator manages its lifecycle through a GatewayAPI custom resource, which installs the Gateway API CRDs (by default) and a GatewayClass named tigera-gateway-class. You then create standard Gateway and HTTPRoute (or GRPCRoute, TLSRoute, TCPRoute, UDPRoute) objects. Envoy Gateway is the control plane; Envoy Proxy pods are the data plane.

Release Status and change
3.30 Tech preview
3.31 Generally available
3.32 / 3.31.x patches Bundled Envoy Gateway moved to v1.8.x, which needs Gateway API v1.5.1 CRDs (TLSRoute, ListenerSet, BackendTLSPolicy at v1)
Next (unreleased) Breaking: proxies move into each Gateway's namespace, the controller moves to calico-system, and mergeGateways is no longer supported

Calico Enterprise and Calico Cloud add a WAF for ingress gateways and an L7 dashboard. See Envoy Gateway for the upstream project.


Service Mesh Integration

Application Layer Policy (Dikastes)

Dikastes is Calico's L7 policy agent. With Application Layer Policy enabled, it runs alongside the Istio Envoy sidecar and enforces Calico policy rules on HTTP methods and paths, using the mesh's cryptographic identity (mTLS) as well as IPs. Calico enforces policy at both points: in the kernel (L3/L4) and in the proxy (L7). Kernel enforcement still protects the workload if the pod is compromised and the proxy is bypassed.

Recent fixes

Dikastes L7 enforcement was broken from 3.30.0 until a 3.32 fix (missing ALPCheckProvider registration), and 3.32 hardened HTTP path normalization before matching. Calico Enterprise deprecated its own Envoy-based application layer policy in Enterprise 3.23.

Istio ambient mode (tech preview, 3.32)

Calico 3.32 bundles Istio in ambient (sidecarless) mode, with Calico-built pilot, proxyv2, install-cni and ztunnel images (Istio 1.29.x). Tigera's modified ztunnel keeps the original destination port instead of rewriting it to the HBONE port 15008, so existing Calico and Kubernetes policies keep working. The exception is waypoint proxies, where traffic follows upstream behavior and policies must allow port 15008. See Istio.


Encryption

Calico can encrypt traffic between nodes with WireGuard, configured through FelixConfiguration:

  • Transparent: encryption uses the kernel WireGuard module (Linux 5.6+, or a backport). No application changes are needed.
  • Per-node keys: Felix generates a key pair on each node and publishes the public key in the node's status (wireguardPublicKey, wireguardPublicKeyV6) so peers can find it. Custom keys are not supported.
  • IPv4 and IPv6: wireguardEnabled and wireguardEnabledV6 turn on encryption independently (UDP 51820 and 51821 by default).
  • Host traffic: wireguardHostEncryptionEnabled also encrypts host-network traffic, supported only on EKS and AKS when you use the cloud provider CNI.
  • Per-node opt-out: a node-specific FelixConfiguration (node.<name>) can turn encryption off for one node.
  • Scope: traffic is encrypted only on the host-to-host part of the path; same-node pod traffic is not encrypted. GKE is not supported.

Kernel requirement

WireGuard is built into Linux 5.6 and later. Older kernels need the wireguard module installed for the running kernel. Nodes without WireGuard still work, but their traffic is not encrypted.

The VPP data plane can also use IPsec between nodes.


Datastore Options

On Kubernetes, Calico stores its state either through the Kubernetes API (the default and only option for operator installs, eBPF mode and OpenShift) or directly in an etcd v3 cluster (used for OpenStack, non-cluster hosts, and some large legacy deployments). The comparison table is in Reference: Datastore options.


Networking Modes

Calico offers three ways to route pod traffic between nodes: unencapsulated BGP, VXLAN and IP-in-IP. The CrossSubnet variants encapsulate only when traffic crosses an L3 subnet boundary. Calico can also advertise Service cluster, external and LoadBalancer IPs over BGP. The full mode table (transport, ports, BGP requirement) is in Reference: Networking modes.

This flowchart summarizes the usual choice of data plane and encapsulation.

flowchart TD
    Start["New Calico cluster"] --> Win{"Windows nodes?"}
    Win -->|"Yes"| IPT["iptables or nftables on Linux,<br/>HNS on Windows<br/>(eBPF cannot mix with Windows)"]
    Win -->|"No"| Perf{"Need kube-proxy replacement,<br/>DSR, source-IP preservation?"}
    Perf -->|"Yes, kernel 5.10+"| EBPF["eBPF data plane<br/>(VXLAN or no-encap, not IP-in-IP)"]
    Perf -->|"No"| NFT{"kube-proxy in nftables mode<br/>and kernel 5.13+?"}
    NFT -->|"Yes"| NFTDP["nftables data plane"]
    NFT -->|"No"| IPTDP["iptables data plane (default)"]
    EBPF --> Fabric{"Can the fabric peer BGP<br/>or share one L2 domain?"}
    NFTDP --> Fabric
    IPTDP --> Fabric
    Fabric -->|"Yes"| BGP["BGP, no encapsulation<br/>(route reflectors above ~100 nodes)"]
    Fabric -->|"No, cloud VPC"| VX["VXLAN or VXLANCrossSubnet"]

Threat Model

Threat Mitigation
Lateral pod-to-pod movement Default-deny GlobalNetworkPolicy, tiered policies, ClusterNetworkPolicy Admin tier
Unauthorized egress to the internet Egress policies with CIDR rules and GlobalNetworkSet; DNS-based policy needs Calico Enterprise or Cloud
Pod impersonation or IP spoofing Felix programs per-endpoint routes and reverse-path filtering on cali* interfaces
Unencrypted inter-node traffic WireGuard encryption (IPv4 and IPv6)
Pod access to the host defaultEndpointToHostAction (default Drop) and host endpoint policies
Untested policy breaking production Staged policies previewed in Whisker flow logs
Insider policy tampering RBAC scoped per tier; in manifest mode the 3.32 admission webhook enforces tier RBAC
Exposure of flow data Whisker and Goldmane are not exposed by default and require mTLS for the gRPC API
Secrets in logs 3.32 removed tokens, kubeconfig contents and etcd credentials from calicoctl, CNI and component logs

Enterprise and Cloud extras

Tigera's commercial editions add audit logging of policy changes, policy recommendations from observed traffic (including for VMs and hosts in Enterprise 3.24), a "last evaluated" view for finding unused policies (Enterprise 3.23), DNS policy, egress gateways, and a WAF. Calico Open Source does not include these.


Design Trade-offs

  • L3 routing first: Calico treats every node as a router and pods as /32 routes, which fits BGP data centers and gives pods routable IPs without overlays. The cost is that the underlay must accept pod routes (BGP peering or one L2 domain), or you fall back to VXLAN.
  • Pluggable data planes: the same policy model runs on iptables, nftables, eBPF, VPP and Windows. That gives more choice than eBPF-only CNIs, but some features are data-plane specific (for example Maglev is eBPF-only, and QoS was iptables/nftables-only until 3.31).
  • Open core: networking, policy tiers, staged policy, WireGuard, flow logs and the ingress gateway are open source. Multi-cluster federation, DNS policy, egress gateways, the management UI and compliance features are paid.
  • API migration: moving projectcalico.org/v3 from an aggregated API server to native CRDs simplifies installs but adds migration steps for existing clusters and requires Kubernetes 1.32+ with the MutatingAdmissionPolicy API.

Benchmarks

Calico publishes no benchmark figures or hard scale limits; Reference: Benchmarks lists the performance changes documented in release notes. Qualitatively, Calico documents that the eBPF data plane lowers first-packet latency to Services, preserves source IPs, and scales better than iptables as policy and Service counts grow. The VPP data plane targets higher throughput with encryption.


Sources