K8s 网络插件大全:CNI 原理、Flannel/Calico/Cilium 深度解析与故障排查
从概念到实战,从安装到故障排查,一文吃透 K8s 网络
Overlay 网络
BGP 路由
eBPF 内核
一、K8s 网络模型基础
1. 每个 Pod 有唯一 IP,无需 NAT 即可与集群内所有 Pod 通信
2. Node 上的 Agent 可以直接与节点上所有 Pod 通信
3. Pod 视角下的本机 IP = 外部看到的 IP(无 IP 伪装)
K8s 网络通信层次:
┌──────────────────────────────────────────────────────────┐
│ 同 Pod 内容器 │
│ Container A ←──── lo (127.0.0.1) ────→ Container B │
└──────────────────────────────────────────────────────────┘
│ veth pair
┌──────────────────────────────────────────────────────────┐
│ 同节点 Pod 间 │
│ Pod A (10.244.0.2) ←──── cbr0/bridge ────→ Pod B │
└──────────────────────────────────────────────────────────┘
│ 物理网卡/隧道/路由
┌──────────────────────────────────────────────────────────┐
│ 跨节点 Pod 间 │
│ Node1 Pod ←──── CNI 插件负责 ────→ Node2 Pod │
└──────────────────────────────────────────────────────────┘
│ kube-proxy / eBPF
┌──────────────────────────────────────────────────────────┐
│ Pod ↔ Service │
│ ClusterIP / NodePort / LoadBalancer / ExternalName │
└──────────────────────────────────────────────────────────┘
二、CNI 是什么?插件标准详解
CNI(Container Network Interface) 是 CNCF 制定的容器网络接口标准,定义了容器运行时(如 kubelet)如何调用网络插件,以及插件如何为容器配置网络。
1. 为每个 Pod 分配唯一 IP(IPAM)
2. 在 Pod 网卡和节点网络之间建立连通性(路由/隧道)
3. Pod 删除时清理网络配置
# CNI 插件调用流程(kubelet 视角)
# 1. Pod 创建:kubelet 调用 CRI(containerd),CRI 调用 CNI
# 配置文件位置:
ls /etc/cni/net.d/
# 10-calico.conflist 或 10-flannel.conflist
# 插件二进制位置:
ls /opt/cni/bin/
# calico calico-ipam flannel host-local bridge loopback …
# 2. CNI 调用链(以 Calico 为例)
# kubelet → /etc/cni/net.d/10-calico.conflist → /opt/cni/bin/calico
# CNI 需实现两个接口:
# ADD → 为容器配置网络(分配 IP、建立路由)
# DEL → 清理容器网络(释放 IP、删除路由)
| CNI 插件类型 | 代表产品 | 原理 | 特点 |
|---|---|---|---|
| Overlay 叠加网络 | Flannel VXLAN Weave |
隧道封装,二层模拟 | 简单通用,有封装开销 |
| Underlay 路由网络 | Calico BGP Flannel host-gw |
直接路由,无封装 | 高性能,依赖底层网络 |
| eBPF 内核加速 | Cilium | eBPF bypass iptables | 极高性能,可观测性强 |
| IPVLAN/MACVLAN | Multus + 子插件 | 直接共享宿主网卡 | 超低延迟,适合 SR-IOV |
三、Flannel:最易上手的 Overlay 网络
3.1 架构与原理
Flannel VXLAN 数据流:
Node1 (10.244.0.0/24) Node2 (10.244.1.0/24)
┌──────────────────────┐ ┌──────────────────────┐
│ Pod-A (10.244.0.2) │ │ Pod-B (10.244.1.3) │
│ eth0 ──► veth │ │ eth0 ──► veth │
│ │ │ │ │ │
│ cni0 │ │ cni0 │
│ (bridge 网桥) │ │ (bridge 网桥) │
│ │ │ │ │ │
│ flannel.1 │─VXLAN──►│ flannel.1 │
│ (VTEP 封装设备) │UDP:8472 │ (VTEP 解封装设备) │
│ │ │ │ │ │
│ eth0 │─────────│ eth0 │
│ (物理网卡 192.168.x) │ │ (物理网卡 192.168.y) │
└──────────────────────┘ └──────────────────────┘
数据流:Pod-A → veth → cni0 → flannel.1(VXLAN封装) → eth0 → 物理网络
→ eth0(Node2) → flannel.1(解封装) → cni0 → veth → Pod-B
# Flannel 安装(适用于 K8s 1.28+)
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
# 关键配置文件
cat /etc/cni/net.d/10-flannel.conflist
# {
# “name”: “cbr0”,
# “cniVersion”: “0.3.1”,
# “plugins”: [
# {
# “type”: “flannel”,
# “delegate”: {
# “hairpinMode”: true,
# “isDefaultGateway”: true
# }
# },
# { “type”: “portmap”, “capabilities”: { “portMappings”: true } }
# ]
# }
# 查看 Flannel 子网分配
cat /run/flannel/subnet.env
# FLANNEL_NETWORK=10.244.0.0/16
# FLANNEL_SUBNET=10.244.0.1/24
# FLANNEL_MTU=1450
# FLANNEL_IPMASQ=true
3.2 Flannel 三种后端模式
| Backend | 原理 | 性能 | 要求 |
|---|---|---|---|
| vxlan(默认) | UDP 封装二层帧,VTEP 设备 | 中等(有封装开销) | 无特殊要求,最通用 |
| host-gw | 直接添加静态路由,无封装 | 最高(接近裸机) | 所有节点必须在同一子网 |
| wireguard | 加密隧道(WireGuard) | 中等(加密开销) | 内核 5.6+ / WireGuard 模块 |
# 切换 backend 为 host-gw(高性能,需同子网)
kubectl edit cm -n kube-flannel kube-flannel-cfg
# 修改:
# “Backend”: {
# “Type”: “host-gw”
# }
kubectl rollout restart daemonset -n kube-flannel kube-flannel-ds
# 验证:节点路由表中能看到其他节点的 Pod CIDR 路由
ip route | grep flannel
# 10.244.1.0/24 via 192.168.1.102 dev eth0
# 10.244.2.0/24 via 192.168.1.103 dev eth0
四、Calico:企业级高性能 BGP 网络
4.1 架构与原理
• 纯三层路由,无隧道封装,性能最优
• 支持 BGP / BGP-RR / IPIP / VXLAN 多种模式
• 内置 NetworkPolicy 功能,支持 L3/L4 防火墙
• 支持 GlobalNetworkPolicy、HostEndpoint 等企业级安全特性
Calico 组件架构:
┌─────────────────────────────────────────────────────┐
│ Control Plane │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ calico-kube │ │ Typha │ │
│ │ -controllers│ │ (scale代理) │ │
│ └─────────────┘ └─────────────┘ │
└──────────────────────────┬──────────────────────────┘
│ watch K8s API
┌──────────────────────────▼──────────────────────────┐
│ 每个 Node 上的 DaemonSet │
│ ┌──────────────────────────────────────────────┐ │
│ │ Felix (核心代理) │ │
│ │ • 路由同步、iptables规则、IP分配通知 │ │
│ └──────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────┐ │
│ │ BIRD (BGP 路由协议守护进程) │ │
│ │ • 与其他节点交换 BGP 路由 │ │
│ └──────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────┐ │
│ │ calico-ipam (IP 地址管理) │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
# 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
# 查看安装状态
kubectl get tigerastatus
# NAME AVAILABLE PROGRESSING DEGRADED SINCE
# apiserver True False False 10m
# calico True False False 10m
# 或直接 manifest 方式
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml
4.2 Calico 模式配置
# 查看当前模式
kubectl get felixconfiguration default -o yaml | grep -E ‘encapsulation|routeMode’
# — 方式 1:纯 BGP(最高性能,需三层互通)—
cat <<EOF | kubectl apply -f –
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
bgp: Enabled
ipPools:
– cidr: 10.244.0.0/16
encapsulation: None
natOutgoing: Enabled
EOF
# — 方式 2:IPIP(兼容性最好,有轻微开销)—
# encapsulation: IPIP
# — 方式 3:VXLAN(不需要 BGP,适合云环境)—
# encapsulation: VXLAN
# bgp: Disabled
# 验证路由(纯 BGP 模式下节点路由直达)
ip route | grep bird
# 10.244.1.0/26 via 192.168.1.102 dev eth0 proto bird
# 10.244.2.0/26 via 192.168.1.103 dev eth0 proto bird
4.3 Calico NetworkPolicy
# 示例:仅允许 frontend 访问 backend 的 8080 端口
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
selector: app == ‘backend’
ingress:
– action: Allow
protocol: TCP
source:
selector: app == ‘frontend’
destination:
ports:
– 8080
– action: Deny # 默认拒绝其他所有入站
—
# GlobalNetworkPolicy:全局策略(跨 namespace)
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: block-external-ssh
spec:
selector: all()
ingress:
– action: Deny
protocol: TCP
destination:
ports:
– 22
source:
notNets:
– 192.168.0.0/16 # 允许内网,拒绝外部
五、Cilium:eBPF 驱动的下一代网络
• eBPF 内核级别:完全绕过 iptables,性能提升 300%+
• L7 策略:支持 HTTP/gRPC/Kafka 等应用层协议的访问控制
• Hubble 可观测性:内置流量监控、拓扑图、Prometheus 集成
• Service Mesh 替代:无需 Sidecar,eBPF 内核实现 mTLS
5.1 eBPF 原理
传统 iptables 路径 vs eBPF 路径: 传统(kube-proxy + iptables): 包到达 → netfilter hook → iptables 规则链(可能上千条)→ 内核协议栈 → 目标 eBPF(Cilium): 包到达 → eBPF hook(XDP/TC)→ eBPF 程序直接转发 → 目标 优势: ✓ 无 iptables 规则,规则数不影响性能 ✓ 支持 O(1) 连接查找(BPF map) ✓ 可在内核态实现 L7 协议解析 ✓ 延迟降低 30-50%,吞吐提升 20-40%
# Cilium 安装(Helm 方式,推荐)
helm repo add cilium https://helm.cilium.io/
helm repo update
# 基础安装(替换 kube-proxy)
helm install cilium cilium/cilium –version 1.15.0 \
–namespace kube-system \
–set kubeProxyReplacement=true \
–set k8sServiceHost=<API_SERVER_IP> \
–set k8sServicePort=6443 \
–set hubble.relay.enabled=true \
–set hubble.ui.enabled=true
# 验证安装
cilium status
# KVStore: Ok Disabled
# Kubernetes: Ok 1.29+ (v1.29.0)
# Kubernetes APIs: Ok cilium/v2::CiliumNetworkPolicy
# KubeProxyReplacement: True NodePort (SNAT, 30000-32767)
# Host Routing: Legacy (No BPF NodePort)
# Cilium: Ok 10 healthy (10 desired)
5.2 Hubble 流量可观测
# 安装 Hubble CLI
HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L –remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz
tar xzvf hubble-linux-amd64.tar.gz
mv hubble /usr/local/bin/
# 开启端口转发访问 Hubble
cilium hubble port-forward &
# 查看实时流量
hubble observe –namespace production
# Feb 20 10:01:01.000: production/frontend:45678 -> production/backend:8080 http-response FORWARDED
# Feb 20 10:01:01.001: production/backend:8080 -> production/frontend:45678 http-request FORWARDED
# 查看 DNS 流量
hubble observe –protocol DNS
# 查看被 drop 的包
hubble observe –verdict DROPPED
# Hubble UI(Web 界面)
cilium hubble ui # 自动打开浏览器,展示服务间流量拓扑图
5.3 Cilium L7 网络策略
# L7 HTTP 策略(Calico 和 Flannel 做不到!)
apiVersion: “cilium.io/v2”
kind: CiliumNetworkPolicy
metadata:
name: l7-http-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: api-server
ingress:
– fromEndpoints:
– matchLabels:
app: frontend
toPorts:
– ports:
– port: “8080”
protocol: TCP
rules:
http:
– method: “GET”
path: “/api/v1/.*” # 只允许 GET /api/v1/
– method: “POST”
path: “/api/v1/orders” # POST 只允许下单接口
egress:
– toFQDNs:
– matchName: “api.external.com” # 只允许访问指定域名!
六、Weave Net / Antrea / 其他插件一览
6.1 Weave Net
# Weave 安装
kubectl apply -f “https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d ‘
‘)”
# Weave 特性:
# – 全 mesh 对等连接,每个节点和其他所有节点直接连
# – 支持加密通信(–password 参数)
# – Fast Datapath:内核 OVS 加速,减少用户态拷贝
# 查看 Weave 状态
kubectl exec -n kube-system weave-net-xxxxx -c weave — /home/weave/weave –local status
# Connections:
# -> 192.168.1.102:6783 established
# -> 192.168.1.103:6783 established
6.2 Antrea(VMware/国产常用)
# Antrea 安装
kubectl apply -f https://github.com/antrea-io/antrea/releases/latest/download/antrea.yaml
# Antrea 特性:
# – 基于 OVS(Open vSwitch)实现,功能强大
# – 支持 NetworkPolicy Tier(优先级分层策略)
# – 内置 Traceflow(数据包追踪,类似 Calico flow log)
# – Octant UI 可视化
# 查看 Antrea 状态
kubectl exec -n kube-system deploy/antrea-controller — antctl get featuregates
# 查看 OVS 流表(在节点上)
ovs-vsctl show
ovs-ofctl dump-flows br-int | head -30
| 插件 | 推荐场景 | 网络模式 | 特色功能 |
|---|---|---|---|
| Flannel | 开发/测试环境 简单集群 |
VXLAN/host-gw | 安装最简单 |
| Calico | 生产环境 大规模集群 |
BGP/IPIP/VXLAN | NetworkPolicy 最强 |
| Cilium | 高性能生产 可观测需求强 |
eBPF native | L7 策略/无需 sidecar |
| Weave | 小集群/加密需求 | VXLAN full-mesh | 开箱即用/加密通信 |
| Antrea | VMware 环境 国产信创 |
OVS/Geneve | 可视化/Traceflow |
七、云原生网络插件(云厂商专属)
| 云厂商 | 插件名称 | 底层实现 | 特色 |
|---|---|---|---|
| AWS(EKS) | amazon-vpc-cni | VPC 弹性网卡(ENI) | Pod IP = VPC 真实 IP,无 Overlay |
| 阿里云(ACK) | terway | 弹性网卡/NetworkPolicy | 支持独占 ENI,延迟最低 |
| 腾讯云(TKE) | tke-route-eni | VPC 路由 + ENI | 支持多网卡,适合高性能 |
| Azure(AKS) | azure-cni | VNet 虚拟子网 | Pod 直接使用 VNet IP |
| GCP(GKE) | google-cloud-cni | VPC native | Pod IP 可直接被 GCP LB 路由 |
| 华为云(CCE) | canal / vpc-cni | VPC 路由 | 支持 GPU 节点加速网络 |
• Pod IP 直接使用云厂商 VPC 的真实 IP,无 NAT 无 Overlay
• 网络性能等同于云主机间直连,延迟极低
• 安全组直接管控 Pod 流量(VPC 级别策略)
• 缺点:Pod 密度受 ENI 数量限制
# 阿里云 Terway 配置示例
# 模式 1:VPC 路由模式(兼容性好)
# 模式 2:独占 ENI 模式(性能最好)
# 模式 3:ENI 多 IP 模式(密度最高)
# 查看 Terway 模式
kubectl get cm -n kube-system eni-config -o yaml
# 查看 ENI 分配状态
kubectl get felixconfiguration -n kube-system
kubectl describe node <node-name> | grep -E ‘ENI|IP’
# AWS VPC CNI:调整每节点最大 Pod 数
# 默认每节点 Pod 数受 ENI * (max_ip_per_eni – 1) 限制
kubectl set env daemonset aws-node -n kube-system \
ENABLE_PREFIX_DELEGATION=true \ # 前缀委托,突破 IP 限制
WARM_PREFIX_TARGET=1
八、网络插件常见问题与排查
8.1 Pod 无法通信排查流程
排查决策树: Pod 无法访问其他 Pod? │ ├─► 能 ping 同节点 Pod? │ ├─ 否 → 检查 cni0/cbr0 网桥配置,查 CNI 日志 │ └─ 是 → 能 ping 跨节点 Pod? │ ├─ 否 → 检查节点路由/隧道,检查防火墙端口(VXLAN:8472,IPIP:4,BGP:179) │ └─ 是 → 能访问 Service ClusterIP? │ ├─ 否 → kube-proxy/eBPF 问题,检查 iptables/ipvs 规则 │ └─ 是 → 检查 DNS(CoreDNS) │ Pod 无法获取 IP? │ ├─► kubectl describe pod 查 Events │ ├─ "failed to create pod network: xxx" → CNI 插件本身问题 │ ├─ "no IP addresses available" → IPAM 耗尽 │ └─ "plugin not found" → /opt/cni/bin/ 插件缺失
# ===== 常用排查命令大全 =====
# 1. 查看 Pod IP 分配情况
kubectl get pod -o wide -A | grep -v Running
# 2. 查看 CNI 日志(以 Calico 为例)
kubectl logs -n calico-system -l app=calico-node –tail=50
kubectl logs -n kube-flannel -l app=flannel –tail=50
# 3. 在 Pod 内测试网络
kubectl exec -it <pod> — sh -c “ping -c 3 <target-ip>”
kubectl exec -it <pod> — sh -c “curl -v http://<service>:port”
kubectl exec -it <pod> — sh -c “nslookup kubernetes.default”
# 4. 查看节点路由表
ip route show
bridge link show
ip link show
# 5. 查看 iptables 规则(kube-proxy 模式)
iptables-save | grep <service-clusterip>
iptables -t nat -L KUBE-SERVICES -n | grep <service-name>
# 6. 查看 IPVS 规则(kube-proxy IPVS 模式)
ipvsadm -Ln | grep -A3 <service-clusterip>
# 7. 抓包分析
# 在节点上抓 VXLAN 包
tcpdump -i eth0 -nn port 8472
# 在 Pod 内抓包
kubectl exec -it <pod> — tcpdump -i eth0 -nn
# 8. 检查 NetworkPolicy 是否误拦截
kubectl describe networkpolicy -A
# Calico 工具查看策略
kubectl exec -n calico-system calico-node-xxx — calico-node -show-policy-list
# 9. Cilium 专用诊断
cilium connectivity test
cilium-health status
hubble observe –verdict DROPPED –last 100
8.2 常见故障与解决方案
| 故障现象 | 常见原因 | 解决方案 |
|---|---|---|
| Pod 一直 ContainerCreating Events: network plugin not ready |
CNI 插件未就绪 kubelet 还没初始化完成 |
等待 CNI DaemonSet 全部就绪 kubectl get ds -A |
| 跨节点 Pod ping 不通 | VXLAN 端口(8472)被防火墙阻断 或 BGP 端口(179)被阻断 |
firewall-cmd 或安全组开放对应端口 |
| DNS 解析失败 nslookup 超时 |
CoreDNS Pod 异常 或 iptables NAT 规则缺失 |
kubectl rollout restart deploy coredns -n kube-system |
| Pod IP 耗尽 no IP available | Pod CIDR 规划太小 或有泄漏的僵尸 IP |
扩大 podCIDR,清理残留 Pod/IP |
| Service ClusterIP 无法访问 | kube-proxy 未运行 iptables 规则被清空 |
检查 kube-proxy DaemonSet iptables-restore 重建规则 |
| MTU 导致大包丢失 | Overlay 封装后 MTU 不一致 | Flannel: FLANNEL_MTU=1450 Calico: ip link set mtu 1480 dev eth0 |
九、如何选择网络插件?
| 场景 | 推荐插件 | 理由 |
|---|---|---|
| 学习 / 开发测试 | Flannel VXLAN | 安装最简单,零配置 |
| 生产环境(裸机/VM) | Calico BGP | 高性能 + 强 NetworkPolicy |
| 生产环境(高性能要求) | Cilium eBPF | 最高性能 + 可观测性 + L7 策略 |
| 公有云(AWS/阿里云) | 云原生 CNI(VPC-CNI/Terway) | Pod IP = VPC IP,无 Overlay 最快 |
| 合规 / 加密传输 | Calico WireGuard 或 Cilium | 内置 WireGuard 加密所有 Pod 流量 |
| 超大规模集群 (1000+ 节点) | Calico + Typha 或 Cilium | Typha 缓解 API Server 压力 |
| 服务网格替代 / 无 Sidecar | Cilium | eBPF 内核实现 mTLS/L7 观测 |
① 用云?→ 优先选云厂商原生 CNI
② 裸机/VM + 性能优先?→ Calico BGP
③ 极致性能 + 可观测 + L7 策略?→ Cilium
④ 只是想快速跑起来?→ Flannel VXLAN
✦ Flannel:入门首选,VXLAN 通用,host-gw 高性能但需同子网
✦ Calico:生产主流,BGP 路由无封装,企业级 NetworkPolicy
✦ Cilium:eBPF 未来方向,L7 策略 + 可观测性 + 无 Sidecar 服务网格
✦ 云环境优先选云原生 CNI,Pod IP = VPC IP,零 Overlay 延迟
📚 更多干货,欢迎关注「院长技术」
🔧 往期推荐:K8s 存储体系 / Prometheus 监控 / Tekton CI/CD 系列
夜雨聆风