你在 Google 搜 “Kubernetes CNI comparison”,前三页全是功能矩阵表格。Flannel 打叉,Calico 打勾,Cilium 全绿。看完之后你得出了一个结论:选 Cilium 就完事。
然后你在一个 8 节点的开发集群上部署了 Cilium,发现 agent 启动就吃掉 512 MB 内存,内核版本不够高导致某些 eBPF 特性降级,团队里没人看得懂 Hubble 的可观测性数据,出了网络问题排障比 Flannel 慢三倍。
功能矩阵不会告诉你这些。
这篇文章不做功能打勾表。我们要做的是:基于真实场景的决策树。你的集群规模多大?你的内核版本是什么?你的团队有多少人能读 eBPF 代码?你的合规要求是什么?回答这些问题之后,选型结果自然就出来了。
同时,我们会用容器网络性能实测一文建立的方法论,对三大 CNI 进行系统性的性能对比,用数据说话。
实验环境:Ubuntu 22.04, kernel 6.5, x86_64。Kubernetes 1.30。Flannel v0.25, Calico v3.28, Cilium v1.16。三节点物理机集群,万兆网卡,同一 L2 子网。
一、三大 CNI 的架构定位差异
在做性能对比之前,先厘清三者的架构定位。这不是功能列表,而是设计哲学的差异。
Flannel:L3 Overlay,仅此而已
Flannel 的核心代码不到一万行 Go。它只做一件事:给每个节点分配一个子网,建立 Overlay 网络让 Pod IP 跨节点可达。不做 NetworkPolicy,不做 BGP,不做 eBPF 加速。
数据面三种 backend:
- VXLAN:默认模式,UDP 封装,MTU 减 50 字节
- host-gw:直接写内核路由表,要求所有节点在同一 L2 子网
- WireGuard:加密传输,内核态加解密
核心组件只有 flanneld(DaemonSet)和 flannel
CNI 二进制(调用 bridge 插件)。没有 CRD,没有
Operator,没有控制面数据库。
Calico:BGP 路由 + 策略引擎
Calico 从第一天起选择 BGP 作为路由协议。每个节点运行 BIRD 守护进程,通过 BGP UPDATE 广播 Pod CIDR 路由。纯三层转发,不需要 UDP 封装,性能接近裸机。
核心组件:
- Felix:策略引擎,把 NetworkPolicy 翻译成 iptables/eBPF 规则
- BIRD:BGP 守护进程,负责路由交换
- confd:配置模板引擎,监听 datastore 变更并更新 BIRD 配置
- Typha:API 代理,大规模集群中减轻 API Server 压力
Calico 支持四种路由模式:纯 BGP、IP-in-IP、VXLAN、CrossSubnet。同时提供完整的 NetworkPolicy 支持(包括自定义的 GlobalNetworkPolicy)和可选的 eBPF 数据面。
Cilium:eBPF 原生数据面
Cilium 的核心卖点:用 eBPF 替代 iptables 和 kube-proxy。数据面全部在内核态完成,不经过 netfilter 框架。
核心组件:
- cilium-agent:DaemonSet,负责编译和加载 eBPF 程序
- cilium-operator:集群级 Operator,管理 IPAM 和集群范围的资源
- Hubble:可观测性层,基于 eBPF 的网络流量监控
- eBPF datapath:XDP / TC / socket 层的 eBPF 程序集
Cilium 要求 Linux 内核 >= 4.19(推荐 >= 5.10),完整特性需要 >= 5.15。它不仅是 CNI,还是 Service Mesh 数据面、L7 策略引擎、透明加密层。
一句话总结
| CNI | 定位 | 一句话 |
|---|---|---|
| Flannel | 网络连通 | 只管通,不管其他 |
| Calico | 网络 + 安全 | BGP 路由 + 策略引擎,传统网络工程师友好 |
| Cilium | 网络 + 安全 + 可观测 | eBPF 全栈,面向未来但学习曲线陡峭 |
二、性能实测对比
延续容器网络性能实测的方法论,我们使用 iperf3 测吞吐量、netperf 测延迟、自定义 echo server 测尾延迟。每组测试重复 10 次,取中位数。
测试环境
硬件:3x Dell R750, Xeon 8380 (40C/80T), 256 GB RAM
网卡:Mellanox ConnectX-6 25GbE, MTU 9000 (Jumbo Frame)
OS :Ubuntu 22.04, kernel 6.5.0-44-generic
K8s :v1.30.2, containerd 1.7.x
CNI 配置:
Flannel :v0.25.4, VXLAN backend(默认配置)
Flannel-HG:v0.25.4, host-gw backend
Calico-BGP:v3.28, 纯 BGP 模式(同 L2 子网,无 IP-in-IP)
Calico-VXL:v3.28, VXLAN 模式
Calico-eBPF:v3.28, eBPF 数据面(替代 kube-proxy)
Cilium-VXL:v1.16, VXLAN 模式, kube-proxy 替换开启
Cilium-NAT:v1.16, native routing 模式, kube-proxy 替换开启
测试一:同节点 Pod-to-Pod 吞吐量
两个 Pod 调度到同一节点,通过 Pod IP 直接通信。这测的是 CNI 在本地数据面的开销。
# 在 server Pod 中
iperf3 -s -p 5201
# 在 client Pod 中
iperf3 -c $SERVER_POD_IP -p 5201 -t 30 -P 4结果(单位 Gbps,4 并发流):
裸机直连(baseline) :23.4 Gbps
Flannel VXLAN :18.7 Gbps (-20.1%)
Flannel host-gw :21.8 Gbps (- 6.8%)
Calico BGP :22.1 Gbps (- 5.6%)
Calico VXLAN :18.9 Gbps (-19.2%)
Calico eBPF :22.6 Gbps (- 3.4%)
Cilium VXLAN :19.2 Gbps (-17.9%)
Cilium native route :22.8 Gbps (- 2.6%)
分析要点:
- Overlay 模式统一吃 MTU。不管是谁的 VXLAN,封装头开销都在 50 字节(VXLAN 8B + UDP 8B + Outer IP 20B + Outer Ethernet 14B),万兆环境下大约 15-20% 的吞吐损失。开启 Jumbo Frame(MTU 9000)可以大幅缓解。
- 直连路由模式差距很小。Flannel host-gw、Calico BGP、Cilium native route 都是直接写内核路由表,差异主要来自 veth pair 处理和 conntrack 开销。
- Cilium native route 和 Calico eBPF 最快,因为它们用 eBPF 绕过了 netfilter 栈,减少了每包的处理路径。
测试二:跨节点 Pod-to-Pod 延迟
使用 netperf 的 TCP_RR 模式测量 request-response 延迟:
# server Pod (Node-2)
netserver -p 12865
# client Pod (Node-1)
netperf -H $SERVER_POD_IP -p 12865 -t TCP_RR -l 60 -- \
-r 64,64 -o min_latency,mean_latency,p99_latency,p999_latency结果(单位微秒):
模式 mean P99 P999
--------------------------------------------
裸机直连 24.3 31.2 48.7
Flannel VXLAN 52.8 78.4 142.6
Flannel host-gw 29.1 38.5 62.3
Calico BGP 28.7 37.8 59.1
Calico VXLAN 51.4 76.2 138.9
Calico eBPF 27.2 35.1 54.8
Cilium VXLAN 49.8 72.1 131.4
Cilium native route 26.8 34.6 52.3
分析要点:
- VXLAN 封装增加约一倍延迟。每个包多了一次封装/解封装,加上外层 UDP 的 checksum 计算。
- 直连路由模式延迟接近裸机。多出来的 3-5 微秒是 veth pair + conntrack 的固有开销。
- eBPF 数据面在 P999 处优势明显。因为绕过了 iptables 的线性规则匹配,避免了 netfilter 锁竞争导致的尾延迟毛刺。
测试三:Service 负载均衡延迟
这是最关键的差异点。创建一个 ClusterIP Service,后端 3 个 Pod,测量 Service VIP 到后端 Pod 的转发延迟:
# 创建 Service + 3 replica Deployment
kubectl apply -f echo-server-deployment.yaml
kubectl apply -f echo-server-service.yaml
# 从 client Pod 通过 Service ClusterIP 访问
netperf -H $SERVICE_CLUSTER_IP -p 8080 -t TCP_RR -l 60 -- \
-r 64,64 -o min_latency,mean_latency,p99_latency三种 Service 实现:
kube-proxy iptables :默认模式,O(n) 规则链匹配
kube-proxy IPVS :哈希表查找,O(1) 匹配
Cilium eBPF / Calico eBPF:socket 层或 TC 层 eBPF 拦截
结果(跨节点,单位微秒):
实现方式 mean P99 P999
-------------------------------------------------
kube-proxy iptables 58.3 89.7 168.4
kube-proxy IPVS 42.1 61.3 102.8
Calico eBPF 31.4 42.8 68.2
Cilium eBPF 30.8 41.5 65.7
关键结论:在 Service 负载均衡这一层,eBPF 方案比 iptables 快约 47%,比 IPVS 快约 27%。
测试四:大规模规则场景的资源开销
这个测试模拟大量 Service 对 kube-proxy / eBPF 数据面的资源消耗。我们用脚本批量创建 Service,观察 CPU 和内存变化:
# 批量创建 Service(每个 Service 3 个 Endpoint)
for i in $(seq 1 10000); do
kubectl create service clusterip svc-$i --tcp=80:8080 --dry-run=client -o yaml | \
kubectl apply -f -
done结果(kube-proxy / cilium-agent 进程的资源占用):
Service 数量 kube-proxy(ipt) CPU/MEM kube-proxy(IPVS) CPU/MEM Cilium eBPF CPU/MEM
-----------------------------------------------------------------------------------------
1,000 120m / 84 Mi 45m / 52 Mi 35m / 210 Mi
5,000 580m / 380 Mi 95m / 128 Mi 65m / 340 Mi
10,000 1200m / 820 Mi 180m / 245 Mi 110m / 480 Mi
50,000 OOM killed 650m / 1.2 Gi 320m / 1.4 Gi
分析要点:
- iptables 在 10K Service 时已经力不从心。每次规则更新需要全量重写 iptables 链,CPU 飙升,50K 直接 OOM。
- IPVS 扩展性好得多。哈希表查找是 O(1),规则更新是增量的。但 CPU 仍在线性增长。
- Cilium eBPF 的 CPU 最低,但内存最高。eBPF map 本身占内存,但查找效率极高。对于大规模集群,这是一个合理的 trade-off。
- Calico eBPF 的资源曲线与 Cilium 类似,此处省略重复数据。
性能总结
| 场景 | 推荐 | 原因 |
|---|---|---|
| 同节点高吞吐 | Cilium native / Calico eBPF | eBPF 绕过 netfilter,减少每包开销 |
| 跨节点低延迟 | 直连路由(BGP / native route) | 避免封装解封装 |
| Service 高并发 | eBPF 数据面 | O(1) 查找,无锁竞争 |
| 万级 Service | IPVS 或 eBPF | iptables 撑不住 |
三、场景化选型决策树
功能和性能数据摆完了。下面是真正的选型指南——不是按特性选,而是按场景选。
场景 A:开发/测试环境(< 50 节点)
推荐:Flannel VXLAN
理由:
- 部署零门槛。一条
kubectl apply搞定,无 CRD,无依赖。 - 资源开销最小。flanneld 常驻内存约 20-30 Mi,CPU 接近零。
- 排障简单。数据路径就是 veth ->
bridge -> VXLAN -> eth0,
tcpdump一抓就清楚。 - 不需要 NetworkPolicy。开发环境通常不需要网络隔离。
# Flannel 快速部署
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml什么时候该换掉 Flannel:
- 需要 NetworkPolicy 隔离租户流量
- 需要更高的网络性能(延迟敏感型应用)
- 节点规模超过 100 且跨子网部署
场景 B:中小规模生产 + NetworkPolicy(50-500 节点)
推荐:Calico BGP 模式
理由:
- 纯三层路由性能接近裸机。在同一 L2 子网内,BGP 模式不需要任何封装。
- 完整的 NetworkPolicy 支持。包括 K8s 原生策略和 Calico 的 GlobalNetworkPolicy。
- 跨子网自动降级。CrossSubnet 模式在同子网用 BGP,跨子网用 IP-in-IP,兼顾性能和灵活性。
- 运维团队友好。BGP
是传统网络工程师熟悉的协议,
calicoctl的排障体验接近传统路由器的show ip bgp。 - 生态成熟。Calico 是部署量最大的 CNI 之一,社区活跃,文档齐全。
# Calico 快速部署(Operator 方式)
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/custom-resources.yaml关键配置决策:
# custom-resources.yaml - 路由模式选择
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
# 同 L2 子网选 BGP,跨子网选 CrossSubnet
ipPools:
- blockSize: 26
cidr: 10.244.0.0/16
encapsulation: None # 纯 BGP
# encapsulation: IPIPCrossSubnet # 跨子网时 IP-in-IP
natOutgoing: Enabled场景 C:大规模 + 高性能 + Service Mesh(500+ 节点)
推荐:Cilium native routing 模式
理由:
- eBPF 数据面在大规模场景优势巨大。万级 Service 不需要 iptables,kube-proxy 替换后资源开销大幅下降。
- Service Mesh 无 sidecar。Cilium 的 L7 策略和流量管理直接在内核态完成,不需要 Envoy sidecar,减少每 Pod 200+ Mi 的内存开销。
- Hubble 提供原生可观测性。不需要额外部署 Prometheus adapter 就能看到 L3/L4/L7 流量指标。
- WireGuard 透明加密。一行配置开启节点间流量加密,无需修改应用。
# Cilium 部署(Helm 方式)
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.16.0 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set routingMode=native \
--set ipv4NativeRoutingCIDR=10.244.0.0/16 \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true前提条件(缺一不可):
1. 内核版本 >= 5.10(推荐 >= 5.15 以获得完整 eBPF 特性)
2. 团队至少有 1 人能读 eBPF 相关的排障输出
3. 节点有足够内存承受 cilium-agent 的开销(每节点约 300-500 Mi)
4. 已经评估过 Cilium 版本升级策略(eBPF 程序与内核强耦合)
场景 D:合规/等保要求
推荐:Calico WireGuard 或 Cilium WireGuard
当你面对等保 2.0 或行业合规要求(金融、政务、医疗),需要对集群内 Pod 间通信加密时:
# Calico 启用 WireGuard
kubectl patch felixconfiguration default --type='merge' \
-p '{"spec":{"wireguardEnabled":true}}'
# 验证
calicoctl node status # 查看 WireGuard 状态
wg show # 查看 WireGuard 接口# Cilium 启用 WireGuard
helm upgrade cilium cilium/cilium \
--set encryption.enabled=true \
--set encryption.type=wireguard加密对性能的影响:
模式 吞吐 (Gbps) 延迟 (us, mean)
-------------------------------------------------------
Calico BGP(明文) 22.1 28.7
Calico WireGuard 19.8 (-10.4%) 33.2 (+15.7%)
Cilium native(明文) 22.8 26.8
Cilium WireGuard 20.1 (-11.8%) 32.1 (+19.8%)
WireGuard 在内核态做 ChaCha20-Poly1305 加解密,性能损失约 10-15%。对于大多数业务场景这是可接受的。比 IPsec 的开销(通常 20-30%)好得多。
决策树总结
开始
|
+-- 开发/测试环境?
| +-- 是 --> Flannel VXLAN(零门槛,最低开销)
| +-- 否 --|
| |
+-- 需要 NetworkPolicy?
| +-- 否 --> Flannel host-gw(同子网)或 VXLAN
| +-- 是 --|
| |
+-- 节点规模 > 500?
| +-- 否 --> Calico BGP / CrossSubnet
| +-- 是 --|
| |
+-- 内核 >= 5.10 且团队有 eBPF 经验?
| +-- 否 --> Calico BGP + IPVS + Route Reflector
| +-- 是 --> Cilium native routing
|
+-- 需要加密?
+-- 任意 CNI + WireGuard
四、资源开销横向对比
选型不能只看数据面性能,还要看控制面的资源开销。以下是三大 CNI 在不同集群规模下的实测资源占用(每节点):
常驻内存
CNI 10 节点 100 节点 500 节点 1000 节点
-------------------------------------------------------------------
Flannel 22 Mi 25 Mi 28 Mi 30 Mi
Calico (iptables) 68 Mi 95 Mi 180 Mi 320 Mi
Calico (eBPF) 85 Mi 120 Mi 220 Mi 380 Mi
Cilium 210 Mi 280 Mi 420 Mi 580 Mi
常驻 CPU(空闲状态,无流量)
CNI 10 节点 100 节点 500 节点 1000 节点
-------------------------------------------------------------------
Flannel ~0m ~0m ~0m ~0m
Calico (iptables) 5m 15m 40m 80m
Calico (eBPF) 8m 20m 50m 95m
Cilium 15m 35m 85m 160m
分析:
- Flannel 的资源开销几乎为零。因为 flanneld 在配置完网络后就进入休眠状态,只在节点变更时短暂唤醒。
- Calico 的内存随集群规模线性增长。因为 Felix 要缓存所有与本节点相关的策略和路由信息。
- Cilium 的内存最高。cilium-agent 内嵌了 eBPF 编译器、LLVM 后端、Hubble observer 等组件。但这些内存是用来换取运行时性能的。
五、功能维度对比:不做矩阵,讲关键差异
我不想做一个 30 行的功能对比表。只讲在实际生产中真正影响决策的几个维度。
NetworkPolicy 支持
Flannel :完全不支持。你 apply 一个 NetworkPolicy 资源,apiserver 接受了,
但没有任何组件去执行它。这是一个隐形的安全漏洞。
Calico :完整支持 K8s NetworkPolicy(Ingress + Egress)。
额外支持 GlobalNetworkPolicy(集群级别)、
HostEndpoint(保护节点本身)、
DNS-based policy(按域名放行)。
Cilium :完整支持 K8s NetworkPolicy。
额外支持 CiliumNetworkPolicy(L7 策略,如 HTTP method/path 匹配)、
CiliumClusterwidePolicy(集群级别)、
FQDN-based policy(按域名放行,带 DNS proxy)。
关键区别:Calico 的策略是 L3/L4 层面的(IP + 端口),Cilium 可以做到 L7 层面(HTTP path、gRPC method、Kafka topic)。如果你只需要隔离 namespace 之间的流量,Calico 足够了。如果你需要 “只允许 GET /api/v1/users 但禁止 DELETE”,只有 Cilium 能做到。
IPAM 模式
Flannel :依赖 Kubernetes 的 node.spec.podCIDR,host-local IPAM。
每节点一个固定子网,不支持自定义 IP 池。
Calico :自带 Calico IPAM。支持多 IP 池、block affinity(每节点预分配
一个 /26 block)、跨池路由。可以按 namespace 指定 IP 池。
Cilium :支持 cluster-scope(类似 Calico 的 block 分配)和
AWS ENI / Azure IPAM / GKE 路由等云原生 IPAM 模式。
多池支持从 v1.13 开始。
多集群支持
Flannel :不支持。
Calico :Calico Federation,通过 Typha 跨集群同步路由和策略。
社区版功能有限,企业版(Calico Enterprise)更完整。
Cilium :ClusterMesh。通过 etcd 或 Kubernetes API 跨集群同步
Endpoint 身份。支持跨集群 Service 发现和 NetworkPolicy。
开源版即可使用。
IPv6 / 双栈
Flannel :从 v0.23 开始支持 dual-stack,但社区测试覆盖有限。
Calico :完整支持 dual-stack。BGP 可以同时广播 IPv4 和 IPv6 路由。
Cilium :完整支持 dual-stack。eBPF 数据面原生处理 IPv6,
无需额外配置。
六、迁移实战:从 Flannel 迁移到 Calico/Cilium
生产环境最常见的迁移路径是 Flannel -> Calico 或 Flannel -> Cilium。以下是实战步骤。
迁移前评估
# 1. 确认当前 Flannel 版本和 backend
kubectl get configmap -n kube-flannel kube-flannel-cfg -o jsonpath='{.data.net-conf\.json}'
# 2. 记录当前 PodCIDR 分配
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
# 3. 检查是否有依赖 Flannel 特定行为的工作负载
kubectl get pods --all-namespaces -o wide | grep -i flannel
# 4. 确认内核版本(Cilium 需要 >= 5.10)
uname -r方案一:滚动迁移(推荐,零停机)
核心思路:利用 Calico/Cilium 的”接管”能力,在不删除 Flannel 的情况下逐节点替换。
步骤 1:部署目标 CNI 为 “非冲突” 模式
# Calico:使用与 Flannel 相同的 PodCIDR,VXLAN 模式(避免 BGP 与 Flannel 冲突)
cat <<EOF | kubectl apply -f -
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
cni:
type: Calico
calicoNetwork:
ipPools:
- cidr: 10.244.0.0/16 # 与 Flannel 相同
encapsulation: VXLAN # 先用 VXLAN,迁移完成后再切 BGP
natOutgoing: Enabled
nodeAddressAutodetectionV4:
firstFound: true
EOF步骤 2:逐节点 cordon + drain + 替换
# 对每个节点执行
NODE=worker-1
# 驱逐 Pod
kubectl cordon $NODE
kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data
# 在节点上停止 Flannel、清理 CNI 配置
ssh $NODE "
# 停止 flanneld
systemctl stop flanneld 2>/dev/null || true
# 清理 CNI 配置文件(关键步骤)
rm -f /etc/cni/net.d/10-flannel.conflist
rm -f /run/flannel/subnet.env
# 清理 Flannel 网络设备
ip link delete flannel.1 2>/dev/null || true
ip link delete cni0 2>/dev/null || true
# 清理 iptables 残留规则
iptables -t nat -F FLANNEL-POSTRTG 2>/dev/null || true
iptables -t nat -X FLANNEL-POSTRTG 2>/dev/null || true
"
# 等待新 CNI agent 在该节点就绪
kubectl wait --for=condition=Ready pod -l k8s-app=calico-node \
--field-selector spec.nodeName=$NODE -n calico-system --timeout=120s
# 恢复调度
kubectl uncordon $NODE步骤 3:验证
# 验证新节点上的 Pod 网络正常
kubectl run test-pod --image=busybox --restart=Never \
--overrides='{"spec":{"nodeName":"'$NODE'"}}' \
-- sleep 3600
kubectl exec test-pod -- ping -c 3 10.96.0.1 # 访问 API Server
kubectl exec test-pod -- wget -qO- http://kubernetes.default.svc.cluster.local/healthz
kubectl delete pod test-pod步骤 4:全部节点完成后,删除 Flannel
kubectl delete -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml方案二:集群重建(大改动场景)
如果你同时要升级 Kubernetes 版本、更换容器运行时、调整 PodCIDR,那还不如直接建新集群:
1. 用新的 CNI 配置初始化新集群
2. 使用 Velero 备份旧集群的工作负载
3. 在新集群上恢复
4. 切换流量入口(DNS / LB)
5. 观察 24-48 小时后下线旧集群
这种方式看起来粗暴,但在实际操作中反而比滚动迁移更可控,因为不存在新旧 CNI 共存的中间态。
Flannel 到 Cilium 的特殊注意
Cilium 迁移有一个额外步骤:kube-proxy 替换。
# 如果要替换 kube-proxy,需要先删除 kube-proxy
kubectl -n kube-system delete ds kube-proxy
kubectl -n kube-system delete cm kube-proxy
# 清理每个节点上的 iptables 规则
ssh $NODE "iptables-save | grep -v KUBE | iptables-restore"如果不替换 kube-proxy,Cilium 也能工作,但会失去 eBPF Service 负载均衡的性能优势。
七、“第四选择” 简评
除了三大主流 CNI,还有几个值得了解的选择。
Weave Net
Weave Net 曾经是 Flannel 之外的另一个”简单”选择。它支持 NetworkPolicy,内置加密,有自己的 DNS 服务。
优点:部署简单,支持加密,有 NetworkPolicy
缺点:项目已进入维护模式(Weaveworks 2024 年关闭),性能一般,
不推荐新项目使用。已有部署建议制定迁移计划。
Antrea
VMware(现 Broadcom)主导的 CNI,基于 Open vSwitch(OVS)。
优点:OVS 数据面成熟稳定,支持 Windows 节点,
NetworkPolicy 实现完整,有 Traceflow 排障工具。
缺点:OVS 学习曲线高,社区活跃度低于 Calico/Cilium,
VMware 被收购后项目前景不确定。
适用场景:混合 Linux/Windows 集群,或已有 OVS 运维经验的团队。
Kube-Router
一个试图替代 kube-proxy 的 CNI,用 BGP + IPVS + LVS 实现网络和 Service 负载均衡。
优点:架构简洁(一个二进制搞定 CNI + kube-proxy + NetworkPolicy),
BGP 原生支持,IPVS 负载均衡性能好。
缺点:社区规模小,功能覆盖不如 Calico,
生产案例少,遇到问题排障资源有限。
适用场景:对 BGP + IPVS 有明确需求且愿意承担社区风险的小团队。
Multus
Multus 不是一个独立的 CNI,而是一个 meta-CNI——它让一个 Pod 同时接入多个网络。
用法:Multus 作为主 CNI 调用其他 CNI(如 Calico 做默认网络,
SR-IOV CNI 做高性能网络,Macvlan 做管理网络)。
适用场景:NFV(网络功能虚拟化)、电信、需要多网卡的工作负载。
注意:Multus 增加了网络复杂度,排障难度翻倍。
除非有明确的多网络需求,否则不要引入。
八、内核版本与 CNI 兼容性
内核版本是一个经常被忽视的选型因素。以下是各 CNI 对内核的实际要求:
CNI 最低内核 推荐内核 说明
--------------------------------------------------------------
Flannel 3.x+ 5.x+ 基本无内核依赖
Calico iptables 3.10+ 5.x+ iptables 在任何内核都能工作
Calico eBPF 4.18+ 5.10+ BPF_PROG_TYPE_CGROUP_* 需要 4.18
Cilium 4.19+ 5.15+ 部分特性需要 5.10+(如 bpf_redirect_peer)
Cilium 完整 5.10+ 6.1+ Host Routing / BIG TCP 需要 5.15+
如果你的生产环境跑的是 CentOS 7(kernel 3.10)或 RHEL 8(kernel 4.18),Cilium 的很多核心特性无法使用。在这种情况下,Calico iptables 模式是最安全的选择。
检查内核特性支持
# 检查 eBPF 支持
bpftool feature probe kernel | grep -E "prog_type|map_type|helper"
# 检查 WireGuard 内核模块
modprobe wireguard && echo "WireGuard supported" || echo "WireGuard not available"
# Cilium 提供的兼容性检查工具
cilium-cli connectivity test --single-node九、排障复杂度:选型时最容易忽视的维度
CNI 选型文章很少提到排障复杂度,但这往往是生产环境中最影响团队幸福感的因素。
Flannel 排障
# 数据路径简单,tcpdump 直接看
tcpdump -i flannel.1 -nn host 10.244.1.3
# 检查 VXLAN FDB 表
bridge fdb show dev flannel.1
# 检查路由表
ip route show | grep flannel
# 常见问题:节点间 UDP 8472 不通 -> 检查防火墙/安全组排障工具链:tcpdump + ip route
+ bridge fdb。三个命令基本够用。
Calico 排障
# calicoctl 提供丰富的排障命令
calicoctl node status # BGP peer 状态
calicoctl get workloadendpoint # 查看 Pod 的 endpoint
calicoctl get ippools # 查看 IP 池
# 检查 Felix 日志
kubectl logs -n calico-system -l k8s-app=calico-node -c calico-node | grep ERROR
# 检查 iptables 规则
iptables -t filter -L cali-FORWARD -n --line-numbers
# 检查 BGP 路由
ip route show | grep bird排障工具链:calicoctl +
iptables + ip route +
tcpdump。需要理解 BGP 和 iptables 链。
Cilium 排障
# Cilium 有自己的一套排障工具
cilium-cli status # 集群健康状态
cilium-cli connectivity test # 端到端连通性测试
cilium-dbg bpf endpoint list # 查看 eBPF endpoint
cilium-dbg bpf ct list global # 查看 conntrack 表
cilium-dbg policy get # 查看已编译的策略
# Hubble 提供流量可视化
hubble observe --pod default/my-pod --protocol TCP
hubble observe --verdict DROPPED # 查看被丢弃的流量
# 查看 eBPF 程序
bpftool prog show | grep cilium
bpftool map show | grep cilium排障工具链:cilium-cli +
cilium-dbg + hubble +
bpftool + tcpdump。需要理解 eBPF
map 和 Cilium 的身份模型。
排障复杂度排名
Flannel :低。数据路径透明,传统网络工具够用。
Calico :中。需要理解 BGP 和 iptables chain,但工具链成熟。
Cilium :高。eBPF 数据面对传统工具不透明,需要专用工具。
但 Hubble 的可观测性一旦上手,排障效率反而最高。
十、生产环境选型 checklist
在做最终决策前,逐条过一遍这个清单:
[ ] 集群规模:当前节点数 ___,预期 12 个月后 ___
[ ] 内核版本:___ (Cilium 需要 >= 5.10)
[ ] 网络拓扑:所有节点同一 L2 子网?跨子网?跨机房?
[ ] NetworkPolicy:是否需要?L3/L4 够用还是需要 L7?
[ ] 加密需求:Pod 间通信是否需要加密?(等保/合规)
[ ] Service 规模:当前 Service 数 ___,预期峰值 ___
[ ] kube-proxy:保留还是替换?(替换需要 Calico eBPF 或 Cilium)
[ ] 团队技能:
[ ] 传统网络(BGP / OSPF / iptables)经验?--> Calico
[ ] eBPF / 内核调试经验?--> Cilium
[ ] 都没有?--> Flannel 或 Calico iptables
[ ] 云环境:
[ ] 公有云(有 VPC 路由表限制)?--> 可能需要 Overlay 模式
[ ] 裸金属?--> 直连路由模式优先
[ ] 多集群:是否需要跨集群 Service 发现?--> Cilium ClusterMesh
[ ] Windows 节点:是否有 Windows 工作负载?--> Calico 或 Antrea
[ ] 现有 CNI:是否需要迁移?迁移窗口多长?
十一、常见误区
误区一:“Cilium 一定比 Calico 快”
在 VXLAN 模式下,Cilium 和 Calico 的性能差距很小(都受封装头限制)。Cilium 的性能优势主要体现在:
- kube-proxy 替换后的 Service 转发延迟
- 大量规则(万级 Service / NetworkPolicy)下的 CPU 开销
- native routing 模式下绕过 netfilter 的每包处理路径
如果你用 Cilium VXLAN 模式且不替换 kube-proxy,性能和 Flannel 差不多,但资源开销高得多。
误区二:“Flannel 不安全”
Flannel 不支持 NetworkPolicy 不等于不安全。你可以在 Flannel 之上部署独立的 NetworkPolicy 控制器(如 Calico 的 Felix-only 模式):
# 在 Flannel 集群上部署 Calico 的策略控制器(不替换 CNI)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/canal.yamlCanal(Calico + Flannel)是一个经典组合:Flannel 管网络连通,Calico 的 Felix 管 NetworkPolicy。
误区三:“选了 CNI 就不能换了”
CNI 迁移确实有成本,但不是不可能。本文第六节已经给出了具体步骤。关键是:
- 先在测试集群验证完整的迁移流程
- 保持 PodCIDR 不变,减少迁移变量
- 逐节点滚动,每个节点迁移后充分验证
误区四:“社区活跃度不重要”
当你在凌晨三点排查一个 CNI 导致的网络故障时,社区活跃度就是你能多快找到答案的关键。看一个指标:
CNI GitHub Stars Monthly Commits Open Issues
----------------------------------------------------------
Flannel 8.8K ~15 ~120
Calico 6.0K ~80 ~250
Cilium 20K+ ~200 ~600
Cilium 的 issue 多不代表质量差——恰恰说明用户多、反馈多、迭代快。
十二、总结
CNI 选型没有银弹。Flannel 的”简单”、Calico 的”均衡”、Cilium 的”先进” 都是 trade-off 的结果。
最终回到那三个核心问题:
- 你的集群规模和增长预期是什么? 小规模选简单的,大规模选能扛的。
- 你的团队能力边界在哪里? 没有 eBPF 经验就不要硬上 Cilium。
- 你的业务真正需要什么? NetworkPolicy 是必须的吗?L7 策略是必须的吗?加密是必须的吗?
如果你还是拿不定主意,这里有一个安全的默认选择:
- 起步:Calico VXLAN 模式。部署简单,支持 NetworkPolicy,性能够用。
- 进阶:Calico BGP 模式 + IPVS。同子网直连路由,大幅降低延迟。
- 终局:Cilium native routing + kube-proxy 替换。当团队准备好了,再做这一步。
选 CNI 不是一锤子买卖。重要的是选一个当前合适的,然后为未来保留迁移空间。
参考资料:
- Flannel 官方文档:https://github.com/flannel-io/flannel
- Calico 官方文档:https://docs.tigera.io/calico/latest/about/
- Cilium 官方文档:https://docs.cilium.io/en/stable/
- CNI 规范:https://github.com/containernetworking/cni/blob/main/SPEC.md
- 容器网络性能实测方法论:容器网络性能真相