4. CNI 标准与 Calico 实现:CNI 规范、Calico CNI 插件安装流程、网络命名空间配置

4.1 CNI 规范核心解析

容器网络接口(CNI)是 Kubernetes 与网络插件之间的标准协议。它定义了插件如何配置网络接口、分配 IP 地址以及管理网络命名空间。CNI 规范的核心由三个要素构成:插件类型、标准配置格式和运行时调用约定。

CNI 规范核心要素
  • 插件类型:main(主插件,如 bridge、ipvlan、macvlan)、ipam(IP 地址管理,如 host-local、dhcp)、meta(元插件,如 flannel、calico、tuning)
  • 配置格式:JSON 格式的配置文件,包含 cniVersion、name、type、ipam 等字段
  • 调用约定:通过 stdin 传递配置,通过环境变量传递网络命名空间路径、容器 ID 等参数

CNI 插件必须实现四个标准操作:ADD(添加容器到网络)、DEL(从网络移除容器)、CHECK(检查容器网络状态)和 VERSION(返回插件版本信息)。Kubelet 在创建 Pod 时,会依次调用每个 CNI 插件的 ADD 操作,将容器接入网络。

CNI 操作 触发时机 Calico 实现行为
ADD Pod 创建时 创建 veth pair,一端接入容器 netns,一端接入 Calico 路由;分配 IP 并写入 etcd
DEL Pod 删除时 清理 veth 接口,释放 IP 地址,更新路由表
CHECK Kubelet 周期性健康检查 验证容器网络接口状态、IP 分配一致性、路由可达性
VERSION CNI 插件初始化 返回支持的 CNI 规范版本号(如 0.3.1、0.4.0、1.0.0)
CNI 版本兼容性提示:Kubernetes 1.24+ 推荐使用 CNI 规范 v0.4.0 或 v1.0.0。Calico v3.25+ 已全面支持 CNI v1.0.0,提供更完善的 CHECK 操作和错误处理机制。
CNI 规范与 Calico 插件调用流程 CNI 规范与 Calico 插件调用流程 Kubelet CNI 配置目录 /etc/cni/net.d/ CNI 插件二进制 /opt/cni/bin/ Calico CNI 插件 calico / calico-ipam Pod 网络命名空间 Felix Agent etcd / Kubernetes API CNI 调用流程说明 1. Kubelet 读取 CNI 配置目录,确定使用的插件链 2. 按顺序调用 CNI 插件二进制(ADD 操作),传入容器 ID 和网络命名空间路径 3. Calico 插件创建 veth pair,Felix 配置路由和 iptables 规则,IP 信息写入 etcd

4.2 Calico CNI 插件安装流程

Calico CNI 插件的安装涉及多个组件的协同部署。在生产环境中,推荐使用 Kubernetes API 数据存储(KDD)模式,避免额外维护 etcd 集群。安装流程分为以下步骤:

  1. 部署 Calico 控制平面:安装 calico-kube-controllers 和 calico-node DaemonSet
  2. 配置 CNI 网络插件:创建 calico-config ConfigMap,指定 IP 池、MTU、网络模式
  3. 安装 CNI 二进制文件:calico-node 容器将 calico、calico-ipam 等二进制文件挂载到宿主机的 /opt/cni/bin/ 目录
  4. 配置 CNI 插件链:生成 10-calico.conflist 配置文件,写入 /etc/cni/net.d/ 目录
  5. 验证安装状态:检查 calico-node Pod 运行状态,确认节点 Ready 状态
安装避坑指南:
  • 确保宿主机内核支持 ip_tables、nf_conntrack、ipip(如果使用 IPIP 模式)
  • CNI 配置目录的优先级:Kubelet 会按文件名顺序读取 .conflist 文件,确保 10-calico.conflist 优先级正确
  • 如果使用 host-local IPAM 而非 Calico 的 IPAM,需要额外配置 IP 池冲突检测

以下是一个典型的 Calico CNI 配置文件示例:

{
  "name": "k8s-pod-network",
  "cniVersion": "0.3.1",
  "plugins": [
    {
      "type": "calico",
      "log_level": "info",
      "datastore_type": "kubernetes",
      "nodename": "__KUBERNETES_NODE_NAME__",
      "mtu": 1500,
      "ipam": {
        "type": "calico-ipam",
        "assign_ipv4": "true",
        "assign_ipv6": "false"
      },
      "policy": {
        "type": "k8s"
      },
      "kubernetes": {
        "kubeconfig": "__KUBECONFIG_FILEPATH__"
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true},
      "snat": true
    }
  ]
}

4.3 网络命名空间配置

网络命名空间(Network Namespace)是容器网络隔离的基础。每个 Pod 拥有独立的网络命名空间,包含自己的网络接口、路由表、ARP 表和 iptables 规则。Calico 通过 veth pair 技术将容器网络命名空间与宿主机网络栈连接起来。

组件 网络命名空间位置 网络接口 IP 地址来源
Pod 容器 /proc/{pid}/ns/net eth0(veth 容器端) Calico IPAM 分配
宿主机 默认命名空间 cali{hash}(veth 主机端) N/A(作为网关)
Calico 路由 默认命名空间 tunl0(IPIP 模式)或 eth0(直接路由) 节点 IP

Calico 在配置网络命名空间时,执行以下关键操作:

  • 创建 veth pair:一端命名为 eth0 放入容器网络命名空间,另一端命名为 cali{hash} 留在宿主机默认命名空间
  • 分配 IP 地址:从 Calico IP 池中选取一个可用 IP,通过 calico-ipam 插件分配给容器 eth0 接口
  • 配置路由:在容器网络命名空间内设置默认路由指向宿主机 veth 端;在宿主机上添加路由将 Pod IP 指向对应 cali 接口
  • 设置 iptables 规则:Felix 在宿主机上配置网络策略规则,控制进出 Pod 的流量
Calico 网络命名空间与 veth pair 架构 Calico 网络命名空间与 veth pair 架构 宿主机默认网络命名空间 Pod A 网络命名空间 eth0: 10.0.1.2/24 默认路由: 10.0.1.1 veth 容器端 Pod B 网络命名空间 eth0: 10.0.1.3/24 默认路由: 10.0.1.1 veth 容器端 cali-abc123 cali-def456 路由表 + iptables veth pair 实现容器与宿主机网络互通,Felix 管理路由和策略

4.4 Calico 网络模式对比

Calico 支持多种网络模式,不同模式对网络命名空间的配置方式有所差异。选择合适的模式对多集群镜像拉取数据传输优化至关重要。

网络模式 封装方式 MTU 开销 性能 适用场景
Direct(直接路由) 无封装 0 字节 最高 同子网、底层网络支持 BGP
IPIP(跨子网) IP over IP 20 字节 高 跨子网、云环境
VXLAN(跨子网) VXLAN 封装 50 字节 中 跨子网、需要大二层网络
WireGuard(加密) 加密隧道 60 字节 中低 安全要求高的跨集群通信
多集群镜像拉取优化建议:对于跨集群的镜像拉取场景,推荐使用 Direct 模式或 IPIP 模式,减少封装开销,提升数据传输效率。如果集群间存在安全隔离要求,可考虑 WireGuard 模式,但需接受一定的性能损耗。