CNI (容器网络接口) 插件原理
CNI(Container Network Interface)是一个规范和一组库,用于配置 Linux 容器的网络接口。在 Kubernetes 中,CNI 插件负责为 Pod 分配 IP 地址并设置必要的路由,使 Pod 能够相互通信。
CNI 的作用
在 Kubernetes 中,CNI 插件扮演着关键角色:
- 为 Pod 分配和配置网络接口
- 为 Pod 分配 IP 地址
- 设置必要的路由规则,使 Pod 能够相互通信
- 实现 Kubernetes 网络模型的四个基本原则
- 提供网络策略(Network Policy)的实现
Kubernetes 本身不提供容器网络功能,而是依赖 CNI 插件来实现。这种插件化的设计使得用户可以根据自己的需求选择合适的网络解决方案。
CNI 工作原理
CNI 规范
CNI 规范定义了容器运行时(如 kubelet)和网络插件之间的接口。规范主要包括:
- 网络配置格式
- 容器运行时如何调用网络插件
- 网络插件如何配置网络接口
- 如何为容器分配 IP 地址
CNI 规范定义了以下主要操作:
- ADD:创建容器时,为容器添加网络接口
- DEL:删除容器时,清理网络接口
- CHECK:检查容器网络配置是否正确
- VERSION:返回插件支持的 CNI 规范版本
CNI 插件类型
CNI 插件可以分为以下几类:
主要网络插件
负责创建和配置容器网络接口的插件,如:
- bridge:创建 Linux 网桥,并将容器连接到网桥
- macvlan:基于物理网卡创建虚拟网卡,直接连接到物理网络
- ipvlan:类似于 macvlan,但共享 MAC 地址
- ptp:创建 veth 对,一端连接到容器,另一端连接到主机
- host-device:将主机上的网络设备直接移动到容器命名空间
IPAM 插件
负责 IP 地址分配和管理的插件,如:
- host-local:从预定义的地址范围中分配 IP 地址,并将分配信息存储在本地文件系统中
- dhcp:使用 DHCP 协议为容器分配 IP 地址
- static:为容器分配静态 IP 地址
Meta 插件
提供额外功能的插件,如:
- flannel:读取 flannel 配置,并将其转换为 bridge 插件配置
- tuning:调整网络接口参数,如 MTU 或 TCP 选项
- portmap:实现端口映射功能
- bandwidth:限制容器的带宽
- firewall:配置 iptables 规则
CNI 工作流程
在 Kubernetes 中,CNI 插件的工作流程如下:
- 当 kubelet 创建 Pod 时,它首先创建一个网络命名空间
- kubelet 通过 CRI(容器运行时接口)调用容器运行时(如 containerd 或 Docker)
- 容器运行时创建容器,但不配置网络
- kubelet 调用 CNI 插件,传递容器 ID、网络命名空间路径和网络配置
- CNI 插件执行以下操作:
- 创建 veth 对,一端连接到容器命名空间,另一端连接到主机
- 调用 IPAM 插件为容器分配 IP 地址
- 设置路由和 iptables 规则
- 返回分配的 IP 地址和其他网络信息给 kubelet
- kubelet 将网络信息更新到 Pod 状态
当 Pod 被删除时,过程相反:
- kubelet 调用 CNI 插件的 DEL 命令
- CNI 插件清理网络资源,包括释放 IP 地址、删除路由和 iptables 规则
- 容器运行时删除容器
- kubelet 删除网络命名空间
IPAM (IP 地址管理)
IPAM(IP Address Management)是 CNI 的一个重要组成部分,负责为容器分配和管理 IP 地址。
IPAM 的主要职责:
- 为容器分配 IP 地址
- 管理 IP 地址池
- 防止 IP 地址冲突
- 在容器删除时回收 IP 地址
常见的 IPAM 实现:
- host-local:在本地文件系统中维护 IP 地址分配状态
- dhcp:使用 DHCP 协议分配 IP 地址
- calico-ipam:Calico 的 IPAM 实现,支持分布式 IP 地址管理
- whereabouts:支持跨多个节点的 IP 地址管理
常见 CNI 插件
Calico
Calico 是一个流行的 CNI 插件,提供高性能、可扩展的网络解决方案。
主要特点:
- 使用 BGP(边界网关协议)进行路由信息交换
- 支持网络策略,提供细粒度的访问控制
- 可以在不使用 Overlay 网络的情况下工作,减少网络开销
- 支持 IPv4 和 IPv6
- 集成了 IPAM 功能
工作原理:
- 为每个节点分配一个 CIDR 块
- 使用 BGP 在节点间交换路由信息
- 在节点上创建路由表,使得 Pod 可以直接通信
- 使用 iptables 或 eBPF 实现网络策略
Flannel
Flannel 是一个简单易用的 CNI 插件,专注于提供 Overlay 网络。
主要特点:
- 配置简单,易于部署
- 支持多种后端,如 VXLAN、host-gw、UDP
- 不支持网络策略(需要与 Calico 集成为 Canal)
- 适合小型到中型集群
工作原理:
- 为每个节点分配一个子网
- 使用 etcd 或 Kubernetes API 存储子网分配信息
- 使用 VXLAN 等技术在节点间创建 Overlay 网络
- 在每个节点上创建路由表,将 Pod 流量路由到正确的节点
Weave Net
Weave Net 是一个功能丰富的 CNI 插件,提供简单的部署和强大的功能。
主要特点:
- 不依赖外部数据存储
- 支持加密通信
- 提供网络策略支持
- 支持多播
- 内置 DNS 解析
工作原理:
- 在节点间建立 TCP 连接,形成网状拓扑
- 使用 VXLAN 或 fast datapath 在节点间传输数据
- 使用 gossip 协议同步路由信息
- 为每个 Pod 分配全局唯一的 IP 地址
Cilium
Cilium 是一个基于 eBPF 的 CNI 插件,提供高性能的网络和安全功能。
主要特点:
- 使用 eBPF 技术,性能优异
- 支持 L3-L7 层的网络策略
- 提供丰富的监控和可观察性功能
- 支持透明加密
- 支持 Kubernetes 服务的负载均衡
工作原理:
- 使用 eBPF 程序在内核中处理网络数据包
- 基于身份而非 IP 地址进行安全策略控制
- 使用 BPF 映射存储策略和状态信息
- 支持多种数据路径,如直接路由、VXLAN 或 Geneve
CNI 插件对比
主要 CNI 插件特性对比
| 特性 | Calico | Flannel | Weave Net | Cilium |
|---|---|---|---|---|
| 网络模型 | BGP / VXLAN | VXLAN / host-gw | VXLAN / fast datapath | eBPF / VXLAN / Geneve |
| 网络策略 | ✓ | ✗ | ✓ | ✓ (L3-L7) |
| 加密 | IPsec (可选) | ✗ | ✓ | ✓ |
| 性能 | 高 (BGP 模式) | 中 | 中 | 高 (eBPF) |
| 可观察性 | 中 | 低 | 中 | 高 |
| 部署复杂度 | 中 | 低 | 低 | 高 |
| IPv6 支持 | ✓ | 部分 | ✓ | ✓ |
| 适用场景 | 大型集群,需要网络策略 | 小型集群,简单部署 | 中型集群,需要加密 | 需要高性能和高级网络策略 |
CNI 排障
在排查 CNI 相关问题时,可以使用以下命令和工具:
常用 CNI 排障命令
CNI 最佳实践
在选择和使用 CNI 插件时,可以参考以下最佳实践:
1. 选择合适的 CNI 插件
- 对于小型集群或测试环境,可以选择 Flannel,部署简单
- 对于需要网络策略的环境,可以选择 Calico 或 Cilium
- 对于需要高性能的环境,可以选择 Calico(BGP 模式)或 Cilium(eBPF)
- 对于需要加密通信的环境,可以选择 Weave Net 或 Cilium
2. 网络配置
- 确保 Pod CIDR 与现有网络不冲突
- 为大型集群预留足够的 IP 地址空间
- 考虑使用 IPAM 插件管理 IP 地址分配
- 根据需要配置 MTU,避免分片问题
3. 性能优化
- 在支持的环境中,使用 BGP 模式而非 Overlay 网络
- 考虑使用 eBPF 技术提升性能
- 适当调整 CNI 插件的资源限制
- 监控网络性能,及时发现问题
4. 安全考虑
- 使用网络策略限制 Pod 间通信
- 考虑启用网络加密
- 定期更新 CNI 插件,修复安全漏洞
- 限制对 CNI 配置的访问权限
CNI 插件是 Kubernetes 网络的基础,选择合适的 CNI 插件对于构建可靠、高性能的 Kubernetes 集群至关重要。了解不同 CNI 插件的特点和工作原理,可以帮助你更好地规划和管理 Kubernetes 网络。
进行动手实验