在 KubeVirt 中使用 GPU Operator

在 KubeVirt 中使用 GPU Operator

基于最新的GPU Operator版本24.9.0。

原文链接:GPU Operator with KubeVirt — NVIDIA GPU Operator 24.9.0 documentation

1. 简介

KubeVirt 是 Kubernetes 的一个虚拟机管理插件,允许您在 Kubernetes 集群中运行和管理虚拟机。它消除了为虚拟机和容器工作负载管理独立集群的需求,二者现在可以在单一 Kubernetes 集群中共存。

在此之前,GPU Operator 仅支持为运行 GPU 加速的容器配置工作节点。现在,GPU Operator 也可以用于为运行 GPU 加速的虚拟机配置工作节点。

运行带有 GPU 的容器和虚拟机所需的前提条件不同,主要区别在于所需的驱动程序。例如,数据中心驱动程序用于容器,vfio-pci 驱动程序用于 GPU 直通,而 NVIDIA vGPU Manager 用于创建 vGPU 设备。

现在可以将 GPU Operator 配置为根据节点上配置的 GPU 工作负载来部署不同的软件组件。以下示例展示了这一点。

  • 节点 A 被配置为运行容器。
  • 节点 B 被配置为运行具有直通 GPU 的虚拟机。
  • 节点 C 被配置为运行具有 vGPU 的虚拟机。

节点 A 配置的软件组件:

  • NVIDIA 数据中心驱动程序:用于安装驱动程序。
  • NVIDIA 容器工具包:确保容器可以正确访问 GPU。
  • NVIDIA Kubernetes 设备插件:用于发现 GPU 资源并将其发布给 kubelet。
  • NVIDIA DCGM 和 DCGM Exporter:用于监控 GPU。

节点 B 配置的软件组件:

  • VFIO 管理器:用于加载 vfio-pci 并将其绑定到节点上的所有 GPU。
  • 沙盒设备插件:用于发现 GPU 直通资源并将其发布给 kubelet。

节点 C 配置的软件组件:

  • NVIDIA vGPU 管理器:用于安装驱动程序。
  • NVIDIA vGPU 设备管理器:用于在节点上创建 vGPU 设备。
  • 沙盒设备插件:用于发现 vGPU 设备并将其发布给 kubelet。

2. 假设、约束和依赖项

  • 一个 GPU 工作节点可以运行特定类型的 GPU 工作负载——容器、具有 GPU 直通的虚拟机或具有 vGPU 的虚拟机——但不能混合运行这些类型的工作负载。
  • 集群管理员或开发者需提前了解集群的需求,并正确地为节点贴上标签,以指示其将运行的 GPU 工作负载类型。
  • 运行 GPU 加速虚拟机(使用 pGPU 或 vGPU)的工作节点假定为裸机。
  • GPU Operator 不会自动在附带 GPU/vGPU 的 KubeVirt 虚拟机中安装 NVIDIA 驱动。
  • 用户在将 GPU 直通和 vGPU 资源分配给 KubeVirt 虚拟机之前,必须手动将所有 GPU 直通和 vGPU 资源添加到 KubeVirt CR 中的 permittedDevices 列表中。有关更多信息,请参阅 KubeVirt 文档
  • 不支持基于 MIG 的 vGPU。

3. 先决条件

  • 在 BIOS 中启用虚拟化和 IOMMU 扩展(Intel VT-d 或 AMD IOMMU)。
  • 主机以 intel_iommu=onamd_iommu=on 启动内核。
  • 如果计划使用 NVIDIA vGPU,并且 GPU 基于 NVIDIA Ampere 架构或更新架构,则必须在 BIOS 中启用 SR-IOV。请参考 NVIDIA vGPU 文档,确保满足使用 NVIDIA vGPU 的所有先决条件。
  • KubeVirt 已安装在集群中。
  • 从 KubeVirt v0.58.2 和 v0.59.1 开始,需设置 DisableMDEVConfiguration 功能门控:
kubectl patch kubevirt -n kubevirt kubevirt --type='json' \
    -p='[{"op": "add", "path": "/spec/configuration/developerConfiguration/featureGates/-", "value": "DisableMDEVConfiguration" }]'

示例输出

kubevirt.kubevirt.io/kubevirt patched

4. 入门指南

使用 GPU Operator 和 KubeVirt 的高层次工作流程如下:

  1. 确保已设置禁用中介设备配置的功能门控。

  2. 根据将要运行的 GPU 工作负载类型为工作节点打标签。

  3. 安装 GPU Operator 并设置 sandboxWorkloads.enabled=true

