
# NVIDIA DRA插件安装指导
为突破传统设备插件在复杂参数传递与动态GPU资源分配上的局限，Kubernetes 1.26引入了DRA（Dynamic Resource Allocation）机制，通过原生API支持细粒度、按需分配的GPU资源调度。NVIDIA DRA驱动与之协同，可实现Pod间动态共享、虚拟化GPU资源，显著提升利用率，降低大模型（LLM）训练与多租户推理场景下的硬件成本。
#### 应用现状
在Kubernetes的早期，GPU资源的调度完全依赖于Device Plugin机制。随着大模型训练、多租户推理以及GPU虚拟化技术的普及，这种传统的"按个计数"的粗放式分配方式已无法满足复杂的业务需求，主要面临以下瓶颈：
- 参数表达能力薄弱：Device Plugin只能处理简单的整数资源请求（如nvidia.com/gpu: 2）。对于"请求2个通过NVLink互联的GPU"或"一个特定显存大小的MIG切片"等复杂需求，传统的YAML格式难以直接、精确地表达。
- 静态配置灵活性缺失：以MIG为例，GPU的切分规格必须在节点初始化时静态配置，无法在运行时动态调整。业务需要变更资源规格时，往往需要重启节点，无法实现真正的"按需分配"。
- 调度与分配脱节：由于Device Plugin采用"预分配"模式，调度器只能获得GPU数量的粗粒度信息，而无法获取如拓扑结构等关键细节，造成调度策略与实际设备能力之间的脱节，限制了资源利用效率与任务性能优化。
- 资源清理不可靠：由于缺乏严格的资源生命周期管理，当Pod异常退出时，可能发生GPU资源释放不彻底的问题，影响集群的稳定性和资源利用率。
 
#### 解决方案
为突破上述瓶颈，Kubernetes自1.26版本起引入了DRA动态资源分配机制。它并非直接取代Device Plugin，而是作为其强有力的补充，为复杂场景提供了更精细、更灵活的解决方案。NVIDIA DRA Driver正是基于此框架开发，旨在将GPU从"可计数的资源"升级为"可描述、可配置的对象"。以下是其主要特点：
- 灵活的设备过滤：支持使用CEL（Common Expression Language） 对设备属性进行细粒度过滤。
- 资源共享：通过引用相应的资源声明，多个容器或Pod可以安全共享相同的设备资源。
- 集中化设备管理：设备驱动和集群管理员可以通过设备类对设备进行统一分类管理。这些设备类可以依据硬件性能和应用需求优化配置。例如，您可以为通用工作负载定义一个成本优化型设备类，为高要求任务提供一个高性能设备类，从而满足多种应用场景的特定需求。
- 简化Pod资源请求管理：使用DRA后，应用运维人员不再需要在创建Pod时显式指定设备的详细规格。相反，Pod只需引用一个预先配置的资源申领，系统会根据这个申领的配置，自动将相应的设备分配给Pod，大幅提升开发和管理效率。
 
#### 前提条件
- 已创建1.34及以上版本的集群。
- 已准备好镜像。 本教程需要以下两个镜像，请提前在一台能够访问公网且已安装Docker的机器上完成下载。
  1. 下载镜像。
     ```
     docker pull nvcr.io/nvidia/k8s-dra-driver-gpu:v25.8.0
     docker pull ubuntu:22.04
     ```
     
  
  2. 将下载的镜像上传至SWR镜像仓库，以确保Kubernetes集群内的所有节点可以拉取。 上传镜像的具体方法请参见[上传镜像](https://support.huaweicloud.com/qs-swr/index.html#section6)。
     
   
 
#### 约束与限制
GPU节点的容器运行时必须是Containerd。
#### 操作步骤
1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。
2. 安装NVIDIA GPU插件。 
   1. 在左侧导航栏中选择"插件中心"，在右侧找到**CCE AI套件（NVIDIA GPU）**插件，单击"安装"。
   
   2. 在"安装插件"面板中，设置以下参数。 ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002517161196.png)
      - 插件版本：须选择2.12.0及之后版本。本文以2.12.0版本为例。
      
      - 集群默认驱动：须选择570.86.15及之后版本。本文以570.86.15版本为例。若选择v25.12.0及以上版本的DRA，请安装580及以上版本的GPU驱动。
      
      
      更多驱动版本信息，请参见[CCE AI套件（NVIDIA GPU）](https://support.huaweicloud.com/usermanual-cce/cce_10_0141.html)。
      
   
   3. 单击"YAML安装"，修改"spec.values.custom"中的"dra_mode"参数值为"true"，并单击"提交"**。**
      ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002518194454.png "点击放大")
      
      
      
   
   
   
   
3. 验证驱动是否安装成功**。**
   
   1. 在"插件中心"页面，查看已安装NVIDIA GPU插件的详情。 确认节点上的nvidia-driver-installer状态为"运行中"。
      ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002548804697.png "点击放大")
      
      
   
   2. 在节点上执行以下命令，确认GPU驱动是否正常加载。
      ```
      nvidia-smi
      ```
      如果输出了GPU的信息（如型号），说明驱动已成功安装。
      ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002517204992.png "点击放大")
      
   
   
   
   
