CNI(容器网络接口)为容器网络提供了标准化的接口和插件机制,极大地简化了容器编排平台的网络管理与扩展,是云原生网络生态的基础。
容器网络接口(Container Network Interface,CNI) 是 CNCF 旗下的重要项目,提供了一套标准化的容器网络配置规范和库。CNI 专注于容器创建时的网络资源分配和容器删除时的网络资源释放,为容器编排平台提供了统一的网络管理接口。
本节将系统介绍 CNI 的核心组成、架构设计、关键概念、实现细节及其在生态系统中的应用。
CNI 由三大核心组成部分构成:
libcni。CNI 设计只关注网络设置、连接和资源清理,便于实现和与各种容器运行时集成。
CNI 架构设计简洁,容器运行时可直接实现 CNI 规范或通过 libcni 库调用插件,完成容器网络配置。
```mermaid “CNI 高层架构” graph TD A[“容器运行时”] B[“CNI 规范”] C[“网络插件”] D[“libcni 库”]
A -->|"调用"| B
A -->|"调用"| D
D -->|"实现"| B
D -->|"执行"| C
C -->|"遵循"| B
subgraph "运行时域"
A
end
subgraph "CNI 项目"
B
D
end
subgraph "插件域"
C
end ```
{width=1920 height=3038}
CNI 仓库同时提供规范和辅助代码,方便运行时和插件开发者实现。
下图展示了 CNI 关键组件之间的关系:
```mermaid “CNI 组件关系” graph TD Runtime[“容器运行时”] Spec[“CNI 规范</br>(SPEC.md)”] Libcni[“libcni 库</br>(pkg/types, libcni/)”] Skel[“插件骨架</br>(pkg/skel)”] Plugins[“网络插件”]
Runtime -->|"调用"| Libcni
Libcni -->|"执行"| Plugins
Plugins -->|"基于"| Skel
Plugins -->|"遵循"| Spec
Runtime -->|"可直接实现"| Spec
Libcni -->|"实现"| Spec
Skel -->|"实现"| Spec
subgraph "CNI 仓库"
Spec
Libcni
Skel
end ```
{width=1920 height=2796}
CNI 的核心概念包括网络配置、操作类型、插件执行流程和插件类型。
CNI 使用 JSON 格式的网络配置,定义网络参数和插件设置。以下为示例配置:
{
"cniVersion": "1.1.0",
"name": "example-network",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.22.0.0/16"
}
}
]
}
网络配置由 CNI 运行时处理,并传递给各插件。
CNI 规范要求插件实现如下操作:
| 操作 | 目的 | 必需环境变量 |
|---|---|---|
| ADD | 添加容器到网络 | CNI_COMMAND, CNI_CONTAINERID, CNI_NETNS, CNI_IFNAME |
| DEL | 从网络移除容器 | CNI_COMMAND, CNI_CONTAINERID, CNI_IFNAME |
| CHECK | 验证网络设置 | CNI_COMMAND, CNI_CONTAINERID, CNI_NETNS, CNI_IFNAME |
| GC | 清理过期资源 | CNI_COMMAND, CNI_PATH |
| VERSION | 查询插件版本信息 | CNI_COMMAND |
| STATUS | 检查插件就绪状态 | - |
容器运行时通过环境变量和标准输入/输出调用插件操作。
下图展示了 CNI 操作的典型流程,包括 IP 地址管理插件的委托调用:
```mermaid “CNI 插件执行流程” sequenceDiagram participant Runtime as 容器运行时 participant CNI as libcni participant Plugin as 网络插件 participant IPAM as IPAM 插件
Runtime->>CNI: AddNetworkList(config)
CNI->>Plugin: 执行 ADD(exec)
Plugin->>IPAM: 委托 IPAM 操作
IPAM-->>Plugin: 返回 IP 信息
Plugin-->>CNI: 返回结果
CNI-->>Runtime: 返回结果
Note over Runtime,Plugin: 容器删除时
Runtime->>CNI: DelNetworkList(config)
CNI->>Plugin: 执行 DEL(exec)
Plugin->>IPAM: 委托清理
IPAM-->>Plugin: 确认
Plugin-->>CNI: 确认
CNI-->>Runtime: 确认 ```
{width=1920 height=1682}
CNI 插件主要分为以下几类:
CNI 的实现细节主要体现在 libcni 库和插件返回的结构化结果类型。
libcni 提供 Go API,供容器运行时与 CNI 插件交互,主要负责:
核心接口如下:
type CNI interface {
AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error
CheckNetworkList(net *NetworkConfigList, rt *RuntimeConf) error
// 其他方法...
}
CNI 操作返回结构化结果,定义于 pkg/types,主要类型包括:
Result:插件执行结果接口DNS:DNS 配置信息Route:路由信息Error:标准化错误报告下图为主要类型关系:
```mermaid “CNI 结果类型关系” classDiagram class Result { «interface» +Version() string +GetAsVersion(version string) Result +Print() error +PrintTo(writer) error }
class Current_Result {
+CNIVersion string
+Interfaces []*Interface
+IPs []*IPConfig
+Routes []*Route
+DNS DNS
}
class PluginConf {
+CNIVersion string
+Name string
+Type string
+IPAM IPAM
+DNS DNS
+PrevResult Result
}
class NetConfList {
+CNIVersion string
+Name string
+Plugins []*PluginConf
}
Result <|.. Current_Result : implements
NetConfList --> PluginConf : contains ```
{width=1920 height=1732}
CNI 已被众多容器运行时和编排平台采用,包括:
主流网络方案均实现了 CNI 插件,如:
广泛的生态应用证明了 CNI 在容器网络标准化方面的成功。
CNI 的设计遵循以下核心原则:
name、type 等。CNI 插件的实现需满足如下要求:
为了解耦 IP 管理策略与 CNI 插件类型,CNI 引入了 IPAM(IP Address Management)插件:
IPAM 插件通过以下方式工作:
CNI_PATH 指定的路径中。以下表格列举了常用 CNI 主插件、IPAM 插件和 Meta 插件,并简要说明其功能。
| 插件名称 | 功能描述 |
|---|---|
| bridge | 创建 Linux 网桥,连接主机和容器 |
| ipvlan | 创建 IPvlan 接口,支持 L2/L3 模式 |
| macvlan | 创建 MACvlan 接口,分配独立 MAC 地址 |
| ptp | 创建点对点 veth 对连接 |
| host-device | 将主机设备移入容器网络命名空间 |
| vlan | 创建 VLAN 子接口 |
| 插件名称 | 功能描述 |
|---|---|
| host-local | 本地静态 IP 地址池管理 |
| dhcp | 通过 DHCP 协议动态分配 IP |
| static | 静态 IP 地址分配 |
| 插件名称 | 功能描述 |
|---|---|
| portmap | 基于 iptables 的端口映射 |
| bandwidth | 网络带宽限制 |
| firewall | 基于 iptables 的防火墙规则 |
| tuning | 网络接口参数调优 |
下面分别给出基本网桥配置和链式插件配置的 JSON 示例,并附简要说明。
该配置为容器分配一个 bridge 网络,并通过 host-local IPAM 插件分配 IP 地址。
{
"cniVersion": "1.0.0",
"name": "mynet",
"type": "bridge",
"bridge": "mynet0",
"isDefaultGateway": true,
"forceAddress": false,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"subnet": "10.10.0.0/16"
}
}
该配置通过 plugins 字段串联多个插件,实现更复杂的网络功能。
{
"cniVersion": "1.0.0",
"name": "mynet",
"plugins": [
{
"type": "bridge",
"bridge": "mynet0",
"ipam": {
"type": "host-local",
"subnet": "10.10.0.0/16"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}
CNI 插件的选择和故障排查是实际运维中的重点,建议如下:
cni 命令行工具测试配置。CNI 作为容器网络的事实标准,极大地推动了云原生网络生态的发展。其模块化、标准化的设计理念,使得容器网络方案具备高度的可扩展性和可插拔性。理解 CNI 的架构和实现,有助于深入掌握 Kubernetes 等平台的网络原理,并为实际生产环境中的网络方案选型和故障排查提供坚实基础。