注:
- 此教程需要访问 Oracle Cloud。要注册免费账户,请参阅开始使用 Oracle Cloud Infrastructure Free Tier 。
- 它使用 Oracle Cloud Infrastructure 身份证明、租户和区间示例值。完成实验室时,请将这些值替换为特定于云环境的那些值。
为基于 VM 的 Oracle Container Engine for Kubernetes 节点使用 Multus 为 pod 配置 SR-IOV 接口
简介
当面向高网络的工作负载需要设置云池中的辅助网络接口时,我们可以使用 Multus 等元 CNI 来实现这一目标。在这些情况下通常连接的辅助网络接口将具有专用网络功能或属性,例如单根 IO 虚拟化 (Single Root IO Virtualization,SR-IOV)。
在早期的教程中:为使用多用户(适用于裸金属 OKE 节点)的云池配置 SR-IOV 接口(可以从“相关链接”部分访问该链接),我们介绍了如何在 Oracle Cloud Infrastructure (OCI) 上的裸金属 Kubernetes 节点上实现此目的,在连接到裸金属实例的硬件上直接创建虚拟功能 (Virtual Functions,VF)。
本教程采用 Oracle Container Engine for Kubernetes (OKE) 集群中虚拟机节点的类似方法,并采用与裸机节点上使用的配置和插件不同的类似方法。在裸金属之间创建和管理接口的方式存在显著差异。在裸金属之间,您可以完全控制虚拟机管理程序对底层硬件的访问进行抽象并且您对底层硬件的控制权没有那么大。
此处描述的方法使用 Multus 向 pod 提供多个接口,但是不使用 SR-IOV CNI 和关联的设备插件。这是因为 SR-IOV CNI 需要访问底层硬件,物理功能 (physical function,PF),这显然对虚拟机构成了挑战。为了克服这一难题,我们可以使用适用于 VNIC 的 OCI 网络 API,在裸金属方案中的物理功能 (Physical Function,PF) 上创建虚拟功能 (Virtual Function,VF),并为 VM 提供对此 VF 的直接访问和不受阻碍的访问。这些 VF 可以作为网络接口连接到计算实例,包括 OKE 节点。这些接口/VF 可以移动到 pod 的网络名称空间,从而允许 pod 直接和独占使用 VF 作为网络接口。从云池的角度来看,它无法区分两者,在两种情况下,它们都可以访问可以直接使用的 VF。
要将 VM 直接访问 VF,需要启动具有 VFIO 网络连接模式的 VM,而不是默认的半虚拟化模式。此选择由计算实例的启动模式控制。网络连接模式设置为 VFIO 后,我们可以使用 OCI API 创建网络连接,从而在底层 PF 上创建 VF 并直接向 VM 提供 VF。主机上的 OS 会将这些接口识别为网络接口。当 VF 可用于 VM 时,可以将其移至 pod 名称空间。在此模型中,使用 OCI API 创建 VF,而不是使用裸机方案中的系统命令创建 VF。
目标
为基于 VM 的 Oracle Container Engine for Kubernetes 节点使用 Multus 配置 pod 的 SR-IOV 接口。
先决条件
- 具有至少包含两个 VM 的节点池的 OKE 群集。
注:此教程已在使用 Flannel 网络(作为主 CNI 的通道)的 OKE 集群上进行验证。
任务 1:设置节点
需要访问 SR-IOV 接口的每个节点都必须针对硬件辅助的网络附件做好准备,然后 pod 才能使用它们。
-
以 VFIO 模式引导节点
-
在集群中创建节点池和一组节点。
-
创建节点后,编辑实例属性。
-
在实例属性上,单击显示高级选项以查看其他属性。在启动选项选项卡上,为网络类型选择硬件辅助 (SR-IOV) 网络。
注:将实例切换为硬件辅助(SR-IOV 或 VFIO)模式的半虚拟化网络连接后,它们不再有资格进行实时迁移以进行基础结构维护。
-
更新工作流将提示您重新引导实例。重新引导后,实例将具有 VFIO 网络附件。这可以在控制台上进行验证。
-
验证实例是否使用 SR-IOV 网络附件的另一种方法是通过 SSH 连接到节点并使用
lspci
列出 VM 上的 PCI 设备。您应该能够直接在 VM 上查看底层虚拟功能,而不是使用virtio
驱动程序的设备(例如下图中的存储控制器)。 -
此时,节点具有单个 VNIC 附件,这是用于与节点的所有通信的主要 VNIC。由于实例使用硬件辅助网络连接,因此该节点在底层硬件上作为虚拟功能可见的网络连接。要使云池独占使用虚拟功能 (Virtual Function,VF),我们需要 VM 上的其他 VF。可以使用控制台或 API 将其他 VNIC 附件添加到实例中。这些 VNIC 附件是底层 PF 上的 VF。可以使用
lspci
验证这些信息。
-
-
添加其他 VNIC 附件
-
从实例页中选择附加的 VNIC ,然后单击创建 VNIC 。
-
使用所需的 VCN 和子网配置 VNIC。
-
通过在节点上启用 SSH 并运行
lspci
,验证是否可以在主机上将 VNIC 视为虚拟功能。 -
将辅助 VNIC 添加到 Linux VM 实例时,会将新接口(即以太网设备)添加到实例并由 OS 自动识别。但是,对于辅助 VNIC,DHCP 不是活动的,您必须使用静态 IP 地址和默认路由配置接口。
-
-
为辅助 VNIC 配置 OS
-
OCI 提供了用于为辅助 VNIC 配置 OS 的文档和脚本。要配置辅助 VNIC,请下载节点上的脚本,并根据 OCI 文档中提供的说明运行该脚本。
Note: The secondary VNICs on each node must be set up by repeating these steps for each node. These steps can be optionally and automated using a custom
cloud_init
script for the nodes. -
验证接口现在是否已连接,以及其 IP 地址和默认路由。要进行检查,请使用命令
ip addr
或nmcli
。 -
(可选)使用 ping 验证路由以相互访问辅助 IP 地址。在下面的图像中,
10.0.10.238
是群集中第二个节点上的辅助 IP。
-
任务 2:安装 MetaPlugin CNI(多用户)
Multus 是一个元插件,它可以向下游 CNI 提供 VF 信息,例如 SR-IOV CNI 插件,用于在启用具有多个网络接口的“多宿主”云池或云池时处理网络资源检测。
注意:Multus 4.0 之后,Multus 引入了一个称为“简单插件”的新客户端 - 服务器样式部署。新的厚插件支持其他功能,例如以前不受支持的度量。本文档使用“瘦”插件,因为它使用的资源更少。
-
要安装 Multus,请运行以下命令。
git clone https://github.com/k8snetworkplumbingwg/multus-cni.git && cd multus-cni kubectl apply -f deployments/multus-daemonset.yml && cd ..
注:安装时,标记为
stable
的守护进程集使用的默认映像需要 kubelet 为 v1.20.x。如果在较旧的群集上进行安装,请编辑清单中的 deamonset 并使用多用户映像标记v3.7.1
。
此清单为 kind:NetworkAttachmentDefinition
创建新的 CRD 并通过守护进程集在所有节点上提供 Multus 二进制文件。可以通过确保在节点上运行 Multus 守护进程集来验证安装。
任务 3:将多个接口连接到 pod
-
要将其他接口连接到 pod,需要配置接口才能连接。这封装在
NetworkAttachmentDefinition
类型的定制资源中。此配置本质上是打包为定制资源的 CNI 配置。 -
有多个 CNI 插件可以与 Multus 一起使用来完成此任务。在此介绍的方法中,目标是专门为单个 pod 提供 SR-IOV 虚拟功能,以便 pod 可以利用功能而不受干扰或介于两者之间的任何层。要授予对 VF 的 pod 独占访问权限,我们可以利用 host-device plug-in 将接口移入 pod 的名称空间,使其具有独占访问权限。
-
以下示例显示了配置添加到节点的辅助
ens5
接口的NetworkAttachmentDefinition
对象。ipam
插件配置确定如何为这些接口管理 IP 地址。在此示例中,由于要使用 OCI 分配给辅助接口的相同 IP 地址,因此我们使用静态ipam
配置和相应的路由。ipam
配置还支持其他方法,例如host-local
或dhcp
,以实现更灵活的配置。## network attachment for the first node. Note the IPaddress assignment in the `ipam` configuration. cat << EOF | kubectl create -f - apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: sriov-vnic-1 spec: config: '{ "cniVersion": "0.3.1", "type": "host-device", "device": "ens5", "ipam": { "type": "static", "addresses": [ { "address": "10.0.10.93/24", "gateway": "0.0.0.0" } ], "routes": [ { "dst": "10.0.10.0/24", "gw": "0.0.0.0" } ] } }' EOF ## network attachment for the second node. Note the IPaddress assignment in the `ipam` configuration. cat << EOF | kubectl create -f - apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: sriov-vnic-2 spec: config: '{ "cniVersion": "0.3.1", "type": "host-device", "device": "ens5", "ipam": { "type": "static", "addresses": [ { "address": "10.0.10.238/24", "gateway": "0.0.0.0" } ], "routes": [ { "dst": "10.0.10.0/24", "gw": "0.0.0.0" } ] } }' EOF
任务 4:部署具有多个接口和测试的云池
Pod 现在可以使用注释请求其他接口。通过注释,元插件(多用户)可以了解创建 pod 时要使用的 NetworkAttachmentDefinition
(CNI 配置)来提供其他接口。
注:使用静态配置(如本示例中所示配置)时,pod 需要设置节点关联性,以便在所需主机设备可用的节点上调度 pod。
-
下面是一个带测试 pod 的示例:
## Create the first pod cat << EOF | kubectl create -f - apiVersion: v1 kind: Pod metadata: name: testpod1 annotations: k8s.v1.cni.cncf.io/networks: sriov-vnic-1 spec: containers: - name: appcntr1 image: centos/tools imagePullPolicy: IfNotPresent command: [ "/bin/bash", "-c", "--" ] args: [ "while true; do sleep 300000; done;" ] EOF ## Create a second pod cat << EOF | kubectl create -f - apiVersion: v1 kind: Pod metadata: name: testpod2 annotations: k8s.v1.cni.cncf.io/networks: sriov-vnic spec: containers: - name: appcntr1 image: centos/tools imagePullPolicy: IfNotPresent command: [ "/bin/bash", "-c", "--" ] args: [ "while true; do sleep 300000; done;" ] EOF
-
创建了两个 pod,我们应该看到它们都在运行。我们应该能够看到在创建云池期间创建了额外的网络接口。Multus 将提供默认 CNI(本例中的通道)支持的
eth0
接口以及 SR-IOV 虚拟功能的其他net1
接口。您可以describe
pod 并观察输出的事件部分以查看各种事件,包括连接到 pod 的接口。 -
云池启动后,可以执行快速测试。
## Verify that both pods have two interfaces. An `eth0` on the overlay and a `net1` which is the VF, along with the IP address for the secondary VNIC. kubectl exec -it testpod1 -- ip addr show kubectl exec -it testpod2 -- ip addr show
-
输出应类似于以下图像。
-
我们还可以通过这些辅助接口验证两个云池之间的通信。
## test communication kubectl exec -it testpod1 -- ping -I net1 <ip address for secondary vnic on the other pod/node> kubectl exec -it testpod2 -- ping -I net1 <ip address for secondary vnic on the other pod/node>
-
输出应类似于以下图像。
-
我们还可以通过尝试从 VM 或 VCN 中的任何其他源访问 pod,验证这些 pod 是否可以使用其网络连接进行路由。
## Test that the pod is routable from outside Kubernetes. This is executed from node1. ping 10.0.10.238 ## similarly, from node 2 ping 10.0.10.93
-
输出应类似于以下映像。
相关链接
确认
- 作者 - Jeevan Joseph(主要产品经理)
更多学习资源
探索 docs.oracle.com/learn 上的其他实验室,或者访问 Oracle Learning YouTube 频道上的更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。
Configure SR-IOV interfaces for pods using Multus for VM-based Oracle Container Engine for Kubernetes nodes
F80585-01
May 2023
Copyright © 2023, Oracle and/or its affiliates.