CNI 网络插件深度解析:Calico、Cilium 与 Flannel
1. CNI 标准接口
CNI(Container Network Interface)是 Kubernetes 网络插件的标准接口:
1 2 3 4 5 6 7 8 9 10 11 12 13
| kubelet │ │ 调用 CNI 插件 ▼ /opt/cni/bin/<plugin> │ ├── ADD:为 Pod 配置网络 │ - 创建 veth pair │ - 分配 IP 地址 │ - 配置路由 │ - 设置 iptables 规则 │ └── DEL:清理 Pod 网络
|
CNI 配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| { "name": "k8s-pod-network", "cniVersion": "0.3.1", "plugins": [ { "type": "calico", "datastore_type": "kubernetes", "mtu": 1440, "ipam": { "type": "calico-ipam" }, "policy": { "type": "k8s" } }, { "type": "portmap", "capabilities": {"portMappings": true} }, { "type": "bandwidth", "capabilities": {"bandwidth": true} } ] }
|
2. Pod 网络通信原理
2.1 同节点 Pod 通信
1 2 3 4 5 6 7
| Pod A (10.244.1.2) Pod B (10.244.1.3) │ │ eth0 eth0 │ │ veth-a ──────────────────── veth-b │ cni0/cbr0(Linux 网桥)
|
1 2 3 4 5 6 7
| ip link show type veth
brctl show cni0
|
2.2 跨节点 Pod 通信(Overlay 模式)
1 2 3 4 5 6 7 8 9 10 11 12
| Node 1 (10.0.0.1) Node 2 (10.0.0.2) Pod A (10.244.1.2) Pod C (10.244.2.2) │ │ eth0 eth0 │ │ veth veth │ │ cni0 cni0 │ │ flannel.1 (VXLAN) ────────────── flannel.1 (VXLAN) │ │ eth0 (10.0.0.1) eth0 (10.0.0.2)
|
VXLAN 封包:
1 2 3 4
| 外层 UDP 包(节点间) └── VXLAN Header(VNI) └── 内层以太网帧 └── 内层 IP 包(Pod IP)
|
2.3 跨节点 Pod 通信(BGP 模式)
1 2 3 4 5 6 7 8 9
| Node 1 (10.0.0.1) Node 2 (10.0.0.2) Pod A (10.244.1.2) Pod C (10.244.2.2) │ │ eth0 eth0 │ │ 路由表: 路由表: 10.244.2.0/24 via 10.0.0.2 10.244.1.0/24 via 10.0.0.1 │ │ eth0 (10.0.0.1) ────────────────── eth0 (10.0.0.2)
|
BGP 模式无需封包,性能更好,但需要底层网络支持 BGP。
3. Flannel
Flannel 是最简单的 CNI 插件,适合入门和小规模集群:
3.1 工作模式
1 2 3
| VXLAN(默认):Overlay,兼容性好,有封包开销 host-gw:路由模式,性能好,要求节点在同一二层网络 UDP:最慢,已废弃
|
3.2 VXLAN 模式原理
1 2 3 4 5 6 7 8 9 10
| ip link show flannel.1
ip route show | grep flannel
bridge fdb show dev flannel.1
|
3.3 Flannel 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| apiVersion: v1 kind: ConfigMap metadata: name: kube-flannel-cfg namespace: kube-flannel data: net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan", "VNI": 1, "Port": 8472 } }
|
4. Calico
Calico 是生产环境最常用的 CNI 插件,支持 BGP 路由和强大的 NetworkPolicy:
4.1 架构组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ┌─────────────────────────────────────────────────────────┐ │ Calico 组件 │ │ │ │ calico-node(DaemonSet) │ │ ├── Felix:配置 iptables/eBPF 规则,管理路由 │ │ ├── BIRD:BGP 路由守护进程 │ │ └── confd:监听配置变化,更新 BIRD 配置 │ │ │ │ calico-kube-controllers(Deployment) │ │ └── 同步 K8s 资源到 Calico 数据存储 │ │ │ │ Typha(可选,大规模集群) │ │ └── apiserver 和 calico-node 之间的缓存代理 │ └─────────────────────────────────────────────────────────┘
|
4.2 BGP 模式配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| apiVersion: projectcalico.org/v3 kind: BGPConfiguration metadata: name: default spec: logSeverityScreen: Info nodeToNodeMeshEnabled: true asNumber: 64512
---
apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: spine-router spec: peerIP: 192.168.1.1 asNumber: 64513
|
4.3 IP Pool 管理
1 2 3 4 5 6 7 8 9 10 11
| apiVersion: projectcalico.org/v3 kind: IPPool metadata: name: default-ipv4-ippool spec: cidr: 10.244.0.0/16 ipipMode: Never vxlanMode: Never natOutgoing: true nodeSelector: all() blockSize: 26
|
4.4 Calico NetworkPolicy(扩展版)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-frontend-to-backend namespace: production spec: selector: app == 'backend' types: - Ingress - Egress ingress: - action: Allow protocol: TCP source: selector: app == 'frontend' destination: ports: - 8080 egress: - action: Allow protocol: TCP destination: selector: app == 'database' ports: - 5432 - action: Allow protocol: UDP destination: ports: - 53
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: deny-all-default spec: selector: all() types: - Ingress - Egress egress: - action: Allow protocol: UDP destination: ports: - 53
|
5. Cilium(eBPF 驱动)
Cilium 是下一代 CNI 插件,基于 eBPF 技术,性能卓越:
5.1 eBPF 革命
1 2 3 4 5
| 传统方式(iptables): 数据包 → 内核网络栈 → iptables 规则链(数万条)→ 转发
eBPF 方式(Cilium): 数据包 → eBPF 程序(内核态,哈希表查找)→ 直接转发
|
性能对比:
- iptables:O(n) 规则匹配,大规模集群延迟高
- eBPF:O(1) 哈希表查找,性能不随规模下降
5.2 Cilium 架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌─────────────────────────────────────────────────────────┐ │ Cilium 组件 │ │ │ │ cilium-agent(DaemonSet) │ │ ├── 管理 eBPF 程序(加载到内核) │ │ ├── 维护 eBPF Map(策略、路由、连接跟踪) │ │ └── 与 Kubernetes API 同步 │ │ │ │ cilium-operator(Deployment) │ │ └── 集群级别操作(IP 分配、CRD 管理) │ │ │ │ Hubble(可观测性) │ │ ├── hubble-relay:聚合各节点数据 │ │ └── hubble-ui:可视化网络流量 │ └─────────────────────────────────────────────────────────┘
|
5.3 Cilium 安装
1 2 3 4 5 6 7 8 9
| helm repo add cilium https://helm.cilium.io/ helm install cilium cilium/cilium \ --namespace kube-system \ --set kubeProxyReplacement=true \ --set k8sServiceHost=10.0.0.1 \ --set k8sServicePort=6443 \ --set hubble.relay.enabled=true \ --set hubble.ui.enabled=true
|
5.4 Cilium NetworkPolicy(L7 策略)
Cilium 支持 L7(应用层) 网络策略,这是 iptables 无法实现的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| apiVersion: "cilium.io/v2" kind: CiliumNetworkPolicy metadata: name: l7-policy spec: endpointSelector: matchLabels: app: backend ingress: - fromEndpoints: - matchLabels: app: frontend toPorts: - ports: - port: "80" protocol: TCP rules: http: - method: "GET" path: "/api/.*" - method: "POST" path: "/api/data" headers: - 'X-Token: .*'
|
5.5 Hubble 网络可观测性
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| cilium hubble enable
hubble observe --follow
hubble observe --pod production/frontend --follow
hubble observe --verdict DROPPED
hubble observe --protocol DNS
|
5.6 Cilium 替代 kube-proxy
1 2 3 4 5 6
| cilium status | grep KubeProxyReplacement
cilium service list
|
6. 网络插件对比
| 特性 |
Flannel |
Calico |
Cilium |
| 实现方式 |
VXLAN/host-gw |
BGP/VXLAN/eBPF |
eBPF |
| 性能 |
中 |
高(BGP) |
最高 |
| NetworkPolicy |
不支持 |
支持(L3/L4) |
支持(L3/L4/L7) |
| 可观测性 |
无 |
基础 |
Hubble(强大) |
| 复杂度 |
低 |
中 |
高 |
| 适用场景 |
小规模/测试 |
生产通用 |
大规模/高性能 |
| kube-proxy 替代 |
否 |
否 |
是 |
7. 网络排查工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| kubectl exec -it <pod> -- ip addr kubectl exec -it <pod> -- ip route kubectl exec -it <pod> -- cat /etc/resolv.conf
kubectl exec -it pod-a -- ping 10.244.1.3 kubectl exec -it pod-a -- curl http://pod-b-service
kubectl exec -it <pod> -- tcpdump -i eth0 -n
kubectl run netshoot --image=nicolaka/netshoot --rm -it -- bash
ip route show table all | grep 10.244
iptables -t nat -L -n -v | grep <service-ip>
cilium bpf lb list cilium bpf policy get <endpoint-id>
|
8. 总结
CNI 网络插件的选择:
- Flannel:简单易用,适合学习和小规模集群
- Calico:生产首选,BGP 路由性能好,NetworkPolicy 强大
- Cilium:下一代方案,eBPF 驱动,L7 策略,内置可观测性
趋势:eBPF 正在成为 Kubernetes 网络的未来,Cilium 在大规模生产环境中的采用率快速增长。