24.4. 配置 SR-IOV 网络设备
您可以在集群中配置单一根 I/O 虚拟化(SR-IOV)设备。
24.4.1. SR-IOV 网络节点配置对象
您可以通过创建 SR-IOV 网络节点策略来为节点指定 SR-IOV 网络设备配置。策略的 API 对象是 sriovnetwork.openshift.io
API 组的一部分。
以下 YAML 描述了 SR-IOV 网络节点策略:
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: <name> 1 namespace: openshift-sriov-network-operator 2 spec: resourceName: <sriov_resource_name> 3 nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" 4 priority: <priority> 5 mtu: <mtu> 6 needVhostNet: false 7 numVfs: <num> 8 nicSelector: 9 vendor: "<vendor_code>" 10 deviceID: "<device_id>" 11 pfNames: ["<pf_name>", ...] 12 rootDevices: ["<pci_bus_id>", ...] 13 netFilter: "<filter_string>" 14 deviceType: <device_type> 15 isRdma: false 16 linkType: <link_type> 17 eSwitchMode: <mode> 18 excludeTopology: false 19
- 1
- 自定义资源对象的名称。
- 2
- 安装 SR-IOV Network Operator 的命名空间。
- 3
- SR-IOV 网络设备插件的资源名称。您可以为资源名称创建多个 SR-IOV 网络节点策略。
在指定名称时,请确保在
resourceName
中使用接受的语法表达式^[a-zA-Z0-9_]+$
。 - 4
- 节点选择器指定要配置的节点。只有所选节点上的 SR-IOV 网络设备才会被配置。SR-IOV Container Network Interface(CNI)插件和设备插件仅在所选节点上部署。重要
SR-IOV Network Operator 按顺序将节点网络配置策略应用到节点。在应用节点网络配置策略前,SR-IOV Network Operator 会检查节点的机器配置池(MCP)是否处于不健康状态,如
Degraded
或Updating
。如果节点处于不健康的 MCP,将节点网络配置策略应用到集群中的所有目标节点的过程会被暂停,直到 MCP 返回健康状态。为了避免处于不健康的 MCP 的节点阻止将节点网络配置策略应用到其他节点,包括处于其他 MCP 的节点,您必须为每个 MCP 创建单独的节点网络配置策略。
- 5
- 可选: priority 是一个
0
到99
之间的整数。较小的值具有更高的优先级。例如,优先级10
是高于优先级99
。默认值为99
。 - 6
- 可选:虚拟功能的最大传输单元(MTU)。最大 MTU 值可能因不同的网络接口控制器(NIC)型号而有所不同。重要
如果要在默认网络接口上创建虚拟功能,请确保将 MTU 设置为与集群 MTU 匹配的值。
- 7
- 可选:将
needVhostNet
设置为true
,以在 pod 中挂载/dev/vhost-net
设备。使用挂载的/dev/vhost-net
设备及 Data Plane Development Kit (DPDK) 将流量转发到内核网络堆栈。 - 8
- 为 SR-IOV 物理网络设备创建的虚拟功能((VF)的数量。对于 Intel 网络接口控制器(NIC),VF 的数量不能超过该设备支持的 VF 总数。对于 Mellanox NIC,VF 的数量不能超过
127
。 - 9
- NIC 选择器标识要配置的 Operator 的设备。您不必为所有参数指定值。建议您足够精确地识别网络设备以避免意外选择设备。
如果指定了
rootDevices
,则必须同时为vendor
、deviceID
或pfNames
指定一个值。如果同时指定了pfNames
和rootDevices
,请确保它们引用同一设备。如果您为netFilter
指定了一个值,那么您不需要指定任何其他参数,因为网络 ID 是唯一的。 - 10
- 可选: SR-IOV 网络设备的厂商十六进制代码。允许的值只能是
8086
和15b3
。 - 11
- 可选: SR-IOV 网络设备的设备十六进制代码。例如,
101b
是 Mellanox ConnectX-6 设备的设备 ID。 - 12
- 可选:该设备的一个或多个物理功能(PF)名称的数组。
- 13
- 可选:用于该设备的 PF 的一个或多个 PCI 总线地址的数组。使用以下格式提供地址:
0000:02:00.1
。 - 14
- 可选:特定平台的网络过滤器。唯一支持的平台是 Red Hat OpenStack Platform(RHOSP)。可接受的值具有以下格式:
openstack/NetworkID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
。将xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx
替换为来自/var/config/openstack/latest/network_data.json
元数据文件的值。 - 15
- 可选:虚拟功能的驱动程序类型。允许的值只能是
netdevice
和vfio-pci
。默认值为netdevice
。对于裸机节点上的 DPDK 模式的 Mellanox NIC,请使用
netdevice
驱动程序类型,并将isRdma
设置为true
。 - 16
- 可选:配置是否启用远程直接访问 (RDMA) 模式。默认值为
false
。如果
isRdma
参数设为true
,您可以继续使用启用了 RDMA 的 VF 作为普通网络设备。设备可在其中的一个模式中使用。将
isRdma
设置为true
,并将needVhostNet
设置为true
以配置 Mellanox NIC 以用于 Fast Datapath DPDK 应用程序。注意对于 intel NIC,您无法将
isRdma
参数设置为true
。 - 17
- 可选:VF 的链接类型。默认值为
eth
(以太网)。在 InfiniBand 中将这个值改为 'ib'。当将
linkType
设置为ib
时,SR-IOV Network Operator Webhook 会自动将isRdma
设置为true
。当将linkType
设定为ib
时,deviceType
不应该被设置为vfio-pci
。不要为 SriovNetworkNodePolicy 将 linkType 设置为 'eth',因为这可能会导致设备插件报告的可用设备数量不正确。
- 18
- 可选:NIC 设备模式。允许的值只能是
legacy
或switchdev
。当将
eSwitchMode
设置为legacy
时,会启用默认的 SR-IOV 行为。当将
eSwitchMode
设置为switchdev
时,会启用硬件卸载。 - 19
- 可选:要排除将一个 SR-IOV 网络资源的 NUMA 节点广告到拓扑管理器,将值设为
true
。默认值为false
。
24.4.1.1. SR-IOV 网络节点配置示例
以下示例描述了 InfiniBand 设备的配置:
InfiniBand 设备的配置示例
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: policy-ib-net-1 namespace: openshift-sriov-network-operator spec: resourceName: ibnic1 nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" numVfs: 4 nicSelector: vendor: "15b3" deviceID: "101b" rootDevices: - "0000:19:00.0" linkType: ib isRdma: true
以下示例描述了 RHOSP 虚拟机中的 SR-IOV 网络设备配置:
虚拟机中的 SR-IOV 设备配置示例
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: policy-sriov-net-openstack-1 namespace: openshift-sriov-network-operator spec: resourceName: sriovnic1 nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" numVfs: 1 1 nicSelector: vendor: "15b3" deviceID: "101b" netFilter: "openstack/NetworkID:ea24bd04-8674-4f69-b0ee-fa0b3bd20509" 2
24.4.1.2. SR-IOV 设备的虚拟功能 (VF) 分区
在某些情况下,您可能想要将同一个物理功能 (PF) 的虚拟功能 (VF) 分成多个资源池。例如: 您可能想要某些 VF 使用默认驱动程序载入,而其他的 VF 负载使用 vfio-pci
驱动程序。在这样的部署中,您可以使用SriovNetworkNodePolicy 自定义资源 (CR) 中的 pfNames
选项器(selector)来为池指定 VF 的范围,其格式为: <pfname>#<first_vf>-<last_vf>
。
例如,以下 YAML 显示名为 netpf0
的、带有 VF 2
到 7
的接口的选择器:
pfNames: ["netpf0#2-7"]
-
netpf0
是 PF 接口名称。 -
2
是包含在范围内的第一个 VF 索引(基于 0)。 -
7
是包含在范围内的最后一个 VF 索引(基于 0)。
如果满足以下要求,您可以使用不同的策略 CR 从同一 PF 中选择 VF:
-
选择相同 PF 的不同策略的
numVfs
值必须相同。 -
VF 索引范围是从
0
到<numVfs>-1
之间。例如,如果您有一个策略,它的numVfs
被设置为8
,则<first_vf>
的值不能小于0
,<last_vf>
的值不能大于7
。 - 不同策略中的 VF 范围不得互相重叠。
-
<first_vf>
不能大于<last_vf>
。
以下示例演示了 SR-IOV 设备的 NIC 分区。
策略 policy-net-1
定义了一个资源池 net-1
,其中包含带有默认 VF 驱动的 PF netpf0
的 VF 0
。策略 policy-net-1-dpdk
定义了一个资源池 net-1-dpdk
,其中包含带有 vfio
VF 驱动程序的 PF netpf0
的 VF 8
到 15
。
策略 policy-net-1
:
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: policy-net-1 namespace: openshift-sriov-network-operator spec: resourceName: net1 nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" numVfs: 16 nicSelector: pfNames: ["netpf0#0-0"] deviceType: netdevice
策略 policy-net-1-dpdk
:
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: policy-net-1-dpdk namespace: openshift-sriov-network-operator spec: resourceName: net1dpdk nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" numVfs: 16 nicSelector: pfNames: ["netpf0#8-15"] deviceType: vfio-pci
验证接口是否已成功分区
运行以下命令,确认 SR-IOV 设备的接口分区到虚拟功能(VF)。
$ ip link show <interface> 1
- 1
- 将
<interface>
替换为您在分区为 SR-IOV 设备的 VF 时指定的接口,如ens3f1
。
输出示例
5: ens3f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 3c:fd:fe:d1:bc:01 brd ff:ff:ff:ff:ff:ff vf 0 link/ether 5a:e7:88:25:ea:a0 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off vf 1 link/ether 3e:1d:36:d7:3d:49 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off vf 2 link/ether ce:09:56:97:df:f9 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off vf 3 link/ether 5e:91:cf:88:d1:38 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off vf 4 link/ether e6:06:a1:96:2f:de brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off
24.4.2. 配置 SR-IOV 网络设备
SR-IOV Network Operator 把 SriovNetworkNodePolicy.sriovnetwork.openshift.io
CRD 添加到 OpenShift Container Platform。您可以通过创建一个 SriovNetworkNodePolicy 自定义资源 (CR) 来配置 SR-IOV 网络设备。
在应用由 SriovNetworkNodePolicy
对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。
它可能需要几分钟时间来应用配置更改。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
您可以使用具有
cluster-admin
角色的用户访问集群。 - 已安装 SR-IOV Network Operator。
- 集群中有足够的可用节点,用于处理从排空节点中驱除的工作负载。
- 您还没有为 SR-IOV 网络设备配置选择任何 control plane 节点。
流程
-
创建一个
SriovNetworkNodePolicy
对象,然后在<name>-sriov-node-network.yaml
文件中保存 YAML。使用配置的实际名称替换<name>
。 -
可选:将 SR-IOV 功能的集群节点标记为
SriovNetworkNodePolicy.Spec.NodeSelector
(如果它们还没有标记)。有关标记节点的更多信息,请参阅"了解如何更新节点上的标签"。 创建
SriovNetworkNodePolicy
对象:$ oc create -f <name>-sriov-node-network.yaml
其中
<name>
指定这个配置的名称。在应用配置更新后,
sriov-network-operator
命名空间中的所有 Pod 都会变为Running
状态。要验证是否已配置了 SR-IOV 网络设备,请输入以下命令。将
<node_name>
替换为带有您刚才配置的 SR-IOV 网络设备的节点名称。$ oc get sriovnetworknodestates -n openshift-sriov-network-operator <node_name> -o jsonpath='{.status.syncStatus}'
其他资源
24.4.3. SR-IOV 配置故障排除
在进行了配置 SR-IOV 网络设备的步骤后,以下部分会处理一些错误条件。
要显示节点状态,请运行以下命令:
$ oc get sriovnetworknodestates -n openshift-sriov-network-operator <node_name>
其中: <node_name>
指定带有 SR-IOV 网络设备的节点名称。
错误输出: 无法分配内存
"lastSyncError": "write /sys/bus/pci/devices/0000:3b:00.1/sriov_numvfs: cannot allocate memory"
当节点表示无法分配内存时,检查以下项目:
- 确认在 BIOS 中为节点启用了全局 SR-IOV 设置。
- 确认在 BIOS 中为该节点启用了 VT-d。
24.4.4. 将 SR-IOV 网络分配给 VRF
作为集群管理员,您可以使用 CNI VRF 插件为 VRF 域分配 SR-IOV 网络接口。
要做到这一点,将 VRF 配置添加到 SriovNetwork
资源的可选 metaPlugins
参数中。
使用 VRF 的应用程序需要绑定到特定设备。通常的用法是在套接字中使用 SO_BINDTODEVICE
选项。SO_BINDTODEVICE
将套接字绑定到在传递接口名称中指定的设备,例如 eth1
。要使用 SO_BINDTODEVICE
,应用程序必须具有 CAP_NET_RAW
功能。
OpenShift Container Platform pod 不支持通过 ip vrf exec
命令使用 VRF。要使用 VRF,将应用程序直接绑定到 VRF 接口。
24.4.4.1. 使用 CNI VRF 插件创建额外的 SR-IOV 网络附加
SR-IOV Network Operator 管理额外网络定义。当您指定要创建的额外 SR-IOV 网络时,SR-IOV Network Operator 会自动创建 NetworkAttachmentDefinition
自定义资源(CR)。
不要编辑 SR-IOV Network Operator 所管理的 NetworkAttachmentDefinition
自定义资源。这样做可能会破坏额外网络上的网络流量。
要使用 CNI VRF 插件创建额外的 SR-IOV 网络附加,请执行以下步骤。
先决条件
- 安装 OpenShift Container Platform CLI(oc)。
- 以具有 cluster-admin 权限的用户身份登录 OpenShift Container Platform 集群。
流程
为额外 SR-IOV 网络附加创建
SriovNetwork
自定义资源 (CR) 并插入metaPlugins
配置,如下例所示。将 YAML 保存为文件sriov-network-attachment.yaml
。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: example-network namespace: additional-sriov-network-1 spec: ipam: | { "type": "host-local", "subnet": "10.56.217.0/24", "rangeStart": "10.56.217.171", "rangeEnd": "10.56.217.181", "routes": [{ "dst": "0.0.0.0/0" }], "gateway": "10.56.217.1" } vlan: 0 resourceName: intelnics metaPlugins : | { "type": "vrf", 1 "vrfname": "example-vrf-name" 2 }
创建
SriovNetwork
资源:$ oc create -f sriov-network-attachment.yaml
验证 NetworkAttachmentDefinition
CR 是否已成功创建
运行以下命令,确认 SR-IOV Network Operator 创建了
NetworkAttachmentDefinition
CR。$ oc get network-attachment-definitions -n <namespace> 1
- 1
- 将
<namespace>
替换为您在配置网络附加时指定的命名空间,如additional-sriov-network-1
。
输出示例
NAME AGE additional-sriov-network-1 14m
注意SR-IOV Network Operator 创建 CR 之前可能会有延迟。
验证额外 SR-IOV 网络附加是否成功
要验证 VRF CNI 是否已正确配置并附加额外的 SR-IOV 网络附加,请执行以下操作:
- 创建使用 VRF CNI 的 SR-IOV 网络。
- 将网络分配给 pod。
验证 pod 网络附加是否已连接到 SR-IOV 额外网络。远程 shell 到 pod 并运行以下命令:
$ ip vrf show
输出示例
Name Table ----------------------- red 10
确认 VRF 接口是从属接口的主接口:
$ ip link
输出示例
... 5: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master red state UP mode ...
24.4.5. 为 NUMA 感知调度排除 SR-IOV 网络拓扑
在 NUMA 感知 pod 调度过程中,可以排除将 SR-IOV 网络的 Non-Uniform Memory Access (NUMA) 节点广告到拓扑管理器,以便实现更灵活的 SR-IOV 网络部署。
在某些情况下,为在单个 NUMA 节点上的一个 pod 最大化 CPU 和内存资源是一个优先操作。如果没有为 Topology Manager 提供有关 pod 的 SR-IOV 网络资源的 NUMA 节点的提示,拓扑管理器可能会将 SR-IOV 网络资源和 pod CPU 和内存资源部署到不同的 NUMA 节点。这可能会添加到网络延迟,因为需要在不同 NUMA 节点之间进行数据传输。但是,当工作负载需要最佳 CPU 和内存性能时,这是可以接受的。
例如,有一个计算节点 compute-1
,它有两个 NUMA 节点:numa0
和 numa1
。启用了 SR-IOV 的 NIC 存在于 numa0
上。可用于 pod 调度的 CPU 仅存在于 numa1
上。通过将 excludeTopology
规格设置为 true
,拓扑管理器可将 pod 的 CPU 和内存资源分配给 numa1
,并可将同一 pod 的 SR-IOV 网络资源分配给 numa0
。只有将 excludeTopology
规格设置为 true
时,才能实现。否则,拓扑管理器会尝试将所有资源放在同一 NUMA 节点上。
24.4.5.1. 排除 NUMA 感知调度的 SR-IOV 网络拓扑
要将 SR-IOV 网络资源的 Non-Uniform Memory Access (NUMA)节点排除到拓扑管理器,您可以在 SriovNetworkNodePolicy
自定义资源中配置 excludeTopology
规格。在 NUMA 感知 pod 调度过程中,使用此配置来实现更灵活的 SR-IOV 网络部署。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
您已将 CPU Manager 策略配置为
static
。有关 CPU Manager 的更多信息,请参阅附加资源部分。 -
您已将 Topology Manager 策略配置为
single-numa-node
。 - 已安装 SR-IOV Network Operator。
流程
创建
SriovNetworkNodePolicy
CR:将以下 YAML 保存到
sriov-network-node-policy.yaml
文件中,替换 YAML 中的值以匹配您的环境:apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: <policy_name> namespace: openshift-sriov-network-operator spec: resourceName: sriovnuma0 1 nodeSelector: kubernetes.io/hostname: <node_name> numVfs: <number_of_Vfs> nicSelector: 2 vendor: "<vendor_ID>" deviceID: "<device_ID>" deviceType: netdevice excludeTopology: true 3
注意如果多个
SriovNetworkNodePolicy
资源都以同一 SR-IOV 网络资源为目标,则SriovNetworkNodePolicy
资源必须具有与excludeTopology
规格相同的值。否则,冲突策略将被拒绝。运行以下命令来创建
SriovNetworkNodePolicy
资源:$ oc create -f sriov-network-node-policy.yaml
输出示例
sriovnetworknodepolicy.sriovnetwork.openshift.io/policy-for-numa-0 created
创建
SriovNetwork
CR:将以下 YAML 保存到
sriov-network.yaml
文件中,替换 YAML 中的值以匹配您的环境:apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: sriov-numa-0-network 1 namespace: openshift-sriov-network-operator spec: resourceName: sriovnuma0 2 networkNamespace: <namespace> 3 ipam: |- 4 { "type": "<ipam_type>", }
运行以下命令来创建
SriovNetwork
资源:$ oc create -f sriov-network.yaml
输出示例
sriovnetwork.sriovnetwork.openshift.io/sriov-numa-0-network created
创建 pod 并从上一步中分配 SR-IOV 网络资源:
将以下 YAML 保存到
sriov-network-pod.yaml
文件中,替换 YAML 中的值以匹配您的环境:apiVersion: v1 kind: Pod metadata: name: <pod_name> annotations: k8s.v1.cni.cncf.io/networks: |- [ { "name": "sriov-numa-0-network", 1 } ] spec: containers: - name: <container_name> image: <image> imagePullPolicy: IfNotPresent command: ["sleep", "infinity"]
- 1
- 这是使用
SriovNetworkNodePolicy
资源的SriovNetwork
资源的名称。
运行以下命令来创建
Pod
资源:$ oc create -f sriov-network-pod.yaml
输出示例
pod/example-pod created
验证
运行以下命令,将
<pod_name>
替换为 pod 的名称来验证 pod 的状态:$ oc get pod <pod_name>
输出示例
NAME READY STATUS RESTARTS AGE test-deployment-sriov-76cbbf4756-k9v72 1/1 Running 0 45h
打开目标 pod 的 debug 会话,以验证 SR-IOV 网络资源是否已部署到与内存和 CPU 资源不同的节点上。
运行以下命令,使用 pod 打开 debug 会话,将 <pod_name> 替换为目标 pod 名称。
$ oc debug pod/<pod_name>
将
/host
设为 debug shell 中的根目录。debug pod 从 pod 中的/host
中的主机挂载 root 文件系统。将根目录改为/host
,您可以从主机文件系统中运行二进制文件:$ chroot /host
运行以下命令,查看有关 CPU 分配的信息:
$ lscpu | grep NUMA
输出示例
NUMA node(s): 2 NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,... NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,...
$ cat /proc/self/status | grep Cpus
输出示例
Cpus_allowed: aa Cpus_allowed_list: 1,3,5,7
$ cat /sys/class/net/net1/device/numa_node
输出示例
0
在本例中,CPU 1,3,5 和 7 分配给
NUMA node1
,但 SR-IOV 网络资源可以使用NUMA node0
中的 NIC。
如果 excludeTopology
规格被设置为 True
,则同一 NUMA 节点上可能存在所需资源。
其他资源