2. Multus 架构原理:CRD 设计、Delegated Plugin 机制与网络附加定义详解
Multus 是 Kubernetes 生态中最主流的多网卡 CNI 插件,其核心设计哲学是 “不替代现有 CNI,而是作为 CNI 的调度器”。它通过自定义资源定义(CRD)和委托插件(Delegated Plugin)机制,让 Pod 能够同时接入多个网络平面,而无需修改底层 CNI 实现。
2.1 Multus 整体架构与工作流
Multus 以 DaemonSet 形式运行在每个节点上,作为 kubelet 调用的“主 CNI 插件”。当 kubelet 请求为 Pod 配置网络时,Multus 首先解析 Pod 的注解,获取网络附加定义列表,然后依次调用每个网络对应的委托 CNI 插件完成配置。
2.2 CRD 设计:NetworkAttachmentDefinition
Multus 的核心 CRD 是 NetworkAttachmentDefinition(NAD),它定义了一个可被 Pod 引用的网络配置。NAD 是 Multus 与底层 CNI 配置之间的桥梁。
| 字段 | 类型 | 说明 |
|---|---|---|
apiVersion |
string | k8s.cni.cncf.io/v1 |
kind |
string | NetworkAttachmentDefinition |
metadata.name |
string | NAD 名称,Pod 注解中引用 |
metadata.namespace |
string | NAD 所属命名空间(跨命名空间引用需特殊配置) |
spec.config |
string (JSON) | 委托 CNI 的完整配置 JSON 字符串 |
spec.config 字段是一个 JSON 字符串,它直接嵌入委托 CNI 的配置。这意味着 NAD 可以承载任何 CNI 插件的配置,包括 macvlan、ipvlan、bridge、vlan 等。
以下是一个典型的 NAD 示例,定义了一个基于 macvlan 的辅助网络:
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: macvlan-conf
namespace: default
spec:
config: '{
"cniVersion": "0.3.1",
"type": "macvlan",
"master": "eth0",
"mode": "bridge",
"ipam": {
"type": "host-local",
"subnet": "192.168.1.0/24",
"rangeStart": "192.168.1.100",
"rangeEnd": "192.168.1.200",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
}'
2.3 Delegated Plugin 机制详解
委托插件机制是 Multus 实现多网络接入的技术核心。当 Multus 收到 kubelet 的 ADD 请求时,它执行以下步骤:
- 读取 Pod 注解:从 Pod 的
k8s.v1.cni.cncf.io/networks注解中获取需要附加的网络列表。 - 解析 NAD 引用:根据注解中的名称和命名空间,查找对应的 NAD 资源。
- 提取委托配置:从 NAD 的
spec.config字段中解析出委托 CNI 的配置 JSON。 - 调用委托 CNI:将委托配置传递给对应的 CNI 插件二进制文件(如
macvlan、ipvlan),并执行 ADD 操作。 - 合并结果:将所有委托 CNI 返回的接口信息合并,返回给 kubelet。
CNI_PATH 目录中。Multus 本身不包含任何底层 CNI 实现,它完全依赖系统中已安装的 CNI 插件。
2.4 Pod 注解与网络选择
Pod 通过注解 k8s.v1.cni.cncf.io/networks 指定要附加的网络。Multus 支持三种引用方式:
| 引用方式 | 示例 | 说明 |
|---|---|---|
| 简单名称 | macvlan-conf |
引用当前命名空间下的 NAD |
| 命名空间/名称 | other-ns/macvlan-conf |
引用指定命名空间下的 NAD |
| JSON 对象 | [{"name":"macvlan-conf","namespace":"default"}] |
支持更复杂的配置,如指定接口名称 |
Pod 注解示例:
apiVersion: v1
kind: Pod
metadata:
name: multi-net-pod
annotations:
k8s.v1.cni.cncf.io/networks: macvlan-conf, other-ns/ipvlan-conf
spec:
containers:
- name: app
image: nginx
2.5 网络附加定义(NAD)的配置规范
NAD 的 spec.config 字段必须是一个合法的 CNI 配置 JSON。Multus 对配置有以下要求:
- 必须包含
cniVersion:指定 CNI 规范版本,推荐0.3.1或1.0.0。 - 必须包含
type:指定委托 CNI 插件的名称,如macvlan、ipvlan、bridge。 - 可选包含
ipam:IP 地址管理配置,如果委托 CNI 需要 IPAM 则必须提供。 - 可选包含
capabilities:声明该网络支持的能力,如ips、mac。
2.6 Multus 与默认 CNI 的协作关系
Multus 通常与一个默认 CNI(如 Calico、Flannel、Cilium)配合使用。默认 CNI 负责 Pod 的主网络接口(eth0),而 Multus 负责附加网络接口(net1、net2 等)。
| 网络类型 | 接口名称 | 负责插件 | 用途 |
|---|---|---|---|
| 主网络 | eth0 | 默认 CNI(如 Calico) | 集群内通信、Service 访问 |
| 附加网络 1 | net1 | 委托 CNI(如 macvlan) | 外部网络直连、高性能数据面 |
| 附加网络 2 | net2 | 委托 CNI(如 ipvlan) | 存储网络、管理网络 |
Multus 通过 delegates 字段在 CNI 配置中声明默认 CNI 的位置:
{
"cniVersion": "0.3.1",
"name": "multus-cni-network",
"type": "multus",
"delegates": [
{
"type": "calico",
"name": "k8s-pod-network",
"capabilities": {"portMappings": true}
}
],
"kubeconfig": "/etc/cni/net.d/multus.d/multus.kubeconfig"
}
在这个配置中,delegates 数组的第一个元素定义了默认 CNI(Calico),Multus 会优先为 Pod 创建这个网络接口,然后再处理 Pod 注解中指定的附加网络。