×

外围组件互连 (PCI) 直通功能使您可以访问和管理虚拟机 (VM) 中的硬件设备。配置 PCI 直通后,PCI 设备的功能就像物理连接到客户机操作系统一样。

集群管理员可以使用oc命令行界面 (CLI) 公开和管理允许在集群中使用的主机设备。

准备节点以进行 GPU 直通

您可以阻止 GPU 操作数在您指定用于 GPU 直通的工作节点上部署。

阻止 NVIDIA GPU 操作数在节点上部署

如果您在集群中使用NVIDIA GPU Operator,您可以将nvidia.com/gpu.deploy.operands=false标签应用于您不想为 GPU 或 vGPU 操作数配置的节点。此标签可阻止创建配置 GPU 或 vGPU 操作数的 Pod,并在这些 Pod 已存在时终止它们。

先决条件
  • 已安装 OpenShift CLI (oc)。

步骤
  • 运行以下命令为节点添加标签

    $ oc label node <node_name> nvidia.com/gpu.deploy.operands=false (1)
    1 <node_name>替换为您不想安装 NVIDIA GPU 操作数的节点的名称。
验证
  1. 运行以下命令以验证标签是否已添加到节点

    $ oc describe node <node_name>
  2. 可选:如果以前在节点上部署了 GPU 操作数,请验证是否已将其移除。

    1. 运行以下命令检查nvidia-gpu-operator命名空间中 Pod 的状态

      $ oc get pods -n nvidia-gpu-operator
      示例输出
      NAME                             READY   STATUS        RESTARTS   AGE
      gpu-operator-59469b8c5c-hw9wj    1/1     Running       0          8d
      nvidia-sandbox-validator-7hx98   1/1     Running       0          8d
      nvidia-sandbox-validator-hdb7p   1/1     Running       0          8d
      nvidia-sandbox-validator-kxwj7   1/1     Terminating   0          9d
      nvidia-vfio-manager-7w9fs        1/1     Running       0          8d
      nvidia-vfio-manager-866pz        1/1     Running       0          8d
      nvidia-vfio-manager-zqtck        1/1     Terminating   0          9d
    2. 监控 Pod 状态,直到状态为Terminating的 Pod 被移除。

      $ oc get pods -n nvidia-gpu-operator
      示例输出
      NAME                             READY   STATUS    RESTARTS   AGE
      gpu-operator-59469b8c5c-hw9wj    1/1     Running   0          8d
      nvidia-sandbox-validator-7hx98   1/1     Running   0          8d
      nvidia-sandbox-validator-hdb7p   1/1     Running   0          8d
      nvidia-vfio-manager-7w9fs        1/1     Running   0          8d
      nvidia-vfio-manager-866pz        1/1     Running   0          8d

准备用于 PCI 直通的主机设备

关于准备用于 PCI 直通的主机设备

要使用 CLI 准备用于 PCI 直通的主机设备,请创建一个MachineConfig对象并添加内核参数以启用输入/输出内存管理单元 (IOMMU)。将 PCI 设备绑定到虚拟功能 I/O (VFIO) 驱动程序,然后通过编辑HyperConverged自定义资源 (CR) 的permittedHostDevices字段在集群中公开它。首次安装 OpenShift Virtualization Operator 时,permittedHostDevices列表为空。

要使用 CLI 从集群中删除 PCI 主机设备,请从HyperConvergedCR 中删除 PCI 设备信息。

添加内核参数以启用 IOMMU 驱动程序

要在内核中启用 IOMMU 驱动程序,请创建MachineConfig对象并添加内核参数。

先决条件
  • 您具有集群管理员权限。

  • 您的 CPU 硬件是 Intel 或 AMD。

  • 您已在 BIOS 中启用 Intel 虚拟化技术用于定向 I/O 扩展或 AMD IOMMU。

步骤
  1. 创建一个标识内核参数的MachineConfig对象。以下示例显示了 Intel CPU 的内核参数。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker (1)
      name: 100-worker-iommu (2)
    spec:
      config:
        ignition:
          version: 3.2.0
      kernelArguments:
          - intel_iommu=on (3)
    # ...
    1 仅将新的内核参数应用于工作节点。
    2 name指示此内核参数在机器配置中的排名 (100) 及其用途。如果您拥有 AMD CPU,请将内核参数指定为amd_iommu=on
    3 为 Intel CPU 将内核参数标识为intel_iommu
  2. 创建新的MachineConfig对象

    $ oc create -f 100-worker-kernel-arg-iommu.yaml
