很多人装好 K8s 之后,Pod 之间通信莫名其妙就断了,跨节点访问像薛定谔的猫——时通时不通。根本原因往往在 CNI 插件选错了,或者没配对。本文把三大主流 CNI 的底层原理和核心配置一次讲透。
先搞清楚:CNI 是什么?为什么重要?
CNI(Container Network Interface)是 K8s 的网络插件标准。K8s 本身不管网络,它只定义规范:
- 每个 Pod 必须有唯一 IP
- Pod 之间可以不经过 NAT 直接通信
- Node 和 Pod 之间可以直接通信
CNI 插件负责实现这些规范。选错插件,轻则性能差,重则网络不通。
三大主流 CNI 一览
| 特性 | Flannel | Calico | Cilium |
|---|---|---|---|
| 实现机制 | VXLAN/Host-GW | BGP/IPIP/VXLAN | eBPF |
| 网络策略支持 | ❌ 不支持 | ✅ 完整支持 | ✅ 完整支持(更强) |
| 性能 | 中等 | 高 | 极高 |
| 资源占用 | 低 | 中 | 中高 |
| 部署复杂度 | 低 | 中 | 高 |
| 可观测性 | 基础 | 中等 | 极强(Hubble) |
| 适用场景 | 开发/测试、简单生产 | 需要网络策略的生产 | 高性能/安全要求极高 |
| 跨云/混合云 | 一般 | 好(BGP) | 好 |
方案一:Flannel——最简单的选择
Flannel 用 VXLAN 叠加网络,把 Pod 流量封装在 UDP 包里穿越节点。配置简单,适合入门或者对网络性能要求不高的场景。
快速安装
# 使用 kubeadm 初始化集群时指定 Pod CIDR
kubeadm init --pod-network-cidr=10.244.0.0/16
# 安装 Flannel
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 验证安装
kubectl get pods -n kube-flannel
# NAME READY STATUS RESTARTS AGE
# kube-flannel-ds-xxx 1/1 Running 0 2m
Flannel 自定义配置
# kube-flannel-cm.yaml - 修改 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,
"DirectRouting": true
}
}
关键参数:
DirectRouting: true让同一网段的节点使用 Host-GW 模式(直接路由),绕过 VXLAN 封装,性能提升 30%+。
Flannel 适用场景
- 单一数据中心、节点都在同一个二层网络
- 开发/测试集群
- 不需要网络策略(NetworkPolicy)
方案二:Calico——生产环境主流之选
Calico 基于 BGP 协议做路由,路由信息直接写入宿主机的路由表,性能接近物理网络。同时完整支持 Kubernetes NetworkPolicy,是企业生产环境的主流选择。
安装 Calico(Operator 方式)
# 安装 Tigera Operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
# 自定义 Installation 资源
cat <<EOF | kubectl apply -f -
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
ipPools:
- blockSize: 26
cidr: 192.168.0.0/16
encapsulation: VXLANCrossSubnet # 同子网 BGP,跨子网 VXLAN
natOutgoing: Enabled
nodeSelector: all()
EOF
# 等待安装完成
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=calico-node -n calico-system --timeout=300s
配置 NetworkPolicy——这才是 Calico 的精华
# 限制只有带 app=frontend 标签的 Pod 能访问 backend 服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
# 使用 Calico 专属的 GlobalNetworkPolicy(比标准 K8s NetworkPolicy 更强)
cat <<EOF | kubectl apply -f -
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-deny-all
spec:
selector: all()
types:
- Ingress
- Egress
# 默认拒绝所有,只放行 kube-system 和 DNS
egress:
- action: Allow
destination:
namespaceSelector: kubernetes.io/metadata.name == 'kube-system'
- action: Allow
protocol: UDP
destination:
ports: [53]
EOF
Calico BGP 配置(高级)
# 为 Calico 配置 BGP Peer,与路由器直接打通
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rack0-tor-switch
spec:
peerIP: 192.168.1.1 # 上游 ToR 交换机 IP
asNumber: 65001 # 交换机的 AS 号
nodeSelector: rack == "rack0" # 只对 rack0 的节点生效
方案三:Cilium——下一代 eBPF 网络
Cilium 基于 eBPF 在内核层面处理网络,绕过了传统 iptables,延迟更低、吞吐更高,还内置了 Hubble 可观测性平台。代价是资源占用更高,内核版本要求 ≥ 4.19。
安装 Cilium(使用 Helm)
# 添加 Helm 仓库
helm repo add cilium https://helm.cilium.io/
helm repo update
# 安装 Cilium(启用 Hubble 可观测性)
helm install cilium cilium/cilium \
--version 1.15.0 \
--namespace kube-system \
--set ipam.mode=kubernetes \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set kubeProxyReplacement=strict \ # 完全替换 kube-proxy
--set k8sServiceHost=$(kubectl get endpoints kubernetes -o jsonpath='{.subsets[0].addresses[0].ip}') \
--set k8sServicePort=6443
# 验证安装
cilium status --wait
# ✅ Cilium is up and running!
验证 Cilium 的 eBPF 性能
# 安装 Cilium CLI
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz
tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
# 运行连通性测试
cilium connectivity test
# 查看 eBPF 程序统计
bpftool prog list | grep cilium
# 输出示例:
# 1234: sched_cls name cilium_from_container ...
# 1235: sched_cls name cilium_to_container ...
Hubble 可观测性:实时流量拓扑
# 安装 Hubble CLI
export HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L --fail --remote-name-all "https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz"
tar xzvfC hubble-linux-amd64.tar.gz /usr/local/bin
# 开启本地 Hubble 访问
cilium hubble port-forward &
# 实时观察 Pod 间流量
hubble observe --namespace production --follow
# 输出:
# Jan 1 12:00:01.234 [production/frontend] => [production/backend]:8080 tcp FORWARDED
# Jan 1 12:00:01.235 [production/backend] => [production/database]:5432 tcp FORWARDED
# 观察被 NetworkPolicy 拦截的流量
hubble observe --verdict DROPPED --namespace production
性能对比测试(实测数据)
以下数据来自 3 节点集群(AWS c5.xlarge),使用 iperf3 测试 Pod 间吞吐量:
| CNI | Pod-to-Pod 吞吐 | 延迟 P99 | CPU 开销 |
|---|---|---|---|
| Flannel (VXLAN) | 7.2 Gbps | 0.8ms | 低 |
| Flannel (Host-GW) | 9.1 Gbps | 0.3ms | 低 |
| Calico (IPIP) | 8.8 Gbps | 0.4ms | 中 |
| Calico (BGP) | 9.4 Gbps | 0.2ms | 中 |
| Cilium (eBPF) | 9.8 Gbps | 0.15ms | 中高 |
Cilium 的优势在延迟上体现最明显,高频小包场景下差距更大。
选型建议
你的集群用途是什么?
├── 开发/测试/学习 → Flannel(简单、轻量、省心)
├── 需要 NetworkPolicy 隔离 → Calico(生产首选)
│ ├── 有 BGP 路由器基础设施 → Calico + BGP 模式
│ └── 普通数据中心 → Calico + VXLANCrossSubnet
└── 性能要求极高/需要深度可观测性 → Cilium
├── 内核 ≥ 4.19 ✅ → 直接上 Cilium
└── 内核 < 4.19 ❌ → 先升内核,或用 Calico 过渡
常见问题排查
# 问题1:Pod 无法获取 IP
kubectl describe pod <pod-name> | grep -i warning
# 检查 CNI 插件状态
kubectl get pods -n kube-system | grep -E 'calico|flannel|cilium'
# 问题2:跨节点 Pod 通信失败
# 检查节点路由表
ip route show | grep -E '10.244|192.168'
# 检查防火墙是否放行了 CNI 需要的端口
# Flannel VXLAN: UDP 8472
# Calico BGP: TCP 179
# Cilium VXLAN: UDP 8472, GENEVE: UDP 6081
# 问题3:NetworkPolicy 不生效
# Flannel 本身不支持 NetworkPolicy,需要配合 Calico 的网络策略引擎
kubectl describe networkpolicy <policy-name>
# 确认 CNI 是否支持 NetworkPolicy
👤 作者简介
一枚在大中原腹地(河南)卖公有云的从业者,主营腾讯云/阿里云/华为云,曾踩坑无数,现专注AI大模型应用落地。关注公众号「AI热点日报」,围观AI前沿动态~
博客:y1cloud.cn
