Kubernetes本身不提供网络解决方案,但是提供了CNI规范。这些规范被许多CNI插件(例如WeaveNet,Flannel,Calico等)遵守。这些插件中任何一个都可以在集群上使用和部署以提供网络解决方案。该网络称为集群的默认网络。此默认网络使Pods不仅可以在同一节点上而且可以在群集中的各个节点之间相互通信。
随着发展,Kubernetes 缺乏支持VNF中多个网络接口的所需功能。传统上,网络功能使用多个网络接口分离控制,管理和控制用户/数据的网络平面。他们还用于支持不同的协议,满足不同的调整和配置要求。
为了解决这个需求,英特尔实现了MULTUS的CNI插件,其中提供了将多个接口添加到Pod的功能。这允许POD通过不同的接口连接到多个网络,并且每个接口都将使用其自己的CNI插件(CNI插件可以相同或不同。这完全取决于需求和实现)。
下面是Multus CNI提供的连接到Pod的网络接口的图示。该图显示了具有三个接口的容器:eth0,net0和net1。 eth0连接kubernetes集群网络以连接kubernetes服务器/服务(例如kubernetes api-server,kubelet等)。 net0和net1是其他网络附件,并通过使用其他CNI插件(例如vlan / vxlan / ptp)连接到其他网络。
二、MULTUS 工作原理
Kubernetes当前没有提供为POD添加额外的接口选项的规定,或支持多个CNI插件同时工作的规定,但是它确实提供了一种由api服务器扩展受支持的API的机制。使用“自定义资源定义”可以做到这一点。 MULTUS依赖于“自定义资源定义”来存储其他接口和CNI插件所需的信息。
我们首先需要确保将MULTUS二进制文件放置在/opt/cni/bin位置的所有节点上,并在/etc/cni/net.d位置创建一个新的配置文件。与MULTUS使用的kubeconfig文件一起使用。
在/etc/cni/net.d中创建的新配置文件基于集群中已经存在的默认网络配置。
在此之后,CRD用于定义新的种类名称“ NetworkAttachmentDefinition”,以及服务帐户和MULTUS的集群角色以及相应的绑定。这个新的集群角色将提供对随CRD添加的新API组以及默认API组中Pod资源的访问权限。
然后创建类型为“ NetworkAttachmentDefinition”的客户资源实例,该实例稍后将在创建具有多个接口的Pod时使用。
我们将在本文档中多次提及的两件事是:
- “默认网络”——这是您的 pod 到 pod 网络。这就是 pod 在集群中相互通信的方式,以及它们如何连接。一般来说,这表示为名为 的接口eth0。此接口始终连接到您的 Pod,以便它们之间可以建立连接。除此之外,我们还将添加接口。
- “CRD”——自定义资源定义。自定义资源是 Kubernetes API 扩展的一种方式。我们在这里使用这些来存储一些 Multus 可以读取的信息。首先,我们使用这些来存储附加到您的 Pod 的每个附加接口的配置。
我们的安装方法要求您首先安装 Kubernetes 并配置默认网络——即用于 pod 到 pod 连接的 CNI 插件。
我们推荐 Kubernetes 1.16 或更高版本。
要验证您的默认网络是否已准备就绪,您可以使用以下命令列出您的 Kubernetes 节点:
如果您的默认网络已准备就绪,您将看到每个节点的STATUS列也切换到Ready。
3、安装multus-cni
我们推荐的部署 Multus 的快速入门方法是使用 Daemonset(一种在集群中的每个节点上运行 Pod 的方法)进行部署,这会启动安装 Multus 二进制文件并配置 Multus 以供使用的 Pod。
首先,克隆这个 GitHub 存储库。
git clone https://github.com/k8snetworkplumbingwg/multus-cni.git && cd multus-cni
我们kubectl将从这个 repo应用一个 YAML 文件。
$ cat ./images/multus-daemonset.yml | kubectl apply -f -
Multus 守护进程的作用- 启动一个 Multus 守护进程,它在每个节点上运行一个 pod,在每个节点上放置一个 Multus 二进制文件 /opt/cni/bin
- 读取 中的字典/etc/cni/net.d序(按字母顺序)第一个配置文件,并为 Multus 创建一个新的配置文件 as /etc/cni/net.d/00-multus.conf,此配置是自动生成的,并基于默认网络配置(假定为按字母顺序排列的第一个配置)
- /etc/cni/net.d/multus.d在每个节点上创建一个包含身份验证信息的目录,以便 Multus 访问 Kubernetes API。
通常,验证安装的第一步是确保 Multus pod 无错误运行,您可以通过查看以下内容来了解这些内容的概述:
$ kubectl get pods --all-namespaces | grep -i multus
您可以通过查看/etc/cni/net.d/目录进一步验证它是否已运行,并确保自动生成的/etc/cni/net.d/00-multus.conf存在对应于按字母顺序排列的第一个配置文件。
创建附加接口我们要做的第一件事是为附加到 pod 的每个附加接口创建配置。我们将通过创建自定义资源来做到这一点。快速入门安装的一部分会创建一个“CRD”——一个自定义资源定义,它是我们保存这些自定义资源的家——我们将在这些中存储每个接口的配置。
CNI 配置我们将添加的每个配置都是一个 CNI 配置。如果您不熟悉它们,让我们快速分解它们。这是一个示例 CNI 配置:
{
"cniVersion": "0.3.0",
"type": "loopback",
"additional": "information"
}
CNI 配置是 JSON,我们在这里有一个结构,其中包含一些我们感兴趣的内容:
- cniVersion:告诉每个 CNI 插件正在使用哪个版本,如果它使用太晚(或太早)的版本,可以提供插件信息。
- type: 这告诉 CNI 在磁盘上调用哪个二进制文件。每个 CNI 插件都是一个被调用的二进制文件。通常,这些二进制文件存储在/opt/cni/bin每个节点上,CNI 执行此二进制文件。在这种情况下,我们指定了loopback二进制文件(它创建了一个环回类型的网络接口)。如果这是您第一次安装 Multus,您可能需要验证“类型”字段中的插件是否实际位于/opt/cni/bin目录中的磁盘上。
- additional: 这个字段放在这里作为例子,每个CNI插件可以在JSON中指定他们想要的任何配置参数。这些特定于您在type现场调用的二进制文件。
当 CNI 配置更改时,您不需要重新加载或刷新 Kubelets。这些是在每次创建和删除 pod 时读取的。因此,如果您更改配置,它将在下次创建 pod 时应用。如果现有 pod 需要新配置,则可能需要重新启动它们。
4、使用multus-cni 将配置存储为自定义资源所以,我们要创建一个额外的接口。让我们创建一个 macvlan 接口供 pod 使用。我们将创建一个自定义资源来定义接口的 CNI 配置。
请注意,在以下命令中,有一个kind: NetworkAttachmentDefinition. 这是我们对配置的奇特名称——它是 Kubernetes 的自定义扩展,定义了我们如何将网络附加到我们的 pod。
其次,注意config字段。您会看到这是一个 CNI 配置,就像我们之前解释的那样。
最后但非常重要的是,请注意metadata该name字段下的内容——这里是我们为此配置命名的地方,也是我们告诉 pod 使用此配置的方式。这里的名称是macvlan-conf——因为我们正在为 macvlan 创建配置。
这是创建此示例配置的命令:
cat <注意:此示例eth0用作master参数,此主参数应与群集中主机上的物理接口名称匹配。若用此macvlan-conf接口创建pod时,Node节点上不存在eth0时将创建失败。
您可以使用以下方法查看您创建的配置kubectl:
kubectl get network-attachment-definitions
您可以通过描述它们来获得更多详细信息:
kubectl describe network-attachment-definitions macvlan-conf
创建附加接口的 pod
我们将创建一个 pod。这看起来与您之前创建的任何 pod 一样熟悉,但是,我们将有一个特殊的annotations字段——在本例中,我们将有一个名为k8s.v1.cni.cncf.io/networks. 该字段采用NetworkAttachmentDefinition我们在上面创建的s名称的逗号分隔列表。注意,在下面,我们有注释的命令k8s.v1.cni.cncf.io/networks: macvlan-conf在那里macvlan-conf是我们在我们创建我们的配置上面使用的名称。
让我们继续使用以下命令创建一个 pod(它只是休眠了很长时间):
cat <您现在可以检查 pod 并查看附加了哪些接口,如下所示:
$ kubectl exec -it samplepod -- ip a
您应该注意到有 3 个接口:
网络状态注释
- lo 环回接口
- eth0 我们的默认网络
- net1 我们使用 macvlan 配置创建的新界面。
对于额外的确认,使用kubectl describe pod samplepod并且会有一个注释部分,类似于以下内容:
Annotations: k8s.v1.cni.cncf.io/networks: macvlan-conf k8s.v1.cni.cncf.io/networks-status: [{ "name": "cbr0", "ips": [ "10.244.1.73" ], "default": true, "dns": {} },{ "name": "macvlan-conf", "interface": "net1", "ips": [ "192.168.1.205" ], "mac": "86:1d:96:ff:55:0d", "dns": {} }]这个元数据告诉我们我们有两个 CNI 插件成功运行。
如果我想要更多接口怎么办?您可以通过创建更多自定义资源然后在 pod 的注解中引用它们来向 pod 添加更多接口。您还可以重用配置,例如,要将两个 macvlan 接口附加到一个 pod,您可以像这样创建一个 pod:
cat <请注意,注释现在显示为k8s.v1.cni.cncf.io/networks: macvlan-conf,macvlan-conf。我们使用了两次相同的配置,用逗号分隔。
如果您要使用名称创建另一个自定义资源,foo您可以使用例如: k8s.v1.cni.cncf.io/networks: foo,macvlan-conf,并使用任意数量的附件。
请注意若我们集群里只有一台机器有多于物理网卡时,我们将给node打上标签。然后在创建部署的时候通过使用nodeSelector标签指定Pod运行在有多余物理网卡的node上。否则Pod将创建失败。