验证
  • 验证是否已添加新的MachineConfig对象。

    $ oc get MachineConfig

将 PCI 设备绑定到 VFIO 驱动程序

要将 PCI 设备绑定到 VFIO(虚拟功能 I/O)驱动程序,请从每个设备获取vendor-IDdevice-ID的值,并创建一个包含这些值的列表。将此列表添加到MachineConfig对象中。MachineConfig Operator 会在具有 PCI 设备的节点上生成/etc/modprobe.d/vfio.conf,并将 PCI 设备绑定到 VFIO 驱动程序。

先决条件
  • 您已添加内核参数以启用 CPU 的 IOMMU。

步骤
  1. 运行lspci命令以获取 PCI 设备的vendor-IDdevice-ID

    $ lspci -nnv | grep -i nvidia
    示例输出
    02:01.0 3D controller [0302]: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB] [10de:1eb8] (rev a1)
  2. 创建一个 Butane 配置文件100-worker-vfiopci.bu,将 PCI 设备绑定到 VFIO 驱动程序。

    有关 Butane 的信息,请参见“使用 Butane 创建机器配置”。

    示例
    variant: openshift
    version: 4.17.0
    metadata:
      name: 100-worker-vfiopci
      labels:
        machineconfiguration.openshift.io/role: worker (1)
    storage:
      files:
      - path: /etc/modprobe.d/vfio.conf
        mode: 0644
        overwrite: true
        contents:
          inline: |
            options vfio-pci ids=10de:1eb8 (2)
      - path: /etc/modules-load.d/vfio-pci.conf (3)
        mode: 0644
        overwrite: true
        contents:
          inline: vfio-pci
    1 仅将新的内核参数应用于工作节点。
    2 指定先前确定的vendor-ID值 (10de) 和device-ID值 (1eb8) 以将单个设备绑定到 VFIO 驱动程序。您可以添加包含多个设备及其供应商和设备信息的列表。
    3 在工作节点上加载 vfio-pci 内核模块的文件。
  3. 使用 Butane 生成一个名为 100-worker-vfiopci.yamlMachineConfig 对象文件,其中包含要交付给工作节点的配置。

    $ butane 100-worker-vfiopci.bu -o 100-worker-vfiopci.yaml
  4. MachineConfig 对象应用于工作节点。

    $ oc apply -f 100-worker-vfiopci.yaml
  5. 验证是否已添加 MachineConfig 对象。

    $ oc get MachineConfig
    示例输出
    NAME                             GENERATEDBYCONTROLLER                      IGNITIONVERSION  AGE
    00-master                        d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    00-worker                        d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-master-container-runtime      d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-master-kubelet                d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-worker-container-runtime      d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-worker-kubelet                d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    100-worker-iommu                                                            3.2.0            30s
    100-worker-vfiopci-configuration                                            3.2.0            30s
验证
  • 验证是否已加载 VFIO 驱动程序。

    $ lspci -nnk -d 10de:

    输出确认正在使用 VFIO 驱动程序。

    示例输出
    04:00.0 3D controller [0302]: NVIDIA Corporation GP102GL [Tesla P40] [10de:1eb8] (rev a1)
            Subsystem: NVIDIA Corporation Device [10de:1eb8]
            Kernel driver in use: vfio-pci
            Kernel modules: nouveau

使用 CLI 在集群中公开 PCI 主机设备

要在集群中公开 PCI 主机设备,请将有关 PCI 设备的详细信息添加到 HyperConverged 自定义资源 (CR) 的 spec.permittedHostDevices.pciHostDevices 数组中。