如果使用 NVIDIA vGPU,还需要执行其他步骤,这将在后续部分中介绍。

5. 为工作节点打标签

使用以下命令为工作节点添加标签:

kubectl label node <node-name> --overwrite nvidia.com/gpu.workload.config=vm-vgpu

可以为标签 nvidia.com/gpu.workload.config 指定以下值:containervm-passthroughvm-vgpu。GPU Operator 使用该标签的值来确定在每个工作节点上部署哪些操作对象。

如果节点上不存在 nvidia.com/gpu.workload.config 标签,GPU Operator 将假定默认的 GPU 工作负载配置为 container,并部署支持该类型负载所需的软件组件。要覆盖默认的 GPU 工作负载配置,可在 ClusterPolicy 中设置以下值:sandboxWorkloads.defaultWorkload=<config>

6. 安装 GPU Operator

根据是否计划使用 NVIDIA vGPU,选择以下适当的小节以安装 GPU Operator。

通常,ClusterPolicy 中的 sandboxWorkloads.enabled 标志控制 GPU Operator 是否可以为虚拟机工作负载(以及容器工作负载)配置 GPU 工作节点。默认情况下,此标志是禁用的,这意味着所有节点将使用相同的软件配置以支持容器工作负载,并且不会使用 nvidia.com/gpu.workload.config 节点标签。

注意

术语“沙箱”通常指在一个单独的隔离环境中运行软件,通常是为了增加安全性(如虚拟机)。我们使用“沙箱工作负载”一词来表示在虚拟机中运行的工作负载,无论使用何种虚拟化技术。

安装 GPU Operator(不使用 NVIDIA vGPU)

安装 GPU Operator,并启用 sandboxWorkloads

helm install --wait --generate-name \
      -n gpu-operator --create-namespace \
      nvidia/gpu-operator \
      --set sandboxWorkloads.enabled=true

安装 GPU Operator(使用 NVIDIA vGPU)

构建私有的 NVIDIA vGPU Manager 容器镜像并推送到私有镜像仓库。请按照本节提供的步骤操作。

创建 GPU Operator 的命名空间:

kubectl create namespace gpu-operator

创建用于访问 NVIDIA vGPU Manager 镜像的 ImagePullSecret:

kubectl create secret docker-registry ${REGISTRY_SECRET_NAME} \
  --docker-server=${PRIVATE_REGISTRY} --docker-username=<username> \
  --docker-password=<password> \
  --docker-email=<email-id> -n gpu-operator

安装 GPU Operator,启用 sandboxWorkloadsvgpuManager,并指定之前构建的 NVIDIA vGPU Manager 镜像:

helm install --wait --generate-name \
      -n gpu-operator --create-namespace \
      nvidia/gpu-operator \
      --set sandboxWorkloads.enabled=true \
      --set vgpuManager.enabled=true \
      --set vgpuManager.repository=<path to private repository> \
      --set vgpuManager.image=vgpu-manager \
      --set vgpuManager.version=<driver version> \
      --set vgpuManager.imagePullSecrets={${REGISTRY_SECRET_NAME}}

由 GPU Operator 部署的 vGPU Device Manager 会自动创建 vGPU 设备,这些设备可以分配给 KubeVirt 虚拟机。默认情况下,GPU Operator 会在所有 GPU 上创建一组默认设备。要了解 vGPU Device Manager 的更多信息以及如何配置在集群中创建的 vGPU 设备类型,请参考 vGPU 设备配置文档

7. 向 KubeVirt CR 中添加 GPU 资源

更新 KubeVirt 自定义资源,使集群中的所有 GPU 和 vGPU 设备均被允许并可以分配给虚拟机。

