Reference¶
Scope
Look-up facts for Cilium: versions and support windows, Kubernetes and kernel requirements, ports, key Helm values and defaults, eBPF map limits, feature maturity, deprecations and removals, IPAM and routing modes, and performance/scale figures. Everything here was checked against the v1.20 release branch of cilium/cilium on 2026-09-25 unless stated otherwise. For why things work this way see Explanation; for tasks see How-to Guides.
Release and Support Matrix¶
Cilium ships a feature release (X.Y.0) about every six months and keeps three stable branches (the latest minor plus the two before it). Patch releases for all maintained branches usually land around the middle of each month. Pre-releases of main come out monthly. Dates below are the publication times of the Helm charts in the cilium/charts index (UTC).
| Branch | First release | Latest patch (date) | Status (2026-09-25) |
|---|---|---|---|
| 1.21 | TBD (expected early 2027 on the ~6-month cadence) | 1.21.0-pre.2 (2026-09-09) |
Development (main reports 1.21.0-dev) |
| 1.20 | 2026-07-29 | 1.20.2 (2026-09-15) | Current stable (stable.txt = v1.20.2) |
| 1.19 | 2026-02-04 | 1.19.8 (2026-09-16) | Maintained |
| 1.18 | 2025-07-29 | 1.18.14 (2026-09-15) | Maintained (oldest supported) |
| 1.17 | 2025-02-04 | 1.17.18 (2026-07-16) | End of life (dropped when 1.20 shipped) |
Upgrade rule
Only upgrades and rollbacks between consecutive minor releases are tested. Move to the latest patch of your current minor first, then go up one minor at a time (for example 1.18.14 -> 1.19.8 -> 1.20.2).
Related tools:
| Component | Latest (date) | Where to check |
|---|---|---|
| cilium-cli | v0.20.1 (2026-09) | https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt |
| Hubble CLI | v1.19.4 (2026-09) | https://raw.githubusercontent.com/cilium/hubble/main/stable.txt |
| Tetragon (Helm chart) | 1.7.1 (2026-08-25) | helm search repo cilium/tetragon |
| cilium-envoy | v1.37.x in Cilium 1.20 | Cilium 1.20 CHANGELOG |
Kubernetes Compatibility¶
Versions listed are the ones e2e-tested for each Cilium minor. Newer Kubernetes versions depend on Kubernetes backward compatibility.
| Cilium | Tested Kubernetes versions |
|---|---|
| 1.20 | 1.33, 1.34, 1.35, 1.36 |
| 1.19 | 1.31, 1.32, 1.33, 1.34 |
| 1.18 | 1.30, 1.31, 1.32, 1.33 |
System Requirements¶
| Requirement | Minimum (Cilium 1.18 - 1.20) | Notes |
|---|---|---|
| Linux kernel | >= 5.10 (or 4.18 on RHEL 8.10) | Cilium 1.16 and 1.17 accepted >= 5.4. The rise to 5.10 came in 1.18 |
| CPU architecture | AMD64, AArch64 | Images are built for both |
| clang/LLVM | >= 18.1 | Only when running cilium-agent natively. Already in the cilium/cilium image |
| etcd (optional kvstore) | >= 3.1.0 | CRD-based identity is the default. A kvstore helps very large clusters |
| Privileges | CAP_SYS_ADMIN (or root/privileged), host network namespace |
Granted automatically by the DaemonSet |
| BPF filesystem | /sys/fs/bpf |
Auto-mounted if missing. Keeps maps across agent restarts |
| cgroup v2 | Mounted at /run/cilium/cgroupv2 by default |
Needed for socket-level load balancing |
Features that need newer kernels:
| Feature | Minimum kernel |
|---|---|
| Multicast (AMD64) | 5.10 |
| IPv6 BIG TCP | 5.19 |
| Multicast (AArch64) | 6.0 |
| IPv4 BIG TCP | 6.3 |
| netkit device mode | 6.8 |
| WireGuard (in-tree) | 5.6 (or out-of-tree module) |
Distributions documented as known to work: Amazon Linux 2, Bottlerocket, CentOS >= 8.6, Container-Optimized OS >= 85, Debian >= 10, Fedora CoreOS, Flatcar, LinuxKit, openSUSE (Tumbleweed, Leap >= 15.4), RHEL >= 8.6, RHCOS >= 4.12, Talos >= 1.5.0, Ubuntu >= 20.04.
Ports¶
| Port / protocol | Component |
|---|---|
| 4240/tcp | cilium-health cluster health checks (ICMP echo is the alternative) |
| 4244/tcp | Hubble server (per node) |
| 4245/tcp | Hubble Relay |
| 4250/tcp | Mutual authentication (deprecated feature) |
| 4251/tcp | SPIRE agent health check (localhost) |
| 6060, 6061, 6062/tcp | pprof: agent, operator, Hubble Relay (localhost) |
| 8472/udp | VXLAN overlay (Linux default) |
| 6081/udp | Geneve overlay |
| 51871/udp | WireGuard tunnel endpoint |
| 9878, 9879/tcp | cilium-envoy health, agent health API (localhost) |
| 9890, 9891, 9893/tcp | gops: agent, operator, Hubble Relay (localhost) |
| 9901/tcp | cilium-envoy admin API (localhost) |
| 9962, 9963, 9964/tcp | Prometheus metrics: agent, operator, cilium-envoy |
| 15008/tcp | HBONE, used by ztunnel encryption (beta) |
| ESP (IP proto 50) | IPsec encryption. AWS security groups block it by default |
| 2379-2380/tcp | etcd (kvstore mode) |
Cilium also reserves routing table IDs 200 (IPsec), 202 (VTEP), 2004 and 2005 (proxy), and 10 + <ENI index> in ENI IPAM mode.
Key Helm Values¶
Chart: cilium/cilium from https://helm.cilium.io/ or oci://quay.io/cilium/charts/cilium (OCI charts, cosign-signed, since 1.19). Defaults are from install/kubernetes/cilium/values.yaml on the v1.20 branch.
| Helm value | Default | Purpose |
|---|---|---|
kubeProxyReplacement |
"false" |
true = full eBPF kube-proxy replacement. false still load-balances ClusterIP per packet |
k8sServiceHost / k8sServicePort |
"" |
API server address. Needed when kube-proxy is removed |
k8s.apiServerURLs |
unset | Several API servers for agent fail-over (replaces removed --k8s-api-server) |
routingMode |
tunnel |
tunnel or native |
tunnelProtocol |
vxlan |
vxlan or geneve |
autoDirectNodeRoutes |
false |
Install direct routes between nodes on the same L2 (native routing) |
ipv4NativeRoutingCIDR |
"" |
CIDR that should not be masqueraded in native routing |
ipam.mode |
cluster-pool |
cluster-pool, kubernetes, multi-pool, eni, azure, alibabacloud, delegated-plugin |
bpf.masquerade |
false |
eBPF masquerading instead of iptables |
bpf.hostLegacyRouting |
false |
false = eBPF host routing when the kernel supports it |
bpf.datapathMode |
veth |
veth, netkit, netkit-l2, auto (1.20+) |
bpf.mapDynamicSizeRatio |
0.0025 |
Share of node memory used to size the large maps (CT, NAT, neighbor) |
bpf.ctTcpMax |
524288 |
TCP connection-tracking entries |
bpf.policyMapMax |
16384 |
Policy entries per endpoint |
bpf.lbMapMax |
65536 |
Service/backend map entries |
bpf.tproxy |
false |
eBPF TPROXY (beta). Not compatible with netkit |
loadBalancer.algorithm |
random |
random or maglev |
loadBalancer.mode |
snat |
snat, dsr, hybrid |
loadBalancer.acceleration |
disabled |
XDP acceleration: disabled, native, best-effort |
socketLB.enabled |
false |
Socket-level (connect-time) load balancing. Turned on by kube-proxy replacement |
hubble.enabled |
true |
Hubble server on each agent |
hubble.relay.enabled / hubble.ui.enabled |
false / false |
Cluster-wide flow API and web UI |
envoy.enabled |
true for new installs |
Run Envoy as the standalone cilium-envoy DaemonSet |
l7Proxy |
true |
Needed for L7 policy, Ingress and Gateway API |
gatewayAPI.enabled |
false |
Gateway API controller (needs kubeProxyReplacement=true) |
ingressController.enabled |
false |
Kubernetes Ingress controller |
encryption.enabled / encryption.type |
false / ipsec |
ipsec, wireguard, or ztunnel (beta) |
bgpControlPlane.enabled |
false |
BGP control plane (CiliumBGP* v2 CRDs) |
l2announcements.enabled |
false |
ARP/NDP announcements for LoadBalancer IPs |
egressGateway.enabled |
false |
Egress gateway (static egress IPs) |
bandwidthManager.enabled / .bbr |
false / false |
EDT-based pod rate limiting, optional BBR |
cluster.name / cluster.id |
default / 0 |
Must be unique per cluster for Cluster Mesh (ID 1-255, or 1-511) |
clustermesh.maxConnectedClusters |
255 |
511 halves cluster-local identities. Can only be set at install |
operator.replicas |
2 |
cilium-operator replicas |
policyEnforcementMode |
default |
default, always, never |
configDriftDetection.enabled |
enabled | ConfigMap drift detection and metric (1.20+) |
eBPF Map Limits¶
Default capacities from the Cilium eBPF maps documentation (v1.20). Going past a limit makes insertions fail, which caps datapath scale.
| Map | Scope | Default limit | Scale implication |
|---|---|---|---|
| Connection tracking | node | 512k TCP / 256k UDP | Concurrent connections per node |
| NAT | node | 512k | NAT entries per node |
| Neighbor table | node | 512k | Neighbor entries |
| Endpoints | node | 64k | Local endpoints + host IPs per node |
| IP cache | node | 512k | Endpoints across all clusters |
| Service load balancer | node | 64k | About 3k ClusterIP/NodePort services across all clusters |
| Service backends | node | 64k | Unique backends across all services |
| Policy | endpoint | 16k | Allowed identity + port + protocol pairs per endpoint |
| Egress policy | node | 16k | Endpoints across all egress-gateway destination CIDRs |
| Node | node | 16k | Distinct node IPs across all clusters |
| IPv4/IPv6 fragmentation | node | 8k | Fragmented datagrams in flight |
| Auth | node | 512k | Authenticated relations (mutual auth) |
Override flags: --bpf-ct-global-tcp-max, --bpf-ct-global-any-max, --bpf-nat-global-max, --bpf-neigh-global-max, --bpf-policy-map-max, --bpf-lb-map-max, --bpf-fragments-map-max, --bpf-auth-map-max. --bpf-map-dynamic-size-ratio sizes the CT, NAT, neighbor and reverse-socket maps from total memory (0.0025 = 0.25%). The NAT table must not exceed 2/3 of the combined CT size.
eBPF Map Types Used¶
| Map Type | Purpose |
|---|---|
| Hash map | Policy rules, service → endpoint mapping |
| LRU hash | Conntrack entries (connection state) |
| Array | Per-CPU counters, configuration |
| Perf event array / ring buffer | Datapath events to the agent (monitor, Hubble). Ring-buffer support added in 1.18 |
| LPM trie | CIDR-based policy matching, IP cache |
Gateway API Support¶
| Cilium | Gateway API version | Notes |
|---|---|---|
| 1.20 | v1.6.1 (minimum) | TLSRoute moved to v1. Adds TCPRoute, UDPRoute, ListenerSet, ExternalAuth filter (GEP-1494), CORS, BackendTLSPolicy |
| 1.19 | v1.4 | GAMMA supports GRPCRoute as well as HTTPRoute |
| 1.18 | v1.3.0 |
Resources supported in 1.20: GatewayClass, Gateway, HTTPRoute, GRPCRoute, TLSRoute, BackendTLSPolicy, ReferenceGrant, ListenerSet, TCPRoute, UDPRoute, plus the CiliumGatewayClassConfig CRD for parametersRef. TCPRoute, UDPRoute and ListenerSet CRDs are optional. If they are missing, Cilium turns those features off.
TLSRoute upgrade trap (1.20)
If you install the Standard v1.6 TLSRoute CRD over existing v1alpha2 objects, the API server can no longer read them from etcd and they effectively disappear. Back up TLSRoutes and install the Experimental v1.6.1 TLSRoute CRD (which still serves v1alpha2) before upgrading Cilium to 1.20.
Prerequisites: kubeProxyReplacement=true, l7Proxy=true, and either LoadBalancer Service support or host-network mode (since 1.16). With the default bpf.tproxy=false, nodes need iptables TPROXY modules.
Feature Maturity¶
| Feature | Status (1.20) | Since / notes |
|---|---|---|
| Multi-Pool IPAM | Stable | Promoted in 1.19 |
| MCS-API (Cluster Mesh) | Stable | Promoted in 1.20. Uses v1beta1 CRDs (v1alpha1 still works) |
| Kubernetes ClusterNetworkPolicy (KCNP) | New in 1.20 | From SIG Network Policy API |
PreferSameZone / PreferSameNode traffic distribution |
New in 1.20 | |
| ztunnel transparent encryption (mTLS) | Beta | Added 1.19. Namespaces opt in with label io.cilium/mtls-enabled=true |
| netkit datapath | Beta | Kernel >= 6.8 plus eBPF host routing. auto mode added in 1.20 |
eBPF TPROXY (bpf.tproxy) |
Beta | Removes the iptables dependency for Gateway/L7 |
| ENI IPAM with IPv6 prefixes | Beta | New in 1.20 |
| Datapath plugins (third-party extensions) | Beta | New in 1.20 |
| IPsec / WireGuard strict mode | Available | Added in 1.19 |
| Mutual authentication (SPIFFE/SPIRE) | Beta, deprecated in 1.20 | Replacement suggested: ztunnel encryption |
| Kafka L7 policy, Envoy Go extensions (proxylib) | Removed in 1.20 | Deprecated in 1.18 |
| Docker libnetwork plugin | Removed in 1.20 | |
| Local REST policy API | Deprecated in 1.18 | Removal announced for a later release |
Deprecations and Removals (1.20)¶
| Item | Change | Action |
|---|---|---|
kafka, l7, l7proto rules in CNP/CCNP |
Removed | Delete those rules sections before upgrading |
CiliumNodeConfig cilium.io/v2alpha1 |
Removed | Use cilium.io/v2 (available since 1.16) |
clustermesh.enableMCSAPISupport |
Removed | Use clustermesh.mcsapi.enabled |
--node-port-algorithm, --node-port-mode |
Removed | Use loadBalancer.algorithm, loadBalancer.mode |
encryption.strictMode.* (old keys) |
Removed | Use encryption.strictMode.egress.* |
--k8s-api-server |
Removed | Use k8s.apiServerURLs |
encryption.ipsec.interface, encryption.ipsec.encryptedOverlay |
Removed | No-ops before removal |
hubble.redact.kafka.apiKey |
Removed | Part of dropping Kafka |
hubble.preferIpv6 |
Deprecated | Use top-level preferIpv6 |
dnsProxy.preCache (--tofqdns-pre-cache) |
Deprecated | Removal planned in 1.21 |
cilium-dbg bgp / REST BGP listing |
Deprecated | Use cilium-dbg shell -- bgp/* |
Empty CNP/CCNP (no spec/specs) |
Now rejected at admission (CEL) | Fix manifests |
| Cluster Mesh auto certificates | Default validity cut to 1 year | Upgrade at least yearly (helm mode) or use cronJob/certmanager |
| CNI spec version | Default now 1.0.0 |
Update custom CNI configs |
IPAM Modes¶
| Mode | How it works | When to use |
|---|---|---|
| Cluster Pool (Helm default) | Cilium Operator allocates per-node CIDRs from a configured pool and records them in CiliumNode resources. |
Default for new installs. Environments where kube-controller-manager does not allocate CIDRs |
| Kubernetes | Uses the Node resource .spec.podCIDR set by kube-controller-manager (--allocate-node-cidrs). |
Clusters where Kubernetes already allocates node CIDRs |
| Multi-Pool | Several CiliumPodIPPool pools, chosen per pod or namespace. Stable since 1.19. 1.20 adds migration from cluster-pool and allowFirstIP/allowLastIP. |
Several IP ranges, per-tenant pools |
| ENI | Allocates AWS Elastic Network Interface IPs (or prefixes) directly to pods. IPv6 prefixes in beta since 1.20. | AWS EKS or self-managed AWS clusters |
| Azure IPAM | Allocates IPs from Azure VNet subnets directly to pods. | Azure (self-managed). AKS uses its own "Azure CNI Powered by Cilium" integration |
| AlibabaCloud | Allocates ENI IPs on Alibaba Cloud. | Alibaba Cloud |
| Delegated plugin | Delegates IPAM to another CNI IPAM plugin (IPv6 supported since 1.18). | Chaining setups |
Routing Modes¶
| Mode | Description | When to use |
|---|---|---|
| Tunnel (VXLAN/Geneve) (default, VXLAN) | Encapsulates pod traffic in VXLAN (UDP 8472) or Geneve (UDP 6081) between nodes. No underlay routing needed. IPv6 underlay supported since 1.18. | Cloud environments, any network fabric |
| Native Routing (direct) | Pod CIDRs are routed by the underlay, by autoDirectNodeRoutes, BGP, or the cloud router. |
Bare-metal, on-prem, cloud VPCs with custom routing |
| Hybrid | Native routing within the same L2 segment, tunneling across subnets. | Mixed environments |
kube-proxy Replacement Coverage¶
| Service Type | kube-proxy (iptables) | Cilium (eBPF) |
|---|---|---|
| ClusterIP | iptables DNAT rules | TC eBPF + socket-level connect-time LB |
| NodePort | iptables DNAT + kube-proxy port binding | TC eBPF on host interfaces (SNAT, DSR or hybrid) |
| LoadBalancer | iptables DNAT via kube-proxy | TC eBPF, optional XDP acceleration |
| ExternalIPs | iptables DNAT | TC eBPF |
| HostPort | portmap CNI plugin | TC eBPF (portmap not needed) |
Current kubeProxyReplacement values are true and false. The old strict/partial/probe modes no longer exist. Maglev table sizes (maglev.tableSize) are primes such as 16381 (~160 backends) and 65521 (~650 backends). All agents must share maglev.hashSeed.
Security Policy Layers¶
| Layer | Enforcement Point | Capabilities |
|---|---|---|
| L3/L4 | TC eBPF (ingress/egress) | Identity-based allow/deny by label, CIDR, FQDN, entity, port, protocol |
| L4+ NAT | Socket BPF / TC eBPF | Service load balancing, kube-proxy replacement |
| L7 HTTP | Envoy (cilium-envoy DaemonSet by default) |
HTTP method/path/header filtering, URL regex |
| L7 gRPC | Envoy | gRPC matched as HTTP/2 paths (/package.Service/Method) |
| L7 Kafka | Removed in 1.20 | Use CiliumEnvoyConfig-based alternatives |
| L7 DNS | DNS proxy in the agent | DNS query pattern filtering, toFQDNs IP learning (**. multi-level wildcard since 1.19) |
| TLS | Envoy with stored certs | TLS interception for L7 inspection |
| Runtime | Tetragon (kprobes/tracepoints/LSM) | Process, file, and socket event monitoring and enforcement |
| Encryption | WireGuard / IPsec / ztunnel (beta) | Transparent pod-to-pod and node-to-node encryption |
Cluster Mesh Limits¶
maxConnectedClusters |
Max cluster-local identities | Cluster ID range |
|---|---|---|
| 255 (default) | 65535 | 1-255 |
| 511 | 32767 | 1-511 |
All clusters in a mesh must use the same maxConnectedClusters. It can only be set at install time. Every cluster needs a unique cluster.name and cluster.id. The mesh is one trust domain.
Benchmarks¶
Unsourced performance data
The throughput, scale and resource figures in this section were estimated from vendor documentation, community benchmarks, and engineering judgment. They are not controlled benchmarks with documented hardware, kernel, Cilium version or methodology. Use them as rough guidance only and benchmark your own workload. Official hard limits are in eBPF Map Limits and Cluster Mesh Limits.
eBPF Performance¶
| Feature | Throughput | Latency | Notes |
|---|---|---|---|
| Pod-to-Pod (same node) | 40+ Gbps | 10-20us | eBPF redirect (unverified) |
| Pod-to-Pod (cross node) | 9.5+ Gbps | 50-100us | VXLAN/Geneve (unverified) |
| Service load balancing | 9+ Gbps | 20-50us | Maglev hashing (unverified) |
| kube-proxy replacement | +5-15% vs iptables | -20-40% vs iptables | eBPF socket-level (unverified) |
Scaling Limits¶
| Dimension | Limit | Notes |
|---|---|---|
| Nodes per cluster | 5,000+ | Claimed by Isovalent. Unverified in this pass. Kubernetes itself documents 5,000 nodes |
| Endpoints per node | 64k map capacity | Official endpoint map default. Practical density is far lower (kubelet max-pods) |
| Network policies | 100,000+ | Unverified. The per-endpoint policy map (16k entries) is the real constraint |
| Identities (security) | 65,535 | Cluster-local identities with the default maxConnectedClusters=255 |
Resource Consumption¶
| Cluster Size | Agent CPU | Agent Memory | Operator Memory |
|---|---|---|---|
| < 100 nodes | 100-200m | 256Mi | 128Mi |
| 100-500 nodes | 200-500m | 512Mi | 256Mi |
| 500+ nodes | 500m-1 | 1Gi+ | 512Mi |
Sourcing Status¶
Rows marked "unverified" have no recorded test conditions. Replace them with sourced numbers (for example the official Cilium scalability and performance reports) when available.