# 使用Kubernetes默认GPU调度
Standard/Turbo集群支持使用Kubernetes默认GPU调度模式。该模式基于Device Plugin机制，通过资源类型实现对GPU的标准化管理。当节点安装了CCE AI套件（NVIDIA GPU）插件后，CCE可以自动识别节点上的GPU数量，并在调度时通过resources.limits字段为Pod分配资源（如nvidia.com/gpu: 1）。nvidia.com/gpu支持设置为整数和小数：
- 当nvidia.com/gpu的值设置为正整数（如nvidia.com/gpu: 1）时，表示GPU整卡调度，即该容器将独占使用一张物理GPU卡，系统不会将该卡划分给其他容器使用，适用于对资源性能和隔离要求高的场景。
- 当nvidia.com/gpu的值设置为小数（如nvidia.com/gpu: 0.2）时，表示GPU共享调度，即多个容器可共享同一张物理GPU卡的计算资源和显存，适用于轻量级推理等对算力需求较低的场景。
本文将进一步为您介绍如何使用Kubernetes默认GPU调度模式。关于该模式的更多信息，请参见[调度GPU](https://kubernetes.io/zh-cn/docs/tasks/manage-gpus/scheduling-gpus/)。
#### 注意事项
在集群中使用Kubernetes默认GPU调度时，需要遵循本文中标准的K8s扩展资源申请方式使用GPU资源，具体注意事项如下：
- 请勿直接在节点上运行使用GPU资源的应用程序。
- 请勿直接在GPU节点上通过docker、podman、nerdctl等容器工具单独创建容器来运行GPU业务。例如执行*docker run --gpus all* 或*docker run -e NVIDIA_VISIBLE_DEVICES=all*并运行GPU程序。
- 请勿直接在Pod YAML配置文件的env字段中硬性指定NVIDIA_VISIBLE_DEVICES这类环境变量。同样，也不要在构建镜像时，就将NVIDIA_VISIBLE_DEVICES默认配置为all或其他特定值。
- 在Pod的securityContext中配置privileged: true后，容器可访问节点上所有GPU，可能影响同节点其他容器使用。
上述非标操作可能带来多种隐患：
- 调度器无法精确掌握每个节点的GPU使用情况，任务可能会被调度到资源已用满的节点，出现资源争抢、运行失败的情况。
- 上述非标操作可能会触发NVIDIA驱动或社区已知的兼容性问题，影响业务运行。例如出现[Failed to initialization NVML： Unknown Error报错](https://github.com/NVIDIA/nvidia-docker/issues/1671)。
 
#### 前提条件
- 创建GPU类型节点，具体请参见[创建节点](https://support.huaweicloud.com/usermanual-cce/cce_10_0363.html)。
- 集群中需要安装CCE AI套件（NVIDIA GPU）插件，且安装时注意要选择节点上GPU型号对应的驱动，具体请参见[CCE AI套件（NVIDIA GPU）](https://support.huaweicloud.com/usermanual-cce/cce_10_0141.html)。
- 在v1.28以下的集群中使用默认GPU调度能力时，CCE AI套件（NVIDIA GPU）插件会把驱动的目录挂载到/usr/local/nvidia/lib64，在容器中使用GPU资源需要将/usr/local/nvidia/lib64追加到LD_LIBRARY_PATH环境变量中。v1.28及以上的集群中则无需执行此步骤。 通常可以通过如下三种方式追加环境变量。
  - 制作镜像的Dockerfile中配置LD_LIBRARY_PATH。（推荐）
    ```
    ENV LD_LIBRARY_PATH /usr/local/nvidia/lib64:$LD_LIBRARY_PATH
    ```
    
  
  - 镜像的启动命令中配置LD_LIBRARY_PATH。
    ```
    /bin/bash -c "export LD_LIBRARY_PATH=/usr/local/nvidia/lib64:$LD_LIBRARY_PATH && ..."
    ```
    
  
  - 创建工作负载时定义LD_LIBRARY_PATH环境变量（需确保容器内未配置该变量，不然会被覆盖）。
    ```
    ...
              env:
                - name: LD_LIBRARY_PATH
                  value: /usr/local/nvidia/lib64
    ...
    ```
    
   
 
#### 创建默认GPU调度工作负载
创建默认GPU调度工作负载时，支持使用控制台和kubectl命令行的方式，具体如下：
- [控制台方式]
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。在左侧导航栏单击"工作负载"，右上角单击"创建工作负载"。
  
  2. 在"容器配置 \> 基本信息 \>GPU配额"中选择对应的调度方式，并在下方填写需要的资源量。默认GPU调度包括"GPU整卡"和"共享模式"，具体介绍如下： 
     - GPU整卡：表示GPU整卡调度，即该容器将独立使用GPU卡，系统不会将该卡划分给其他容器使用。
     
     - 共享模式：表示GPU共享调度，即多个容器可共享同一张物理GPU卡的计算资源和显存。
     
     
     图1GPU整卡   
     ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002358757101.png "点击放大")
     
     
     
  
  3. （可选步骤）如果需要为该工作负载指定GPU资源，请在"GPU显卡"处选择对应GPU资源。选择完成后，系统将根据资源类型让Pod与相关节点亲和，从而让Pod选择正确的节点。
  
  4. 其他参数请参考[创建工作负载](https://support.huaweicloud.com/usermanual-cce/cce_10_0673.html)进行配置，参数配置完成后，在右下角单击"创建工作负载"。待工作负载变为运行中后，则表示创建成功。
   
- [kubectl命令行方式]
  1. 使用kubectl连接集群。
  
  2. 执行以下命令，创建YAML文件，用于创建一个使用Kubernetes默认GPU调度的工作负载。 
     ```
     vim gpu-app.yaml
     ```
     文件内容如下：
     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: gpu-test
       namespace: default
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: gpu-test
       template:
         metadata:
           labels:
             app: gpu-test
         spec:
           nodeSelector:
             accelerator: nvidia-t4
           containers:
           - image: nginx:perl
             name: container-0
             resources:
               requests:
                 cpu: 250m
                 memory: 512Mi
                 nvidia.com/gpu: 1   # 非必填，填写时必须与limits.nvidia.com/gpu保持一致
               limits:
                 cpu: 250m
                 memory: 512Mi
                 nvidia.com/gpu: 1   # 用于指定GPU资源量
           imagePullSecrets:
           - name: default-secret
     ```
     - nodeSelector：可选参数，表示节点选择器。创建GPU节点后，系统将会为其加上对应资源标签。使用GPU资源时，可以根据标签让Pod与相关节点亲和，从而让Pod选择正确的节点。 您可以通过以下命令查询节点的标签：
       ```
       kubectl get node -L accelerator
       ```
       回显结果如下，加粗部分即为对应标签值：
       ```
       NAME           STATUS   ROLES    AGE     VERSION                                    ACCELERATOR
       10.100.2.179   Ready    <none>   8m43s   v1.19.10-r0-CCE21.11.1.B006-21.11.1.B006   nvidia-t4
       ```
       
     
     - resources.limits.nvidia.com/gpu：用于指定GPU资源量。
       - 当nvidia.com/gpu的值设置为正整数（如nvidia.com/gpu: 1）时，表示GPU整卡调度，即该容器将独占使用一张物理GPU卡，系统不会将该卡划分给其他容器使用。
       
       - 当nvidia.com/gpu的值设置为小数（如nvidia.com/gpu: 0.2）时，表示GPU共享调度，即多个容器可共享同一张物理GPU卡的计算资源和显存。
       
       
       ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
       requests.nvidia.com/gpu为非必填项，**填写时必须与limits.nvidia.com/gpu保持一致**。
       
     
     
     
     
  
  3. 执行以下命令，创建工作负载。 
     ```
     kubectl apply -f gpu-app.yaml
     ```
     回显结果如下，则说明工作负载已创建。
     ```
     deployment.apps/gpu-test created
     ```
     
     
  
  4. 执行以下命令，查看已创建的Pod名称。 
     ```
     kubectl get pod -n default
     ```
     回显结果如下：
     ```
     NAME                      READY   STATUS    RESTARTS   AGE
     gpu-test-6bdb4d7cb-pmtc2   1/1     Running   0          21s
     ```
     
     
  
  5. 执行以下命令，登录容器内部。 
     ```
     kubectl -n default exec -it gpu-test-6bdb4d7cb-pmtc2 -c container-0 -- /bin/bash
     ```
     
     
  
  6. 在容器内执行以下命令，查看GPU是否分配成功。 
     ```
     nvidia-smi
     ```
     由回显结果可知，GPU分配成功**。**
     ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002324943560.png "点击放大")
     
     
   
#### GPU隔离性验证
为确保容器内对加速器的访问由Kubernetes资源管理框架（设备插件或DRA）和容器运行时进行正确隔离与管控，防止工作负载之间发生未授权访问或相互干扰，您可以进行以下测试进行验证。
测试一：确保容器内对加速器的访问由Kubernetes资源管理框架（设备插件或DRA）和容器运行时进行管控
1. 登录节点，确认设备插件Pod正在运行。
   ```
   kubectl get pods -n kube-system
   ```
   预期输出如下：
   ```
   NAME                                  READY   STATUS    RESTARTS   AGE
   nvidia-gpu-device-plugin-6zf4b        1/1     Running   0          32m
   ```
   
2. 确认设备插件向kubelet上报了正确的GPU资源数量。
   1. 运行**nvidia-smi** 检查GPU数量。
      ```
      Tue Dec 23 10:11:04 2025       
      +-----------------------------------------------------------------------------------------+
      | NVIDIA-SMI 570.86.15              Driver Version: 570.86.15      CUDA Version: 12.8     |
      |-----------------------------------------+------------------------+----------------------+
      | GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
      | Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
      |                                         |                        |               MIG M. |
      |=========================================+========================+======================|
      |   0  NVIDIA L2                      Off |   00000000:00:0D.0 Off |                    0 |
      | N/A   49C    P8             16W /   72W |       1MiB /  23034MiB |      0%      Default |
      |                                         |                        |                  N/A |
      +-----------------------------------------+------------------------+----------------------+
      |   1  NVIDIA L2                      Off |   00000000:00:0E.0 Off |                    0 |
      | N/A   50C    P8             16W /   72W |       1MiB /  23034MiB |      0%      Default |
      |                                         |                        |                  N/A |
      +-----------------------------------------+------------------------+----------------------+
      |   2  NVIDIA L2                      Off |   00000000:00:0F.0 Off |                    0 |
      | N/A   42C    P8             12W /   72W |       1MiB /  23034MiB |      0%      Default |
      |                                         |                        |                  N/A |
      +-----------------------------------------+------------------------+----------------------+
      |   3  NVIDIA L2                      Off |   00000000:00:10.0 Off |                    0 |
      | N/A   41C    P8             12W /   72W |       1MiB /  23034MiB |      0%      Default |
      |                                         |                        |                  N/A |
      +-----------------------------------------+------------------------+----------------------+
      +-----------------------------------------------------------------------------------------+
      | Processes:                                                                              |
      |  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
      |        ID   ID                                                               Usage      |
      |=========================================================================================|
      |  No running processes found                                                             |
      ```
      
   
   2. 检查节点信息，确认设备插件注册的可用GPU数量。
      ```
      kubectl describe node
      ```
      回显如下：
      ```
      Capacity:
        cpu:                96
        ephemeral-storage:  1055758772Ki
        hugepages-1Gi:      0
        hugepages-2Mi:      0
        localssd:           0
        localvolume:        0
        memory:             792305148Ki
        nvidia.com/gpu:     4
        pods:               110
      Allocatable:
        cpu:                95690m
        ephemeral-storage:  972987282665
        hugepages-1Gi:      0
        hugepages-2Mi:      0
        localssd:           0
        localvolume:        0
        memory:             771057148Ki
        nvidia.com/gpu:     4
        pods:               110
      ```
      
    
3. 创建一个请求GPU资源的负载。
   YAML示例如下：
   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: pytorch-cuda-check
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: pytorch-cuda-check
     template:
       metadata:
         labels:
           app: pytorch-cuda-check
       spec:
         containers:
           - name: pytorch-cuda-check
             image: nvcr.io/nvidia/pytorch:25.09-py3
             command: ["/bin/sh", "-c"]
             args:
               - |
                 while true; do
                   python3 -c "import torch; print(torch.cuda.device_count())"
                   sleep 30
                 done
             resources:
               limits:
                 nvidia.com/gpu: 1
   ```
   观察所创建负载的运行状态。
   ```
   kubectl get pods -w
   ```
   回显如下：
   ```
   NAME                                  READY   STATUS    RESTARTS   AGE
   pytorch-cuda-check-68bc4bf767-pdgw7   1/1     Running   0          15m
   ```
   
4. 更新Deployment，移除Pod规格中的资源请求，容器内的命令应当失败。
   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: pytorch-cuda-check
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: pytorch-cuda-check
     template:
       metadata:
         labels:
           app: pytorch-cuda-check
       spec:
         containers:
           - name: pytorch-cuda-check
             image: nvcr.io/nvidia/pytorch:25.09-py3
             command: ["/bin/sh", "-c"]
             args:
               - |
                 while true; do
                   python3 -c "import torch; print(torch.cuda.device_count())"
                   sleep 30
                 done
             # resources:
             #   limits:
             #     nvidia.com/gpu: 1
   ```
   查看日志，应显示失败信息。
   ```
   kubectl logs pytorch-cuda-check-68bc4bf767-2zm7s
   ```
   回显如下：
   ```
   /usr/local/lib/python3.12/dist-packages/torch/cuda/__init__.py:63: FutureWarning: The pynvml package is deprecated. Please install nvidia-ml-py instead. If you did not install pynvml directly, please report this to the maintainers of the package that installed pynvml for you.
     import pynvml  # type: ignore[import]
   0
   ```
   
 
测试二：确保容器内对加速器的访问得到正确隔离
1. 创建两个Pod，每个Pod分配一个加速器资源。运行**nvidia-smi** 确保每个Pod只能访问分配给自己的加速器。
   YAML示例如下：
   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: pytorch-cuda-check-2
   spec:
     replicas: 2
     selector:
       matchLabels:
         app: pytorch-cuda-check
     template:
       metadata:
         labels:
           app: pytorch-cuda-check
       spec:
         containers:
           - name: pytorch-cuda-check
             image: nvcr.io/nvidia/pytorch:25.09-py3
             command: ["/bin/sh", "-c"]
             args:
               - |
                 while true; do
                   python3 -c "import torch; print(torch.cuda.device_count())"
                   sleep 30
                 done
             resources:
               limits:
                 nvidia.com/gpu: 1
   ```
   观察Pod的运行状态：
   ```
   kubectl get pods -w
   ```
   回显如下：
   ```
   NAME                                    READY   STATUS    RESTARTS   AGE
   pytorch-cuda-check-2-68bc4bf767-h8b7q   1/1     Running   0          3m55s
   pytorch-cuda-check-2-68bc4bf767-jb2kq   1/1     Running   0          3m55s
   ```
   
2. 验证每个Pod分配到了不同的GPU。
   ```
   kubectl exec -it pytorch-cuda-check-2-68bc4bf767-h8b7q -- nvidia-smi -L
   kubectl exec -it pytorch-cuda-check-2-68bc4bf767-jb2kq -- nvidia-smi -L
   ```
   回显如下：
   ```
   GPU 0: NVIDIA L2 (UUID: GPU-1dda2a1d-a678-15e2-f2cc-9b0622d3d523)
   GPU 0: NVIDIA L2 (UUID: GPU-f71e5af2-ca6e-ccc7-e612-c9d23092c9b4)
   ```
   
 
#### 常见问题
**问题现象**：工作负载创建失败，报错信息如下：
- 0/2 nodes are available: 2 Insufficient nvidia.com/gpu.
- 0/4 nodes are available: 1 InsufficientResourceOnSingleGPU, 3 Insufficient nvidia.com/gpu.
**问题原因** ：对应的GPU资源不足。指定**nvidia.com/gpu**后，系统不会将负载调度到没有GPU的节点，当资源不足时，将会产生上述错误。
**解决方案**：购买对应的GPU节点，保证GPU资源充足。