以下示例展示了如何允许 A10 GPU 设备和 A10-24Q vGPU 设备。

  1. 确定 GPU 设备的资源名称:

    kubectl get node cnt-server-2 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("nvidia.com/"))) | with_entries(select(.value != "0"))'
    

    示例输出

    {
      "nvidia.com/NVIDIA_A10-12Q": "4"
    }
    
  2. 确定 GPU 的 PCI 设备 ID。

    可以在 PCI IDs 数据库中按设备名称进行搜索。

    如果有节点的主机访问权限,可以使用以下命令列出 NVIDIA GPU 设备:

    lspci -nnk -d 10de:
    

    示例输出

    65:00.0 3D controller [0302]: NVIDIA Corporation GA102GL [A10] [10de:2236] (rev a1)
            Subsystem: NVIDIA Corporation GA102GL [A10] [10de:1482]
            Kernel modules: nvidiafb, nouveau
    
  3. 修改 KubeVirt 自定义资源,以下为部分示例:

    ...
    spec:
      configuration:
        developerConfiguration:
          featureGates:
          - GPU
          - DisableMDEVConfiguration
        permittedHostDevices:
          pciHostDevices:
          - externalResourceProvider: true
            pciVendorSelector: 10DE:2236
            resourceName: nvidia.com/GA102GL_A10
          mediatedDevices:
          - externalResourceProvider: true
            mdevNameSelector: NVIDIA A10-24Q
            resourceName: nvidia.com/NVIDIA_A10-24Q
    ...
    
  4. 根据您的设备替换 YAML 中的值:

    • pciHostDevices 下,将 pciVendorSelectorresourceName 替换为您的 GPU 型号。
    • mediatedDevices 下,将 mdevNameSelectorresourceName 替换为您的 vGPU 类型。
  5. 设置 externalResourceProvider=true,以表明该资源由外部设备插件(即 GPU Operator 部署的 sandbox-device-plugin)提供。

有关更多配置信息,请参阅 KubeVirt 用户指南

8. 创建带有 GPU 的虚拟机

在 GPU Operator 完成将沙箱设备插件和 VFIO 管理器 pod 部署到工作节点上,并将 GPU 资源添加到 KubeVirt 允许列表之后,可以通过编辑 VirtualMachineInstance 清单中的 spec.domain.devices.gpus 字段,将 GPU 分配给虚拟机。

apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachineInstance
...
spec:
  domain:
    devices:
      gpus:
      - deviceName: nvidia.com/GA102GL_A10
        name: gpu1
...
  • deviceName 是表示设备的资源名称。
  • name 是在虚拟机中用于标识该设备的名称。

9. vGPU 设备配置

vGPU 设备管理器(vGPU Device Manager)用于在 GPU 工作节点上创建 vGPU 设备。管理员可以声明式地定义一组可能的 vGPU 设备配置,并应用于节点上的 GPU。运行时,可以将 vGPU 设备管理器指向这些配置中的一个,设备管理器会负责将其应用。配置文件以 ConfigMap 的形式创建,并在所有工作节点之间共享。运行时,可以使用节点标签 nvidia.com/vgpu.config 来决定在特定时间应在节点上应用哪个配置。如果节点没有此标签,则使用默认配置。有关此组件及其配置的更多信息,请参阅项目的 README

默认情况下,GPU Operator 部署一个 vGPU 设备管理器的 ConfigMap,包含所有 NVIDIA vGPU 支持的 vGPU 类型的命名配置。用户可以通过应用 nvidia.com/vgpu.config 节点标签为工作节点选择特定配置。例如,将节点标记为 nvidia.com/vgpu.config=A10-8Q 会在节点上的所有 A10 GPU 上创建 3 个 A10-8Q 类型的 vGPU 设备(注:每个 GPU 最多可创建 3 个 A10-8Q 设备)。如果节点没有标签,则应用默认配置。默认配置会在所有 GPU 上创建 Q 系列的 vGPU 设备,其中每个 vGPU 设备的帧缓冲内存为 GPU 总内存的一半。例如,默认配置会在所有 A10 GPU 上创建两个 A10-12Q 设备,在所有 V100 GPU 上创建两个 V100-8Q 设备,在所有 T4 GPU 上创建两个 T4-8Q 设备。

如果需要自定义的 vGPU 设备配置,可以创建自己的 ConfigMap:

kubectl create configmap custom-vgpu-config -n gpu-operator --from-file=config.yaml=/path/to/file

然后通过设置 vgpuDeviceManager.config.name=custom-vgpu-config 配置 GPU Operator 使用该自定义配置。

10. 应用新的 vGPU 设备配置

可以通过设置 nvidia.com/vgpu.config 节点标签,在每个节点上应用特定的 vGPU 设备配置。如果不希望应用默认配置,建议在安装 GPU Operator 前先设置此节点标签。

在已成功应用某一 vGPU 设备配置后切换配置时,假定该节点上没有正在运行的带 vGPU 的虚拟机。任何现有的虚拟机需要先关闭或迁移。

在安装 GPU Operator 后要应用新配置,只需更新 nvidia.com/vgpu.config 节点标签。以下是一个包含两个 A10 GPU 系统上的运行示例:

