

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 在 Amazon EKS 上管理 NVIDIA GPU 设备
<a name="device-management-nvidia"></a>

NVIDIA GPU 广泛用于机器学习训练、推理和高性能计算工作负载。Amazon EKS 支持两种在 EKS 集群中管理 NVIDIA GPU 设备的机制：*适用于 GPU 的 NVIDIA DRA 驱动程序*和 *NVIDIA Kubernetes 设备插件*。

对于在运行 Kubernetes 1.34 或更高版本的集群上使用 EKS 托管节点组或自行管理的节点组进行的新部署，建议使用 NVIDIA DRA 驱动程序。NVIDIA DRA 驱动程序支持灵活的 GPU 分配以及容器间的 GPU 共享。

NVIDIA DRA 驱动程序不支持与 Karpenter 或 EKS 自动模式结合使用。请将 [NVIDIA 设备插件](#nvidia-device-plugin)与 Karpenter 和 EKS 自动模式结合使用。NVIDIA 设备插件仍然支持与 EKS 托管节点组和自行管理的节点结合使用。

## NVIDIA DRA 驱动程序与 NVIDIA 设备插件
<a name="_nvidia_dra_driver_vs_nvidia_device_plugin"></a>


| 能力 | NVIDIA DRA 驱动程序 | NVIDIA 设备插件 | 
| --- | --- | --- | 
| 最低 Kubernetes 版本 | 1.34 | 所有 EKS 支持的 Kubernetes 版本 | 
| EKS 计算 | 托管节点组、自行管理的节点 | EKS 自动模式、Karpenter、托管节点组、自行管理的节点 | 
| EKS 优化型 AMI | AL2023（NVIDIA） | AL2023（NVIDIA）、Bottlerocket | 
| 设备发布方式 | 通过 `ResourceSlice` 对象发布丰富属性，包括 GPU 型号、显存、驱动程序版本和拓扑 | 以整数计数形式发布 `nvidia.com/gpu` 扩展资源 | 
| GPU 共享 | 同一容器组（pod）中的多个容器可以通过共享 `ResourceClaim` 引用共享一个 GPU | 不支持。每个 GPU 独占分配给一个容器。 | 
| ComputeDomains | 通过 `ComputeDomain` 资源管理多节点 NVLink (MNNVL)，实现安全的多节点 GPU 通信 | 不支持 | 
| 基于属性的选择 | 使用 CEL 表达式按型号、显存或其他属性筛选 GPU | 不支持 | 
| 拓扑感知 EFA 分配 | DRA 原生拓扑感知 | 自动拓扑感知（仅限 EKS 优化版 AL2023 AMI） | 

## 安装 NVIDIA DRA 驱动程序
<a name="nvidia-dra-driver"></a>

适用于 GPU 的 NVIDIA DRA 驱动程序管理两种类型的资源：GPU 和 ComputeDomain。它运行两个 DRA kubelet 插件：`gpu-kubelet-plugin` 和 `compute-domain-kubelet-plugin`。这两个插件可在安装时分别启用或禁用。本指南重点介绍 GPU 分配。有关使用 ComputeDomain 的信息，请参阅 [将 P6e-GB200 UltraServer 与 Amazon EKS 搭配使用](ml-eks-nvidia-ultraserver.md)。

### 先决条件
<a name="_prerequisites"></a>
+ 运行 Kubernetes 1.34 或更高版本的 Amazon EKS 集群，使用 EKS 托管节点组或自行管理的节点组。
+ 具有 NVIDIA GPU 实例类型（例如 `P` 或 `G` 实例）的节点。
+ 为 NVIDIA GPU 安装主机级组件的节点。当使用 EKS 优化型 AL2023 或 Bottlerocket NVIDIA AMI 时，主机级 NVIDIA 驱动程序、CUDA 用户模式驱动程序和容器工具包已预装。
+ 在命令行环境中安装 Helm，有关更多信息，请参阅[安装 Helm 说明](helm.md)。
+  `kubectl` 配置为与您的集群通信，更多信息，请参阅 [安装或更新 `kubectl`](install-kubectl.md#kubectl-install-update)。

### 过程
<a name="_procedure"></a>

**重要**  
当使用 NVIDIA DRA 驱动程序进行 GPU 设备管理时，不能与 NVIDIA 设备插件部署在同一节点上。有关更新，请参阅上游 Kubernetes [KEP–5004](https://github.com/kubernetes/enhancements/issues/5004)。

**重要**  
目前不支持将 NVIDIA DRA 驱动程序与 Bottlerocket 结合使用。

1. 添加 NVIDIA DRA 驱动程序 Helm 图表存储库。

   ```
   helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
   ```

1. 更新本地 Helm 存储库。

   ```
   helm repo update
   ```

1. 获取最新版本的 NVIDIA DRA 驱动程序。

   ```
   helm search repo nvidia/nvidia-dra
   ```

1. 安装 NVIDIA DRA 驱动程序。

   ```
   helm install nvidia-dra-driver-gpu nvidia/nvidia-dra-driver-gpu \
       --create-namespace \
       --namespace nvidia-dra-driver-gpu \
       --set resources.computeDomains.enabled=false \
       --set 'gpuResourcesEnabledOverride=true'
   ```

   有关高级配置选项，请参阅 [NVIDIA DRA 驱动程序 Helm 图表](https://github.com/kubernetes-sigs/nvidia-dra-driver-gpu/blob/main/deployments/helm/nvidia-dra-driver-gpu/values.yaml)。

1. 验证 DRA 驱动程序容器组（pod）是否正在运行。

   ```
   kubectl get pods -n nvidia-dra-driver-gpu
   ```

1. 验证 `DeviceClass` 对象是否已创建。

   ```
   kubectl get deviceclass
   ```

   ```
   NAME            AGE
   gpu.nvidia.com  60s
   ```

1. 验证是否为您的 GPU 节点发布了 `ResourceSlice` 对象。

   ```
   kubectl get resourceslice
   ```

   要使用 DRA 驱动程序请求 NVIDIA GPU，请创建一个引用 `gpu.nvidia.com` `DeviceClass` 的 `ResourceClaimTemplate`，并在您的容器组（pod）规约中引用它。以下示例请求单个 GPU。有关分配具有拓扑对齐的 EFA 接口之 NVIDIA GPU 的步骤，请参阅[拓扑感知的 EFA 和 GPU/Neuron 设备分配](device-management-efa.md#efa-dra-topology-aware)。

   ```
   apiVersion: resource.k8s.io/v1
   kind: ResourceClaimTemplate
   metadata:
     name: single-gpu
   spec:
     spec:
       devices:
         requests:
         - name: gpu
           exactly:
             deviceClassName: gpu.nvidia.com
             count: 1
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     name: gpu-workload
   spec:
     containers:
     - name: app
       ...
       resources:
         claims:
         - name: gpu
     resourceClaims:
     - name: gpu
       resourceClaimTemplateName: single-gpu
     tolerations:
     - key: "nvidia.com/gpu"
       operator: "Exists"
       effect: "NoSchedule"
   ```

## 安装 NVIDIA Kubernetes 设备插件
<a name="nvidia-device-plugin"></a>

NVIDIA Kubernetes 设备插件将 NVIDIA GPU 作为 `nvidia.com/gpu` 扩展资源进行发布。您在容器的资源请求和限制中请求 GPU。

### 先决条件
<a name="_prerequisites_2"></a>
+ 一个 Amazon EKS 集群。
+ 使用 EKS 优化型 AL2023 NVIDIA AMI 的 NVIDIA GPU 实例类型的节点。EKS 优化型 Bottlerocket AMI 已包含 NVIDIA 设备插件，无需单独安装。
+ 在命令行环境中安装 Helm，有关更多信息，请参阅[安装 Helm 说明](helm.md)。
+  `kubectl` 配置为与您的集群通信，更多信息，请参阅 [安装或更新 `kubectl`](install-kubectl.md#kubectl-install-update)。

### 过程
<a name="_procedure_2"></a>

1. 添加 NVIDIA 设备插件 Helm 图表存储库。

   ```
   helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
   ```

1. 更新本地 Helm 存储库。

   ```
   helm repo update
   ```

1. 安装 NVIDIA Kubernetes 设备插件。

   ```
   helm install nvdp nvdp/nvidia-device-plugin \
       --namespace nvidia \
       --create-namespace \
       --set gfd.enabled=true
   ```
**在搭载 EFA 设备的节点上禁用 MOFED**  
从 `k8s-device-plugin` v0.19.0 开始，`--mofed-enabled` 标志默认为 `true`。这会导致 NVIDIA 设备插件将所有 `/dev/infiniband/uverbs*` 设备挂载到请求 GPU 的容器中 (`nvidia.com/gpu`)。这与管理 AWS 设备安装的 EFA `uverbs` 设备插件冲突。请求少于节点上所有 EFA 设备的工作负载会受到影响，因为默认情况下，NVIDIA 设备插件会占用所有 `uverbs` 设备。  
如果节点有 EFA 设备，请在安装 NVIDIA 设备插件时明确禁用 MOFED：  

   ```
   helm upgrade --install nvdp nvdp/nvidia-device-plugin \
       --namespace nvidia \
       --create-namespace \
       --set gfd.enabled=true \
       --set mofedEnabled=false
   ```
如果通过 [NVIDIA GPU Operator](https://github.com/NVIDIA/gpu-operator) 管理 NVIDIA 设备插件，请通过 `devicePlugin.env` 字段禁用 MOFED：  

   ```
   helm upgrade --install gpu-operator nvidia/gpu-operator \
       --namespace gpu-operator \
       --set 'devicePlugin.env[0].name=MOFED_ENABLED' \
       --set 'devicePlugin.env[0].value=false'
   ```
有关更多信息，请参阅 [NVIDIA k8s-device-plugin issue \#1692](https://github.com/NVIDIA/k8s-device-plugin/issues/1692)。
**注意**  
您也可以使用 [NVIDIA GPU Operator](https://github.com/NVIDIA/gpu-operator) 来安装和管理 NVIDIA Kubernetes 设备插件，该 Operator 可自动管理配置 GPU 所需的所有 NVIDIA 软件组件。

1. 验证 NVIDIA 设备插件 DaemonSet 是否正在运行。

   ```
   kubectl get ds -n nvidia nvdp-nvidia-device-plugin
   ```

   ```
   NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
   nvdp-nvidia-device-plugin   2         2         2       2            2           <none>          60s
   ```

1. 验证节点是否具有可分配的 GPU。

   ```
   kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"
   ```

   示例输出如下。

   ```
   NAME                                           GPU
   ip-192-168-11-225.us-west-2.compute.internal   1
   ip-192-168-24-96.us-west-2.compute.internal    1
   ```

### 在容器组（pod）中请求 NVIDIA GPU
<a name="_request_nvidia_gpus_in_a_pod"></a>

要使用设备插件请求 NVIDIA GPU，请在容器的资源请求和限制中指定 `nvidia.com/gpu` 资源。

```
apiVersion: v1
kind: Pod
metadata:
  name: nvidia-smi
spec:
  restartPolicy: OnFailure
  containers:
  - name: gpu-demo
    image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
    command: ["/bin/sh", "-c"]
    args: ["nvidia-smi && tail -f /dev/null"]
    resources:
      limits:
        nvidia.com/gpu: 1
      requests:
        nvidia.com/gpu: 1
  tolerations:
  - key: "nvidia.com/gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"
```

要运行此测试，请应用清单并查看日志：

```
kubectl apply -f nvidia-smi.yaml
kubectl logs nvidia-smi
```

示例输出如下。

```
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI XXX.XXX.XX            Driver Version: XXX.XXX.XX     CUDA Version: XX.X      |
|-----------------------------------------+------------------------+----------------------+
| 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 L4                      On  |   00000000:31:00.0 Off |                    0 |
| N/A   27C    P8             11W /   72W |       0MiB /  23034MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+
```