步骤
  1. 通过运行以下命令,在默认编辑器中编辑 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. 将 PCI 设备信息添加到 spec.permittedHostDevices.pciHostDevices 数组中。例如:

    示例配置文件
    apiVersion: hco.kubevirt.io/v1
    kind: HyperConverged
    metadata:
      name: kubevirt-hyperconverged
      namespace: openshift-cnv
    spec:
      permittedHostDevices: (1)
        pciHostDevices: (2)
        - pciDeviceSelector: "10DE:1DB6" (3)
          resourceName: "nvidia.com/GV100GL_Tesla_V100" (4)
        - pciDeviceSelector: "10DE:1EB8"
          resourceName: "nvidia.com/TU104GL_Tesla_T4"
        - pciDeviceSelector: "8086:6F54"
          resourceName: "intel.com/qat"
          externalResourceProvider: true (5)
    # ...
    1 允许在集群中使用的主机设备。
    2 节点上可用的 PCI 设备列表。
    3 标识 PCI 设备所需的 vendor-IDdevice-ID
    4 PCI 主机设备的名称。
    5 可选:将此字段设置为 true 表示该资源由外部设备插件提供。OpenShift Virtualization 允许在集群中使用此设备,但将分配和监控留给外部设备插件。

    上面的示例代码片段显示了两个名为 nvidia.com/GV100GL_Tesla_V100nvidia.com/TU104GL_Tesla_T4 的 PCI 主机设备,它们已添加到 HyperConverged CR 中允许的主机设备列表中。这些设备经过测试和验证,可与 OpenShift Virtualization 配合使用。

  3. 保存更改并退出编辑器。

验证
  • 通过运行以下命令,验证 PCI 主机设备是否已添加到节点。示例输出显示,每个与 nvidia.com/GV100GL_Tesla_V100nvidia.com/TU104GL_Tesla_T4intel.com/qat 资源名称关联的设备各有一个。

    $ oc describe node <node_name>
    示例输出
    Capacity:
      cpu:                            64
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              915128Mi
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         131395264Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  1
      pods:                           250
    Allocatable:
      cpu:                            63500m
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              863623130526
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         130244288Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  1
      pods:                           250

使用 CLI 从集群中删除 PCI 主机设备

要从集群中删除 PCI 主机设备,请从 HyperConverged 自定义资源 (CR) 中删除该设备的信息。

步骤
  1. 通过运行以下命令,在默认编辑器中编辑 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. 通过删除相应设备的 pciDeviceSelectorresourceNameexternalResourceProvider(如果适用)字段,从 spec.permittedHostDevices.pciHostDevices 数组中删除 PCI 设备信息。在此示例中,已删除 intel.com/qat 资源。

    示例配置文件
    apiVersion: hco.kubevirt.io/v1
    kind: HyperConverged
    metadata:
      name: kubevirt-hyperconverged
      namespace: openshift-cnv
    spec:
      permittedHostDevices:
        pciHostDevices:
        - pciDeviceSelector: "10DE:1DB6"
          resourceName: "nvidia.com/GV100GL_Tesla_V100"
        - pciDeviceSelector: "10DE:1EB8"
          resourceName: "nvidia.com/TU104GL_Tesla_T4"
    # ...
  3. 保存更改并退出编辑器。

验证
  • 通过运行以下命令,验证 PCI 主机设备是否已从节点中删除。示例输出显示,与 intel.com/qat 资源名称关联的设备为零。

    $ oc describe node <node_name>
    示例输出
    Capacity:
      cpu:                            64
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              915128Mi
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         131395264Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  0
      pods:                           250
    Allocatable:
      cpu:                            63500m
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              863623130526
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         130244288Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  0
      pods:                           250

配置虚拟机以进行 PCI 直通

将 PCI 设备添加到集群后,您可以将其分配给虚拟机。PCI 设备现在可用,就像它们物理连接到虚拟机一样。

将 PCI 设备分配给虚拟机

当 PCI 设备在集群中可用时,您可以将其分配给虚拟机并启用 PCI 直通。

步骤
  • 将 PCI 设备作为主机设备分配给虚拟机。

    示例
    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    spec:
      domain:
        devices:
          hostDevices:
          - deviceName: nvidia.com/TU104GL_Tesla_T4 (1)
            name: hostdevices1
    1 在集群中允许作为主机设备使用的 PCI 设备的名称。虚拟机可以访问此主机设备。
验证
  • 使用以下命令验证虚拟机是否可以使用主机设备。

    $ lspci -nnk | grep NVIDIA
    示例输出
    $ 02:01.0 3D controller [0302]: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB] [10de:1eb8] (rev a1)