4. （可选）准备CDI。 
   您可以在目标集群的"概览"页面，查看集群的补丁版本。如果补丁版本为v1.34.2-r0及之后版本，则可以跳过本步骤。
   1. 执行以下命令，编辑containerd配置文件。
      ```
      vi /etc/containerd/config.toml
      ```
      
   
   2. 在\[plugins."io.containerd.grpc.v1.cri"\]配置段中，添加以下参数。
      ```
      enable_cdi = true
      cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"]
      ```
      
   
   3. 重启containerd服务使配置生效。
      ```
      systemctl restart containerd
      ```
      
   
   4. 检查containerd日志，确认CDI已成功启用。
      ```
      cat /var/log/cce/containerd/containerd.log | grep -i cdi
      ```
      若日志中出现以下内容，则说明CDI已正确开启。
      ```
      EnableCDI:true CDISpecDirs:[/etc/cdi /var/run/cdi]
      ```
      
   
   
   
   
5. 安装NVIDIA DRA驱动。 
   在目标节点上执行以下命令。
   1. 安装Helm。本文以3.19.3版本为例。
      ```
      curl -O https://get.helm.sh/helm-v3.19.3-linux-amd64.tar.gz
      tar xvf helm-v3.19.3-linux-amd64.tar.gz 
      cp ./linux-amd64/helm /usr/local/bin/ 
      helm version
      ```
      若回显如下，则说明安装成功。
      ```
      version.BuildInfo{Version:"v3.19.3", GitCommit:"0707f566a3f4ced24009ef14d67fe0ce69db****", GitTreeState:"clean", GoVersion:"go1.24.10"}
      ```
      
   
   2. 获取Helm模板包。
      ```
      helm fetch https://helm.ngc.nvidia.com/nvidia/charts/nvidia-dra-driver-gpu-25.8.0.tgz
      tar xvf nvidia-dra-driver-gpu-25.8.0.tgz
      cd nvidia-dra-driver-gpu
      ```
      
   
   3. 创建命名空间。
      ```
      kubectl create namespace nvidia-dra
      ```
      
   
   4. 安装nvidia-dra-driver。
      ```
      helm install nvidia-dra . --namespace nvidia-dra \
        --set resources.computeDomains.enabled=false \
        --set gpuResourcesEnabledOverride=true \
        --set image.repository="<需要填入实际SWR镜像地址>" \
        --set image.tag="v25.8.0" \
        --set "kubeletPlugin.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].key=accelerator" \
        --set "kubeletPlugin.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].operator=Exists" \
        --set "kubeletPlugin.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[1].key=kubernetes.io/role" \
        --set "kubeletPlugin.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[1].operator=NotIn" \
        --set "kubeletPlugin.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[1].values[0]=virtual-kubelet" \
        --set "kubeletPlugin.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[1].values[1]=edge" \
        --set nvidiaDriverRoot="/usr/local/nvidia"
      ```
      代码中需要根据实际情况修改以下参数：
      - "image.repository"：需要替换为您在SWR仓库中上传的k8s-dra-driver-gpu镜像地址。
      
      - "image.tag"：根据实际使用的镜像版本进行调整。例如 ，v25.8.0。
      
      - "nvidiaDriverRoot"：如果NVIDIA驱动不是通过CCE AI套件安装，需要指定实际的驱动安装路径。
      
      
      预期输出示例如下。
      ```
      NAME: nvidia-dra
      LAST DEPLOYED: xxx xxx xxx xx:xx:xx xxxx
      NAMESPACE: nvidia-dra
      STATUS: deployed
      REVISION: 1
      TEST SUITE: None
      ```
      
   
   5. 验证DeviceClass是否生成。
      ```
      kubectl get deviceclass
      ```
      预期输出示例如下。
      ```
      NAME             AGE
      gpu.nvidia.com   74s
      mig.nvidia.com   74s
      ```
      
   
   6. 验证ResourceSlices是否生成。
      ```
      kubectl get resourceslices
      ```
      预期输出示例如下。
      ```
      NAME                                 NODE            DRIVER           POOL            AGE
      192.168.**.**-gpu.nvidia.com-5rrfv   192.168.**.**   gpu.nvidia.com   192.168.**.**   71s
      ```
      
   
   
   
   
6. 验证NVIDIA驱动是否成功**。**
   
   1. 创建一个名为"gpu-pod.yaml"的文件。其中，"gpu-pod.yaml"为自定义名称。
      ```
      vi gpu-pod.yaml
      ```
      文件内容示例如下。
      ```
      apiVersion: resource.k8s.io/v1
      kind: ResourceClaimTemplate
      metadata:
        name: single-gpu
      spec:
        spec:
          devices:
            requests:
            - exactly:
                allocationMode: ExactCount
                deviceClassName: gpu.nvidia.com
                count: 1
              name: gpu
      ---
      apiVersion: v1
      kind: Pod
      metadata:
        name: pod1
        labels:
          app: pod
      spec:
        containers:
        - name: ctr
          image: {{填入在前提条件中下载的Ubuntu镜像}}:22.04
          command: ["bash", "-c"]
          args: ["nvidia-smi -L; trap 'exit 0' TERM; sleep 9999 & wait"]
          resources:
            claims:
            - name: gpu
        resourceClaims:
        - name: gpu
          resourceClaimTemplateName: single-gpu
      ```
      
   
   2. 创建Deployment。
      ```
      kubectl create -f gpu-pod.yaml
      ```
      
   
   3. 查看Deployment状态以验证NVIDIA驱动是否成功。
      ```
      kubectl get pod -owide
      ```
      您可以看到pod1处于Running状态。
      
   
   4. 查看Pod日志，确认是否成功挂载了GPU。
      ```
      kubectl logs pod1
      ```
      
   
   5. 查看GPU信息。
      ```
      kubectl exec -it pod1 -- /bin/bash
      nvidia-smi
      ```
      若能正常返回GPU信息，说明设备可用，插件安装成功。
      ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002517288590.png "点击放大")
      
   
   
   
   
 
