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 操作和错误处理机制。
4.2 Calico CNI 插件安装流程
Calico CNI 插件的安装涉及多个组件的协同部署。在生产环境中,推荐使用 Kubernetes API 数据存储(KDD)模式,避免额外维护 etcd 集群。安装流程分为以下步骤:
- 部署 Calico 控制平面:安装 calico-kube-controllers 和 calico-node DaemonSet
- 配置 CNI 网络插件:创建 calico-config ConfigMap,指定 IP 池、MTU、网络模式
- 安装 CNI 二进制文件:calico-node 容器将 calico、calico-ipam 等二进制文件挂载到宿主机的 /opt/cni/bin/ 目录
- 配置 CNI 插件链:生成 10-calico.conflist 配置文件,写入 /etc/cni/net.d/ 目录
- 验证安装状态:检查 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 的流量
4.4 Calico 网络模式对比
Calico 支持多种网络模式,不同模式对网络命名空间的配置方式有所差异。选择合适的模式对多集群镜像拉取数据传输优化至关重要。
| 网络模式 | 封装方式 | MTU 开销 | 性能 | 适用场景 |
|---|---|---|---|---|
| Direct(直接路由) | 无封装 | 0 字节 | 最高 | 同子网、底层网络支持 BGP |
| IPIP(跨子网) | IP over IP | 20 字节 | 高 | 跨子网、云环境 |
| VXLAN(跨子网) | VXLAN 封装 | 50 字节 | 中 | 跨子网、需要大二层网络 |
| WireGuard(加密) | 加密隧道 | 60 字节 | 中低 | 安全要求高的跨集群通信 |
多集群镜像拉取优化建议:对于跨集群的镜像拉取场景,推荐使用 Direct 模式或 IPIP 模式,减少封装开销,提升数据传输效率。如果集群间存在安全隔离要求,可考虑 WireGuard 模式,但需接受一定的性能损耗。