nvidia-smi -L
GPU 0: NVIDIA A10 (UUID: GPU-ebd34bdf-1083-eaac-2aff-4b71a022f9bd)
GPU 1: NVIDIA A10 (UUID: GPU-1795e88b-3395-b27b-dad8-0488474eec0c)

按照之前章节中的步骤安装 GPU Operator,且未使用 nvidia.com/vgpu.config 标签对节点进行标记时,将应用默认的 vGPU 配置:创建四个 A10-12Q 设备(每个 GPU 两个设备):

kubectl get node cnt-server-2 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("nvidia.com/"))) | with_entries(select(.value != "0"))'
{
  "nvidia.com/NVIDIA_A10-12Q": "4"
}

如果希望创建 A10-4Q 设备,可以这样标记节点:

kubectl label node <node-name> --overwrite nvidia.com/vgpu.config=A10-4Q

在 vGPU 设备管理器完成应用新配置后,所有 GPU Operator 相关的 pod 应恢复到 Running 状态。

kubectl get pods -n gpu-operator
NAME                                                          READY   STATUS    RESTARTS   AGE
...
nvidia-sandbox-device-plugin-daemonset-brtb6                  1/1     Running   0          10s
nvidia-sandbox-validator-ljnwg                                1/1     Running   0          10s
nvidia-vgpu-device-manager-8mgg8                              1/1     Running   0          30m
nvidia-vgpu-manager-daemonset-fpplc                           1/1     Running   0          31m

此时在节点上可以看到 12 个 A10-4Q 设备,因为每个 A10 GPU 可创建 6 个 A10-4Q 设备。

kubectl get node cnt-server-2 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("nvidia.com/"))) | with_entries(select(.value != "0"))'
{
  "nvidia.com/NVIDIA_A10-4Q": "12"
}

11. 构建 NVIDIA vGPU 管理器镜像

注意:

如果计划使用 NVIDIA vGPU,才需要构建 NVIDIA vGPU 管理器镜像。如果仅计划使用 PCI 直通,请跳过此部分。

本节涵盖了构建 NVIDIA vGPU 管理器容器镜像并将其推送到私有注册表的过程。

下载 vGPU 软件

NVIDIA 许可门户下载 vGPU 软件。

  • 登录到 NVIDIA 许可门户,并导航到软件下载部分。

  • NVIDIA vGPU 软件位于 NVIDIA 许可门户的 软件下载 部分。

  • vGPU 软件包以 zip 文件形式打包。下载并解压该包,以获取适用于 Linux 的 NVIDIA vGPU 管理器文件 NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run

注意:

对于 NVIDIA AI 企业客户,必须使用 aie .run 文件来构建 NVIDIA vGPU 管理器镜像。请下载 NVIDIA-Linux-x86_64-<version>-vgpu-kvm-aie.run 文件,并在继续执行后续步骤之前将其重命名为 NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run

克隆驱动容器仓库并构建驱动镜像

打开终端并克隆驱动容器镜像仓库。

git clone https://gitlab.com/nvidia/container-images/driver
cd driver

切换到适用于您的操作系统的 vgpu-manager 目录

以 Ubuntu 20.04 为例:

cd vgpu-manager/ubuntu20.04

注意:

对于 RedHat OpenShift,运行 cd vgpu-manager/rhel8 使用 rhel8 文件夹。

复制从解压的 zip 文件中获得的 NVIDIA vGPU 管理器文件

cp <local-driver-download-directory>/*-vgpu-kvm.run ./

设置以下环境变量:

  • PRIVATE_REGISTRY - 用于存储驱动镜像的私有注册表名称。
  • VERSION - 从 NVIDIA 软件门户下载的 NVIDIA vGPU 管理器版本。
  • OS_TAG - 必须与客户端操作系统版本匹配。上面的示例中使用的是 ubuntu20.04。对于 RedHat OpenShift,应设置为 rhcos4.x,其中 x 是受支持的 OCP 次版本号。
  • CUDA_VERSION - 用于构建驱动镜像的 CUDA 基础镜像版本。

示例:

export PRIVATE_REGISTRY=my/private/registry VERSION=510.73.06 OS_TAG=ubuntu20.04 CUDA_VERSION=11.7.1

构建 NVIDIA vGPU 管理器镜像

docker build \
    --build-arg DRIVER_VERSION=${VERSION} \
    --build-arg CUDA_VERSION=${CUDA_VERSION} \
    -t ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG} .

将 NVIDIA vGPU 管理器镜像推送到私有注册表(registry)

docker push ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lldhsds

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值