Kubernetes 网络实战:CNI 插件选型 + Calico/Flannel/Cilium 配置全攻略

阿里云上云采购季 2核2G云服务器99元/年 续费同价

很多人装好 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

发表评论