2. GPU虚拟化

2.1. 简介

GPU Operator 的driver-manager组件提供GPU内核驱动的生命周期管理,支持在集群环境中自动化部署GPU内核驱动。 同时支持SR-IOV虚拟化、在KubeVirt虚拟机场景自动绑定VFIO驱动,保障驱动与集群环境的兼容性和稳定性。

2.2. 安装 GPU Operator

备注

关于 GPU Operator 所依赖的前置资源,参见《曦云系列通用GPU云原生参考手册》中“安装与维护”章节。

  1. 获取安装包

    以 0.13.0 版本为例,从 沐曦软件中心 下载离线安装包 metax-gpu-k8s-package.0.13.0.tar.gz,解压后获取以下文件:

    • metax-k8s-images.0.13.0.run:镜像资源包

    • metax-operator-0.13.0.tgz:Operator Helm Chart

    • metax-gpu-extensions-0.13.0.tgz:Extensions Helm Chart

  2. 准备内核驱动和 MXMACA® SDK 镜像

    GPU Operator 会自动管理节点上的内核驱动及 MXMACA® SDK 的部署与更新,需确保所有工作节点均可正常拉取相关镜像资源。

    内核驱动与 MXMACA® SDK 可从 沐曦软件中心 下载。

    资源包格式:

    • 内核驱动镜像包

      metax-k8s-driver-image.<VERSION>-<ARCH>.run:包含内核态驱动和配套 mx-smi 工具的资源包

    • MXMACA® SDK 镜像包

      随 MXMACA® 的发布包发布,例如 maca-native:<VERSION>-<DISTRO>-<ARCH>.container.xz 或者 maca-c500-container-*.xz

  3. 推送镜像

    # 假设容器仓库服务器域名为 DOMAIN ,用于存放沐曦Kubernetes组件镜像的项目名为 PROJECT。
    # 默认使用docker进行镜像推送
    metax-k8s-images.0.13.0.run push DOMAIN/PROJECT
    # 使用nerdctl进行镜像推送
    metax-k8s-images.0.13.0.run nerdctl push DOMAIN/PROJECT
    

    备注

    • 自 0.13.0 起,该工具支持多种运行时:dockernerdctlctr

    • 若未显式指定,默认使用docker。若主机未安装docker,系统将自动检测可用运行时并执行镜像推送。

  4. 推送 Helm Charts

    helm push ./k8s/metax-operator-0.13.0.tgz oci://DOMAIN/PROJECT
    
  5. 安装 GPU Operator

    # 离线安装(基于本地Helm Charts)
    helm install ./k8s/metax-operator-0.13.0.tgz \
    --create-namespace -n metax-operator \
    --generate-name \
    --wait \
    --set registry=DOMAIN/PROJECT
    
  6. 验证安装状态

    在 Kubernetes 管理节点执行以下命令检查 Pod 是否处于 Running 状态。

    kubectl get pod -n metax-operator
    NAME                                           READY   STATUS      RESTARTS   AGE
    metax-container-runtime-4lsd7                  1/1     Running     0          31s
    metax-gpu-device-7774b                         1/1     Running     0          31s
    metax-gpu-label-l5tkf                          1/1     Running     0          31s
    metax-operator-1755847288-77bfc94568-7wqlh     1/1     Running     0          31s
    ...
    

2.3. SR-IOV虚拟化

2.3.1. 准备条件

Metax GPU支持开启虚拟化,开启虚拟化需确保环境已完成如下配置:

  • BIOS 开启 SRIOV

  • 安装带 -VF 后缀的VBIOS固件

关于开启SRIOV的详细介绍,参见《曦云系列通用GPU云原生参考手册》。

driver-manager通过名为 driver-configConfigMap 资源控制工作节点是否开启SR-IOV虚拟化, 目前可使用v1、v2两种版本配置。

备注

使用 GPU Operator 方案配置SR-IOV虚拟化时,不建议使用mx-smi工具对相关配置进行修改。

2.3.2. [推荐] v2版配置

