3、CNI网络模型深度解析:CNI插件架构、常见CNI(Calico/Flannel/Weave)工作原理

3.1 CNI(Container Network Interface)规范与插件架构

CNI 是 Cloud Native Computing Foundation(CNCF)旗下的一个项目,旨在定义容器运行时与网络插件之间的标准化接口。它解决了 Kubernetes 等容器编排平台中网络插件的可插拔性问题,使得不同的网络实现(如 Calico、Flannel、Weave)能够以统一的方式接入。

3.1.1 CNI 核心架构组件

组件 角色 说明
容器运行时 调用方 如 containerd、CRI-O,在创建/删除 Pod 时调用 CNI 插件。
CNI 插件(二进制) 执行者 可执行文件(如 calico、flannel),负责配置网络接口。
CNI 配置文件 配置源 位于 /etc/cni/net.d/,定义插件链、IP 分配方式等。
IPAM 插件 地址管理 负责 IP 地址分配与回收,如 host-local、calico-ipam。

3.1.2 CNI 插件调用流程

  1. ADD 操作:容器运行时通过环境变量(CNI_COMMAND=ADD)调用 CNI 插件二进制。
  2. 解析配置:插件读取标准输入(stdin)中的 JSON 配置,获取网络名称、子网、IPAM 类型等。
  3. 创建网络命名空间:插件在容器网络命名空间内创建 veth pair 或其它虚拟设备。
  4. 配置 IP 与路由:调用 IPAM 插件分配 IP 地址,设置路由规则。
  5. 返回结果:将接口名称、MAC 地址、IP 等信息以 JSON 格式输出到 stdout。
  6. DEL 操作:Pod 删除时,运行时调用 DEL 命令,插件清理网络资源。
关键点:CNI 插件是无状态的,每次调用都基于配置文件和环境变量独立执行。这种设计保证了插件的轻量性和可组合性。

3.2 常见 CNI 插件工作原理对比

在生产环境中,Calico、Flannel 和 Weave 是最广泛使用的三种 CNI 插件。它们在数据平面、网络模型、性能与功能上存在显著差异。

3.2.1 Flannel:简单 Overlay 网络

Flannel 是 CoreOS 推出的最简 CNI 实现,核心思想是为每个节点分配一个独立的子网,并通过 Overlay 隧道(VXLAN 或 host-gw)实现跨节点通信。

  • 数据平面:默认使用 VXLAN 封装,将二层帧封装在 UDP 包中。
  • 路由模型:节点间通过 etcd 或 Kubernetes API 存储子网分配信息。
  • 优点:部署简单,无需额外依赖,适合中小规模集群。
  • 缺点:VXLAN 封装带来性能损耗;不支持 NetworkPolicy。

3.2.2 Calico:纯三层 BGP 网络

Calico 采用纯三层路由模型,利用 BGP(Border Gateway Protocol)在节点间直接交换路由,无需 Overlay 封装。

  • 数据平面:基于 eBPF 或标准 Linux 路由表,数据包直接路由到目标节点。
  • 路由模型:每个节点运行 BGP 客户端(如 Bird),将 Pod 子网路由广播到整个集群。
  • 优点:接近原生性能;原生支持 Kubernetes NetworkPolicy;支持 IPIP 封装作为备选。
  • 缺点:需要 BGP 基础设施;在大规模集群中路由表可能膨胀。

3.2.3 Weave:加密与多跳 Overlay

Weave 提供加密 Overlay 网络,支持跨主机通信和跨数据中心部署。

  • 数据平面:使用自己的协议(Weave Router)封装数据包,支持可选的 IPsec 加密。
  • 路由模型:每个节点运行 Weave Router 进程,通过 gossip 协议发现拓扑。
  • 优点:内置加密;支持多跳路由;无需外部存储。
  • 缺点:性能相对较低;配置复杂度高于 Flannel。

3.3 三种 CNI 插件核心特性对比

特性 Flannel Calico Weave
网络模型 Overlay(VXLAN) 纯三层路由(BGP) Overlay(自定义协议)
性能 中等(有封装开销) 高(无封装) 较低(加密+封装)
NetworkPolicy 不支持 原生支持 支持(通过 iptables)
加密 不支持 不支持(需额外配置) 内置 IPsec
外部依赖 etcd 或 Kubernetes API BGP 路由器或 RR 无
部署复杂度 低 中 中

3.4 CNI 插件架构与数据流示意图

下图展示了 CNI 插件在 Kubernetes 节点上的通用架构,以及三种插件在数据包转发路径上的差异。

CNI 插件架构与数据流对比 Kubernetes 节点 Pod A Pod B CNI 插件(二进制) 容器运行时(containerd) 数据包 CNI 插件处理路径 Flannel VXLAN 封装 Calico BGP 路由 Weave 加密 Overlay 目标节点 Pod 网络命名空间 三种 CNI 数据流差异详解 Flannel:Pod A → veth → cni0 桥 → flannel.1 → VXLAN 隧道 → 目标节点 Calico:Pod A → veth → cali 接口 → 主机路由表 → BGP 路由 → 目标节点(无封装) Weave:Pod A → veth → weave 网桥 → Weave Router → IPsec 加密 → 目标节点 注:Calico 在跨子网场景下可回退到 IPIP 封装,但默认纯三层模式性能最优。 Flannel 的 host-gw 模式可避免封装,但要求节点二层互通。

3.5 CNI 插件选择建议

选型建议:对于需要 NetworkPolicy 和性能敏感的生产环境,优先选择 Calico;对于快速搭建测试环境或中小规模集群,Flannel 足够;对于跨数据中心且需要加密的场景,Weave 是合适的选择。

3.6 CNI 配置示例

以下是一个典型的 Calico CNI 配置文件(位于 /etc/cni/net.d/10-calico.conflist):

{
  "name": "k8s-pod-network",
  "cniVersion": "0.3.1",
  "plugins": [
    {
      "type": "calico",
      "log_level": "info",
      "datastore_type": "kubernetes",
      "nodename": "node-01",
      "ipam": {
        "type": "calico-ipam",
        "assign_ipv4": "true",
        "assign_ipv6": "false"
      },
      "policy": {
        "type": "k8s"
      },
      "kubernetes": {
        "kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true},
      "snat": true
    }
  ]
}
注意:CNI 配置文件中的 cniVersion 必须与容器运行时支持的版本兼容。Kubernetes 1.24+ 推荐使用 0.3.1 或 0.4.0。