设置 SR-IOV 网络

本文档介绍了如何为 Google Distributed Cloud 设置单根输入/输出虚拟化 (SR-IOV) 网络。SR-IOV 提供 I/O 虚拟化,使网络接口卡 (NIC) 可作为 Linux 内核中的网络设备使用;以便您可以管理和分配 pod 的网络连接。在这种情况下数据包直接在 NIC 和 pod 之间移动,因此性能也会得到提升。

如果您需要通过网络快速连接到 pod 工作负载,则可以使用此功能。借助适用于 Google Distributed Cloud 的 SR-IOV,您可以在集群节点的受支持设备上配置虚拟函数 (VF)。您还可以指定要绑定到 VF 的特定内核模块。

此功能适用于运行工作负载的集群,例如混合集群、独立集群和用户集群。 SR-IOV 网络连接功能要求集群至少具有两个节点。

设置过程包括以下简要步骤:

  1. 配置集群以启用 SR-IOV 网络连接。
  2. 配置 SR-IOV 运算符,这是一种 SriovOperatorConfig 自定义资源。
  3. 设置 SR-IOV 政策并配置 VF。
  4. 创建引用 VF 的 NetworkAttachmentDefinition 自定义资源。

使用要求

SR-IOV 网络连接功能要求集群节点上具有网络适配器的官方驱动程序。使用 SR-IOV 运算符之前,请先安装驱动程序。此外,要将 vfio-pci 模块用于 VF,请确保该模块在将要使用它的节点上可用。

为集群启用 SR-IOV 网络连接

如需为 Google Distributed Cloud 启用 SR-IOV 网络,请将 multipleNetworkInterfaces 字段和 sriovOperator 字段添加到 Cluster 对象的 clusterNetwork 部分,并将这两个字段都设置为 true

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
spec:
  clusterNetwork:
    multipleNetworkInterfaces: true
    sriovOperator: true
...

sriovOperator 字段是可变的,可在创建集群后更改。

配置 SR-IOV 运算符

SriovOperatorConfig 自定义资源为 SR-IOV 网络连接功能提供全局配置。此捆绑式自定义资源的名称为 default,它位于 gke-operators 命名空间中。系统仅使用此名称和命名空间的 SriovOperatorConfig 自定义资源。

您可以使用以下命令修改此对象:

kubectl -n gke-operators edit sriovoperatorconfigs.sriovnetwork.k8s.cni.cncf.io default

以下是 SriovOperatorConfig 自定义资源配置的示例:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovOperatorConfig
metadata:
  name: default
  namespace: gke-operators
spec:
  configDaemonNodeSelector:
    nodePool: "withSriov"
  disableDrain: false
  logLevel: 0

通过 configDaemonNodeSelector 部分,您可以限制 SR-IOV 运算符可以处理的节点。在上面的示例中,运算符将仅处理具有 nodePool: withSriov 标签的节点。如果未指定 configDaemonNodeSelector 字段,则系统会应用以下默认标签:

beta.kubernetes.io/os: linux
node-role.kubernetes.io/worker: ""

disableDrain 字段指定在节点重新启动之前还是在特定 VF 配置更改之前执行 Kubernetes 节点排空操作。

创建 SR-IOV 政策

如需配置集群中的特定 VF,您必须在 gke-operators 命名空间中创建 SriovNetworkNodePolicy 自定义资源。

以下是 SriovNetworkNodePolicy 自定义资源的清单示例:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
  namespace: gke-operators
spec:
  deviceType: "netdevice"
  mtu: 1600
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
    deviceID: "1015"
    rootDevices:
    - 0000:01:00.0
    vendor: "15b3"
  numVfs: 4
  priority: 80
  resourceName: "mlnx"

通过 nodeSelector 部分,您可以进一步限制必须在其上创建 VF 的节点。此限制将在上一部分中描述的 SriovOperatorConfig 中提供的选择器之前应用。

deviceType 字段指定要用于 VF 的内核模块。deviceType 的可用选项包括:

  • netdevice(适用于特定于 VF 的标准内核模块)
  • vfio-pci(适用于 VFIO-PCI 驱动程序)

resourceName 定义 VF 在 Kubernetes 节点中的显示名称。

配置过程完成后,您选定的集群节点将包含定义的资源,如以下示例所示(请注意 gke.io/mlnx):

apiVersion: v1
kind: Node
metadata:
  name: worker-01
spec:
…
status:
  allocatable:
    cpu: 47410m
    ephemeral-storage: "210725550141"
    gke.io/mlnx: "4"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 59884492Ki
    pods: "250"
  capacity:
    cpu: "48"
    ephemeral-storage: 228651856Ki
    gke.io/mlnx: "4"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 65516492Ki
    pods: "250"

该运算符将始终为您使用 SriovNetworkNodePolicy 定义的每个资源添加 gke.io/ 前缀。

指定 NIC 选择器