GPU Operator 0.11.0 版本引入 driver config v2,支持单GPU粒度的虚拟化配置以及通过BDF号配置GPU,具备细粒度的控制能力。

  1. 集群初始化配置

    提供 --set-file 或修改 values.yaml 配置两种方式进行初始化,仅当 v1 配置为空时 v2 生效。

    优先级:--set-file 修改 values.yaml

    配置参数的详细介绍参见《曦云系列通用GPU云原生参考手册》中“组件介绍”章节。

    • --set-file 方式

      用户可参考如下示例准备v2版本驱动配置文件:

      nodes-config:
        - nodeName: workerNode-1     # workerNode-1 每张 GPU 虚拟为 2 个 VF
          vfNum: 2
        - nodeName: workerNode-2     # workerNode-2 仅将 0,1号 GPU 虚拟为 2 个 VF
          vfNum: 2
          virtGPUs: "0,1"
      

      并通过helm提供的 --set-file 参数,将以上配置文件路径指定到 driver.driverConfigFile 选项下:

      helm install metax-operator --generate-name --set-file driver.driverConfigFile=driver_config_v2.yaml
      
    • 修改 values.yaml 方式

      可在 values.yaml 配置文件中配置下列选项,并通过常规 helm install 命令安装:

      # values.yaml 配置示例
      driver:
        driverConfig:
          nodesConfig:
          - nodeName: workerNode-1
            vfNum: 2
          - nodeName: workerNode-2
            vfNum: 2
            virtGPUs: "0,1"
      

      也可通过helm提供的 --set 参数覆盖 driver.driverConfig.nodesConfig 项。

      假设 workerNode-1 节点共有四块物理GPU,当vfNum设为2时,节点预期上报数量为8(8=物理GPU数量*vfNum)的 metax-tech.com/gpu 资源。

      配置生效后,可通过以下命令查看目标节点的GPU资源:

      kubectl get node workerNode-1 -o jsonpath='{"Capacity.metax-tech.com/gpu:"}{"\n"}{.status.capacity.metax-tech\.com/gpu}{"\n"}{"Allocatable.metax-tech.com/gpu:"}{"\n"}{.status.allocatable.metax-tech\.com/gpu}{"\n"}'
      
      # output:
      Capacity.metax-tech.com/gpu:
      8
      Allocatable.metax-tech.com/gpu:
      8
      
  2. 运行时修改配置

    GPU Operator 运行后可通过修改 driver-config 更改集群虚拟化状态:

    kubectl edit cm driver-config
    

    data.nodes-config 中直接修改配置,并确保 data.version: v2

  3. v1 到 v2 切换

    • 初始化时:通过 --set 清空 v1 配置(如 driver.vfnumsConfig=null

    • 运行时:手动修改 data.versionv2,并迁移 v1 配置至 nodes-config

  4. 运行Pod任务

    用户可参考如下示例编写作业创建 gpu-task.yaml 文件:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gpu-demo
    spec:
      containers:
      - name: vector-add
        image: ubuntu:20.04
        command: [
            "bash",
            "-c",
            "cp -r /opt/maca/samples/0_Introduction/vectorAdd /home;
            cd /home/vectorAdd;
            mxcc -x maca vectorAdd.cpp -o vectorAdd --maca-path=/opt/maca;
            ./vectorAdd > log/vectoradd_exec_output.log;
            tail -f /dev/null",
        ]
        resources:
          limits:
            metax-tech.com/gpu: 1  # 申请 1 个GPU资源
    

    通过 gpu-task.yaml 文件部署并验证任务:

    #部署任务:
    kubectl apply -f gpu-task.yaml -n metax-operator
    
    #检查 Pod 状态,状态为 Running:
    kubectl get pod gpu-demo -n metax-operator
    
    #查看运行结果:
    kubectl logs pod gpu-demo -n metax-operator
    

2.3.3. v1版配置

  1. 配置方式

    v1仅支持节点级别的虚拟化,如下配置所示:

    kind: ConfigMap
    metadata:
      name: driver-config
    data:
      node-vfnums: |
        nodes:
          sample-node:      # sample-node 每张 GPU 虚拟为 4 个 VF
            vfnum: 4
          sample-node2:     # sample-node2 每张 GPU 虚拟为 2 个 VF
            vfnum: 2
    
    • 生效后,节点资源 metax-tech.com/gpu 的数量调整为:\(N_\mathrm(gpu) \times M_\mathrm(vfnum)\)

    • 期间,以 metax-gpu-device 开头的 Pod 将自动重建,属于正常现象

  2. 运行Pod任务

    v1配置生效后,用户可参考如下示例编写作业创建 gpu-task.yaml 文件:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gpu-demo
    spec:
      containers:
      - name: vector-add
        image: ubuntu:20.04
        command: [
            "bash",
            "-c",
            "cp -r /opt/maca/samples/0_Introduction/vectorAdd /home;
            cd /home/vectorAdd;
            mxcc -x maca vectorAdd.cpp -o vectorAdd --maca-path=/opt/maca;
            ./vectorAdd > log/vectoradd_exec_output.log;
            tail -f /dev/null",
        ]
        resources:
          limits:
            metax-tech.com/gpu: 1  # 申请 1 个GPU资源
    

    通过 gpu-task.yaml 文件部署并验证任务:

    #部署任务:
    kubectl apply -f gpu-task.yaml -n metax-operator
    
    #检查 Pod 状态,状态为 Running:
    kubectl get pod gpu-demo -n metax-operator
    
    #查看运行结果:
    kubectl logs pod gpu-demo -n metax-operator
    

2.4. KubeVirt虚拟机模式

GPU Operator 支持KubeVirt虚拟机场景下Metax GPU的使用,通过driver-manager组件提供的配置项,可自动化加载并绑定GPU设备到VFIO-PCI驱动,以便后续透传至KubeVirt虚拟机。

2.4.1. 准备条件

配置VFIO-PCI驱动相关功能前,需确保环境已完成如下配置:

  • 操作系统开启 IOMMU

  • 操作系统已安装VFIO-PCI驱动

driver-manager通过名为 driver-configConfigMap 资源控制工作节点GPU是否绑定至VFIO-PCI驱动,目前可使用v1、v2两种版本配置。

2.4.2. [推荐] v2版配置

GPU Operator 0.11.0 版本引入 driver config v2,支持通过BDF号配置GPU,相比 v1 具备更细粒度的控制能力。 v2版配置通过 driver-config 控制VFIO-PCI驱动的绑定。

  1. 集群初始化配置

    SR-IOV虚拟化 相同,同样提供 --set-file 或修改 values.yaml 配置两种方式进行初始化。

    • --set-file 方式

      # values.yaml 配置示例
      nodes-config:
        - nodeName: workerNode-1     # workerNode-1 0,1号 GPU 绑定至VFIO-PCI
          vfioGPUs: "0,1"
        - nodeName: workerNode-2     # workerNode-2 所有 GPU 绑定至VFIO-PCI
          vfioGPUs: "all"
      
    • 修改 values.yaml 方式

      # values.yaml 配置示例
      driver:
        driverConfig:
          nodesConfig:
          - nodeName: workerNode-1
            vfioGPUs: "0,1"
          - nodeName: workerNode-2
            vfioGPUs: "all"
      
  2. 运行时切换版本为v2

    修改 driver-configdata.nodes-config 项,并确保 data.version: v2

2.4.3. v1版配置

GPU Operator 使用名为 metax-vfio-configConfigMap 来选择绑定至VFIO-PCI驱动的设备:

kind: ConfigMap
metadata:
  name: metax-vfio-config
data:
  vfio: |
    - nodeName: workerNode-1
      gpus: "0,1"
    - nodeName: workerNode-2
      gpus: "all"
  • 若配置无效 GPU 序号,系统将自动忽略

  • 配置生效后,节点 metax-tech.com/vfio-gpu 资源数等于绑定的 GPU 数量。

  • 关于配置参数的详细介绍,参见《曦云系列通用GPU云原生参考手册》中“组件介绍”章节。

2.4.4. 运行KubeVirt虚拟机

v1或v2任一版本配置生效后,gpu-device组件会将绑定了 VFIO-PCI 驱动的沐曦GPU注册为 metax-tech.com/vfio-gpu 资源,可以在 KubeVirt 上申请该资源。

  1. 配置KubeVirt CR

    KubeVirt CR中的 featureGates 添加 HostDevices, GPU 选项,并将沐曦GPU相应的设备信息配置到 permittedHostDevices 中。

    apiVersion: kubevirt.io/v1
    kind: KubeVirt
    metadata:
      name: kubevirt
      namespace: kubevirt
    spec:
      certificateRotateStrategy: {}
      configuration:
        developerConfiguration:
          featureGates: ["HostDevices", "GPU"]
        permittedHostDevices:
          pciHostDevices:
          - pciVendorSelector: "9999:4000"
            resourceName: "metax-tech.com/vfio-gpu"
            externalResourceProvider: true
          - pciVendorSelector: "9999:4018"
            resourceName: "metax-tech.com/vfio-gpu"
            externalResourceProvider: true
      customizeComponents: {}
      imagePullPolicy: IfNotPresent
      workloadUpdateStrategy: {}
    
  2. 配置虚拟机YAML

    在虚拟机配置的 hostDevices 中添加 metax-tech.com/vfio-gpu 设备。

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      labels:
        kubevirt.io/vm: testvm
      name: testvm
    spec:
      running: false
      template:
        metadata:
          labels:
            kubevirt.io/vm: testvm
        spec:
          domain:
            devices:
              disks:
              - disk:
                  bus: virtio
                name: containerdisk
              - disk:
                  bus: virtio
                name: cloudinitdisk
              interfaces:
              - name: default
                masquerade: {}
              hostDevices:
              - deviceName: metax-tech.com/vfio-gpu
                name: gpu
            resources:
              requests:
                memory: 4096Mi
          terminationGracePeriodSeconds: 0
          networks:
          - name: default
            pod: {}
          volumes:
          - containerDisk:
              image: registry:5000/kubevirt/cirros-container-disk-demo:devel
            name: containerdisk
          - cloudInitNoCloud:
              userData: |
                #!/bin/sh
    
                echo 'printed from cloud-init userdata'
            name: cloudinitdisk
    
  3. 验证GPU设备

    虚拟机启动成功后,可以通过 lspci 命令看到对应的设备。

    user@testvm:~$ lspci | grep 9999
    0a:00.0 Display controller: Device 9999:4000 (rev 01)