CNI 网络插件深度解析:Calico、Cilium 与 Flannel

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
// /etc/cni/net.d/10-calico.conflist
{
"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
# 查看 veth pair
ip link show type veth

# 查看网桥
brctl show cni0
# bridge name bridge id STP enabled interfaces
# cni0 8000.xxx no veth-a veth-b

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
# Flannel 在每个节点创建 flannel.1 接口
ip link show flannel.1

# 查看 Flannel 路由
ip route show | grep flannel
# 10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink

# 查看 ARP 表(VXLAN FDB)
bridge fdb show dev flannel.1
# 5e:f8:4f:00:e3:37 dst 10.0.0.2 self permanent

3.3 Flannel 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Flannel ConfigMap
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
# Calico BGP 配置
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
logSeverityScreen: Info
nodeToNodeMeshEnabled: true # 节点间全互联 BGP
asNumber: 64512 # AS 号

---
# BGP Peer(对接物理路由器)
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 # 不使用 IPIP 封装(BGP 模式)
vxlanMode: Never
natOutgoing: true # 出集群流量做 SNAT
nodeSelector: all()
blockSize: 26 # 每个节点分配 /26(64 个 IP)

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
# Calico 扩展的 NetworkPolicy(比 K8s 原生更强大)
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 # DNS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# GlobalNetworkPolicy(跨命名空间)
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 安装 Cilium
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium \
--namespace kube-system \
--set kubeProxyReplacement=true \ # 完全替代 kube-proxy
--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/.*" # 只允许 GET /api/* 请求
- method: "POST"
path: "/api/data"
headers:
- 'X-Token: .*' # 必须携带 Token

5.5 Hubble 网络可观测性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 安装 Hubble CLI
cilium hubble enable

# 查看实时网络流量
hubble observe --follow

# 查看特定 Pod 的流量
hubble observe --pod production/frontend --follow

# 查看被拒绝的流量
hubble observe --verdict DROPPED

# 查看 DNS 查询
hubble observe --protocol DNS

5.6 Cilium 替代 kube-proxy

1
2
3
4
5
6
# 验证 kube-proxy 替代
cilium status | grep KubeProxyReplacement
# KubeProxyReplacement: True

# 查看 Service 负载均衡(eBPF 实现)
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
# 查看 Pod 网络配置
kubectl exec -it <pod> -- ip addr
kubectl exec -it <pod> -- ip route
kubectl exec -it <pod> -- cat /etc/resolv.conf

# 测试 Pod 间连通性
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

# 使用 netshoot 调试容器
kubectl run netshoot --image=nicolaka/netshoot --rm -it -- bash

# 查看节点路由
ip route show table all | grep 10.244

# 查看 iptables 规则(传统方式)
iptables -t nat -L -n -v | grep <service-ip>

# 查看 eBPF 程序(Cilium)
cilium bpf lb list
cilium bpf policy get <endpoint-id>

8. 总结

CNI 网络插件的选择:

  1. Flannel:简单易用,适合学习和小规模集群
  2. Calico:生产首选,BGP 路由性能好,NetworkPolicy 强大
  3. Cilium:下一代方案,eBPF 驱动,L7 策略,内置可观测性

趋势:eBPF 正在成为 Kubernetes 网络的未来,Cilium 在大规模生产环境中的采用率快速增长。


CNI 网络插件深度解析:Calico、Cilium 与 Flannel
https://k8s.chucz.asia/CNI网络插件深度解析/
作者
K8s Engineer
发布于
2026年1月23日
许可协议