为使 SriovNetworkNodePolicy 正常工作,请在 nicSelector 部分中指定至少一个选择器。此字段包含有关如何识别集群节点中的特定物理函数 (PF) 的多个选项。系统会为您识别此字段所需的大部分信息,并将其保存在 SriovNetworkNodeState 自定义资源中。此运算符可以处理的每个节点都有一个相应的对象。

使用以下命令查看所有可用节点:

kubectl -n gke-operators get sriovnetworknodestates.sriovnetwork.k8s.cni.cncf.io -o yaml

下面是一个节点示例:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
  name: worker-01
  namespace: gke-operators
spec:
  dpConfigVersion: "6368949"
status:
  interfaces:
  - deviceID: "1015"
    driver: mlx5_core
    eSwitchMode: legacy
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9c
    mtu: 1500
    name: enp1s0f0
    pciAddress: "0000:01:00.0"
    totalvfs: 4
    vendor: 15b3
  - deviceID: "1015"
    driver: mlx5_core
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9d
    mtu: 1500
    name: enp1s0f1
    pciAddress: "0000:01:00.1"
    totalvfs: 2
    vendor: 15b3
  syncStatus: Succeeded

设置物理函数分区

请特别注意 nicSelector 部分的 pfNames 字段。除了定义要使用的确切 PF 之外,您还可以使用该字段指定要用于指定 PF 以及政策中定义的资源的确切 VF。

以下是一个示例:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
  namespace: gke-operators
spec:
  deviceType: "netdevice"
  mtu: 1600
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#3-6
    deviceID: "1015"
    rootDevices:
    - 0000:01:00.0
    vendor: "15b3"
  numVfs: 7
  priority: 80
  resourceName: "mlnx"

在上面的示例中,gke.io/mlnx 资源将仅使用编号为 3 到 6 的 VF,并且只会显示这四个可用的 VF。由于 VF 始终从零索引开始创建,因此您请求的 VF 数量 numVfs 必须至少与范围结束值(从零开始计数)一样大。这种编号逻辑就是上例中 numVfs 设置为 7 的原因。同理,如果您设置的范围为 3 到 4 (enp65s0f0#3-4),则 numVfs 必须至少为 5

如果未指定分区,则由 numVfs 定义要使用的 VF 范围,该范围始终从零开始。例如,如果您设置了 numVfs=3 且未指定分区,则系统会使用 0-2 的 VF。

了解政策优先级

您可以指定多个 SriovNetworkNodePolicy 对象来处理各种供应商或不同的 VF 配置。如果多个政策引用相同的 PF,那么在管理多个对象和供应商时可能会出现问题。为了处理此类情况,priority 字段会按节点解决冲突问题。

下面是重叠的 PF 政策的优先级逻辑:

  1. 仅当 PF 分区重叠时,优先级较高的政策才会覆盖优先级较低的政策。

  2. 合并具有相同优先级的政策:

    1. 政策按名称排序并按该顺序处理
    2. 具有重叠 PF 分区的政策将被覆盖
    3. 具有不重叠 PF 分区的政策将被合并且全部存在

具有较高优先级的政策指的是 priority 字段中具有较小数值的政策。例如,与 priority: 20 的政策相比,priority: 10 的政策的优先级更高。

以下部分提供了不同分区配置的政策示例。

分区 PF

部署以下两个 SriovNetworkNodePolicy 清单会导致两个资源可用:gke.io/dev-kernelgke.io/dev-vfio。每个资源都具有两个不重叠的 VF。

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#0-1
  numVfs: 2
  priority: 70
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

重叠 PF 分区

部署以下两个 SriovNetworkNodePolicy 清单会导致只有 gke.io/dev-vfio 资源可用。policy-1 VF 范围是 0-2,与 policy-2 重叠。根据命名,policy-2 将在 policy-1 之后进行处理。因此,只有 policy-2 中指定的资源 gke.io/dev-vfio 可用。

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
  numVfs: 3
  priority: 70
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

具有不同优先级的非重叠 PF 分区

部署以下两个 SriovNetworkNodePolicy 清单会导致两个资源可用:gke.io/dev-kernelgke.io/dev-vfio。每个资源都具有两个不重叠的 VF。虽然 policy-1 的优先级高于 policy-2,但因为 PF 分区不重叠,所以我们会合并这两个政策。

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
  numVfs: 2
  priority: 10
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

检查 SR-IOV 政策设置状态

应用 SR-IOV 政策时,您可以在特定节点的 SriovNetworkNodeState 自定义资源中跟踪和查看节点的最终配置。在 status 部分中,syncStatus 字段表示配置守护程序的当前阶段。Succeeded 状态表示配置已完成。SriovNetworkNodeState 自定义资源的 spec 部分会根据政策的数量及其优先级定义该节点的 VF 配置的最终状态。创建的所有 VF 都将列在指定 PF 的 status 部分中。

下面是 SriovNetworkNodeState 自定义资源示例:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
  name: worker-02
  namespace: gke-operators
spec:
  dpConfigVersion: "9022068"
  interfaces:
  - linkType: eth
    name: enp1s0f0
    numVfs: 2
    pciAddress: "0000:01:00.0"
    vfGroups:
    - deviceType: netdevice
      policyName: policy-1
      resourceName: mlnx
      vfRange: 0-1
status:
  interfaces:
  - Vfs:
    - deviceID: "1016"
      driver: mlx5_core
      mac: 96:8b:39:d8:89:d2
      mtu: 1500
      name: enp1s0f0np0v0
      pciAddress: "0000:01:00.2"
      vendor: 15b3
      vfID: 0
    - deviceID: "1016"
      driver: mlx5_core
      mac: 82:8e:65:fe:9b:cb
      mtu: 1500
      name: enp1s0f0np0v1
      pciAddress: "0000:01:00.3"
      vendor: 15b3
      vfID: 1
    deviceID: "1015"
    driver: mlx5_core
    eSwitchMode: legacy
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9c
    mtu: 1500
    name: enp1s0f0
    numVfs: 2
    pciAddress: "0000:01:00.0"
    totalvfs: 2
    vendor: 15b3
  - deviceID: "1015"
    driver: mlx5_core
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9d
    mtu: 1500
    name: enp1s0f1
    pciAddress: "0000:01:00.1"
    totalvfs: 2
    vendor: 15b3
  syncStatus: Succeeded

创建 NetworkAttachmentDefinition 自定义资源

在集群上成功配置 VF 后,它们会在 Kubernetes 节点中作为资源显示,您需要创建一个引用该资源的 NetworkAttachmentDefinition。使用 k8s.v1.cni.cncf.io/resourceName 注解进行引用。 下面是一个引用 gke.io/mlnx 资源的 NetworkAttachmentDefinition 清单示例:

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-sriov-1
  annotations:
    k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
  config: '{
      "cniVersion": "0.3.0",
      "name": "mynetwork",
      "type": "sriov",
      "ipam": {
        "type": "whereabouts",
        "range": "21.0.108.0/21",
        "range_start": "21.0.111.16",
        "range_end": "21.0.111.18"
      }
    }'

NetworkAttachmentDefinition 必须使用 sriov 作为 CNI 类型。使用 k8s.v1.cni.cncf.io/networks 注解引用 pod 中已部署的任何 NetworkAttachmentDefinition 自定义资源。

以下示例展示了如何在 pod 中引用上述 NetworkAttachmentDefinition 自定义资源:

apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: gke-sriov-1
spec:
  containers:
  ...

在工作负载中引用 NetworkAttachmentDefinition 自定义资源时,您不必担心 Pod 的资源定义或其在特定节点中的位置,系统会自动为您完成这些设置。

以下示例展示了具有 VLAN 配置的 NetworkAttachmentDefinition 自定义资源。在此示例中,每个 VF 都属于 100 VLAN:

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-sriov-vlan-100
  annotations:
    k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
  config: '{
      "cniVersion": "0.3.0",
      "name": "mynetwork",
      "type": "sriov",
      "vlan": 100,
      "ipam": {
        "type": "whereabouts",
        "range": "21.0.100.0/21"
      }
    }'

其他信息

以下部分包含可帮助您配置 SR-IOV 网络连接的有用信息。

节点重新启动

当 SR-IOV 运算符配置节点时,可能需要重新启动节点。在 VF 或内核配置期间,可能需要重新启动节点。内核配置包括在操作系统中启用 SR-IOV 功能支持。

支持的网络适配器

下表列出了版本 1.29.x 集群支持的网络适配器:

名称 供应商 ID 设备 ID VF 设备 ID
Intel i40e XXV710 8086 158a 154c
Intel i40e 25G SFP28 8086 158b 154c
Intel i40e 10G X710 SFP 8086 1572 154c
Intel i40e XXV710 N3000 8086 0d58 154c
Intel i40e 40G XL710 QSFP 8086 1583 154c
Intel ice Columbiaville E810-CQDA2 2CQDA2 8086 1592 1889
Intel ice Columbiaville E810-XXVDA4 8086 1593 1889
Intel ice Columbiaville E810-XXVDA2 8086 159b 1889
Nvidia mlx5 ConnectX-4 15b3 1013 1014
Nvidia mlx5 ConnectX-4LX 15b3 1015 1016
Nvidia mlx5 ConnectX-5 15b3 1017 1018
Nvidia mlx5 ConnectX-5 Ex 15b3 1019 101a
Nvidia mlx5 ConnectX-6 15b3 101b 101c
Nvidia mlx5 ConnectX-6_Dx 15b3 101d 101e
Nvidia mlx5 MT42822 BlueField-2 integrated ConnectX-6 Dx 15b3 a2d6 101e
Broadcom bnxt BCM57414 2x25G 14e4 16d7 16dc
Broadcom bnxt BCM75508 2x100G 14e4 1750 1806