

 **帮助改进此页面** 

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

# 管理 Amazon EKS 上的 EFA 设备
<a name="device-management-efa"></a>

 [Elastic Fabric Adapter](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html)（EFA）是一种用于 Amazon EC2 实例的网络设备，可为人工智能、机器学习和高性能计算（HPC）工作负载实现高性能的节点间通信与 RDMA（远程直接内存访问）。Amazon EKS 支持两种在 EKS 集群中管理 EFA 设备的机制：*EFA 动态资源分配（DRA）驱动程序（DRANET）*和 *EFA 设备插件*。

对于在运行 Kubernetes 1.34 或更高版本的 EKS 集群上使用 EKS 托管节点组，或自行管理的节点组进行的新部署，建议使用 EFA DRA 驱动程序（DRANET）。借助 EFA DRA 驱动程序，您可以配置拓扑感知分配，将 EFA 接口与其拓扑邻近的 GPU 或 Neuron 设备配对，并支持在 Pod 之间共享设备。

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

## EFA DRA 驱动程序与 EFA 设备插件
<a name="eks-efa-dra-vs-device-plugin"></a>


| 功能 | EFA DRA 驱动程序 | EFA 设备插件 | 
| --- | --- | --- | 
| 最低 Kubernetes 版本 | 1.34 | 所有 EKS 支持的 Kubernetes 版本 | 
| EKS 计算 | 托管节点组、自行管理的节点 | EKS 自动模式、Karpenter、托管节点组、自行管理的节点 | 
| EKS 优化型 AMI | AL2023（NVIDIA、Neuron）、Bottlerocket | AL2023（NVIDIA、Neuron）、Bottlerocket | 
| 设备发布方式 | 通过 `ResourceSlice` 对象发布丰富属性，包括设备类型、拓扑和 PCIe 就近性 | 以整数计数形式发布 `vpc.amazonaws.com/efa` 扩展资源 | 
| GPU-EFA 亲和性 | DRA 原生拓扑感知 | 自动拓扑感知（仅限 EKS 优化版 AL2023 AMI） | 
| Neuron-EFA 亲和性 | DRA 原生拓扑感知 | 自动拓扑感知（仅限 EKS 优化版 AL2023 AMI） | 
| 设备共享 | 多个容器组（pod）可以通过共享 `ResourceClaim` 引用共享同一个 EFA 设备 | 不支持。每个 EFA 设备专用于一个容器组（pod）。 | 

## 创建带有 EFA 接口的 EKS 节点
<a name="eks-efa-nodes"></a>

当您创建带有 EFA 接口的 EKS 节点时，EFA 接口会在实例预置期间附加到实例。您可以自定义每台设备的 EFA 配置，并将[置放群组](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html)与 Karpenter、EKS 托管节点组或 EKS 自行管理的节点组结合使用。使用 Karpenter 时，您可以通过 `NodeClass` 传递每个网络接口的配置。使用 EKS 托管节点组或自行管理的节点时，您可以通过[启动模板](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html)传递每个网络接口的配置。即将推出 EKS 自动模式对每台设备 EFA 配置和置放群组的支持。

当使用 [`eksctl`](install-kubectl.md#eksctl-install-update) 并以 `efaEnabled` 设置配置 EKS 节点时，所有接口都要配置接口类型 `EFA`，系统会创建一个特定于 EFA 的安全组，并在集群上安装 EFA 设备插件。如果您在使用 `eksctl` 时需要自定义每设备的 EFA 配置，建议使用 eksctl 对[启动模板](https://docs.aws.amazon.com/eks/latest/eksctl/launch-template-support.html)的支持。

以下示例演示了如何配置具有 EFA 接口的 `NodeClass` 和启动模板。这对于自定义用于 EFA 和基于 IP 的标准流量的接口非常有用。有关每种实例类型支持的 EFA 接口数量以及如何为最大网络带宽配置它们的信息，请参阅《Amazon EC2 用户指南**》中的[最大限度地提高启用 EFA 的实例类型的网络带宽](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-acc-inst-types.html)。

## Karpenter
<a name="eks-efa-auto-karpenter"></a>

`networkInterfaces` 中的每个条目都指定了 `networkCardIndex`、`deviceIndex` 和 `interfaceType`。`interfaceType` 可以是标准网络接口的 `interface`，也可以是专用于 RDMA 流量且不分配 IP 地址的 EFA 接口的 `efa-only`。`networkInterfaces` 配置完成后，无论容器组（pod）是否请求 `vpc.amazonaws.com/efa` 资源，由引用 `NodeClass` 的 `NodePool` 启动的实例都会使用此配置。

当使用 Karpenter 且未在 `NodeClass` 中指定 `networkInterfaces` 时，为请求 `vpc.amazonaws.com/efa` 的容器组（pod）创建的实例会将所有接口配置为接口类型 `EFA`。

在 Karpenter v1.11 中增加了对 `EC2NodeClass` 的 `networkInterfaces` 配置。以下示例演示了为 P6-B200 实例配置的 `EC2NodeClass`，具有 1 个 ENA 接口和 8 个仅限 EFA 的接口。

### 示例：为 P6-B200 配置仅限 EFA 接口的 Karpenter EC2NodeClass
<a name="eks-efa-karpenter-example"></a>

```
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: efa-node-class
spec:
  networkInterfaces:
  - networkCardIndex: 0
    deviceIndex: 0
    interfaceType: interface
  - networkCardIndex: 0
    deviceIndex: 1
    interfaceType: efa-only
  - networkCardIndex: 1
    deviceIndex: 0
    interfaceType: efa-only
  - networkCardIndex: 2
    deviceIndex: 0
    interfaceType: efa-only
  - networkCardIndex: 3
    deviceIndex: 0
    interfaceType: efa-only
  - networkCardIndex: 4
    deviceIndex: 0
    interfaceType: efa-only
  - networkCardIndex: 5
    deviceIndex: 0
    interfaceType: efa-only
  - networkCardIndex: 6
    deviceIndex: 0
    interfaceType: efa-only
  - networkCardIndex: 7
    deviceIndex: 0
    interfaceType: efa-only
```

## EKS 托管节点组与自行管理的节点
<a name="eks-efa-mng-self-managed"></a>

使用 EKS 托管节点组或自行管理的节点时，您可以通过[启动模板](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html)传递每个网络接口的配置。

以下示例演示了为 P6-B200 实例配置的启动模板，具有 1 个 ENA 接口和 8 个仅限 EFA 的接口。主网络接口（网卡 0，设备索引 0）使用 `interface` 标准类型处理 IP 流量，而附加接口则使用 `efa-only` 处理专用 RDMA 流量。根据实例类型调整 `efa-only` 接口数量。有关每种实例类型支持的 EFA 接口数量，请参阅《Amazon EC2 用户指南**》中的[最大限度地提高启用 EFA 的实例类型的网络带宽](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-acc-inst-types.html)。

### 示例：为 P6-B200 配置仅限 EFA 接口的启动模板
<a name="eks-efa-launch-template-example"></a>

将 ` security-group-id ` 替换为您自己的值。安全组必须允许进出其本身的所有入站和出站流量，以启用 EFA 操作系统绕过功能。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[步骤 1：准备启用 EFA 的安全组](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-security)。

**重要**  
使用 EKS 托管节点组时，请勿在启动模板中指定 `SubnetId`。EKS 要求通过 `CreateNodegroup` API 指定所有子网，并拒绝包含子网配置的启动模板。

```
{
  "LaunchTemplateName": "efa-launch-template",
  "LaunchTemplateData": {
    "InstanceType": "p6-b200.48xlarge",
    "NetworkInterfaces": [
      {
        "NetworkCardIndex": 0,
        "DeviceIndex": 0,
        "InterfaceType": "interface",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 0,
        "DeviceIndex": 1,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 1,
        "DeviceIndex": 0,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 2,
        "DeviceIndex": 0,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 3,
        "DeviceIndex": 0,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 4,
        "DeviceIndex": 0,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 5,
        "DeviceIndex": 0,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 6,
        "DeviceIndex": 0,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      },
      {
        "NetworkCardIndex": 7,
        "DeviceIndex": 0,
        "InterfaceType": "efa-only",
        "Groups": ["security-group-id"]
      }
    ]
  }
}
```

## 将 EKS 优化的 AMI 与 EFA 配合使用
<a name="eks-amis-efa"></a>

EKS 优化版 AL2023 加速型 AMI（NVIDIA 和 Neuron）和所有 Bottlerocket AMI 都包含使用 EFA 所需的主机级组件（即由 [aws-efa-installer](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-enable) 安装的组件）。EKS AL2023 和 Bottlerocket AMI **不包含** EFA DRA 驱动程序或 EFA 设备插件，在部署工作负载之前必须将其单独安装到集群上。

## 节省 IP 地址分配
<a name="eks-efa-conserve-ip"></a>

启用 EFA 的实例（例如 `p5.48xlarge` 和 `p6-b200.48xlarge`）支持许多网络接口。默认情况下，Amazon VPC CNI 会在所有启用 IP 的附加 ENI 上分配 IP 地址，即使这些地址未被容器组（pod）积极使用，也可能消耗子网中的大量 IP 地址。在具有数十个网络接口的实例上，这可能会迅速耗尽子网的可用 IP 空间。

要减少启用 EFA 的节点上的 IP 地址消耗，请将除主接口外的所有接口配置为使用 `efa-only`。仅限 EFA 的接口专用于 RDMA 流量且不分配 IP 地址，因此它们不会消耗子网中的地址。有关示例配置，请参阅 [Karpenter](#eks-efa-auto-karpenter) 和 [EKS 托管节点组与自行管理的节点](#eks-efa-mng-self-managed)。有关每种实例类型的推荐接口布局，《Amazon EC2 用户指南**》中的[最大限度地提高启用 EFA 的实例类型的网络带宽](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-acc-inst-types.html)。

除了使用 `efa-only` 接口外，您还可以配置 Amazon VPC CNI 以限制热（预分配）IP 地址和 ENI 的数量。默认情况下，VPC CNI 会预分配 ENI 和 IP 地址的暖池，以便更快地启动容器组（pod），但在大型实例中，这可能会预留数百个未使用的 IP 地址。在 `aws-node` DaemonSet 上设置 `WARM_IP_TARGET` 和 `WARM_ENI_TARGET` 环境变量，以控制 CNI 维护的备用 IP 地址和 ENI 的数量。有关这些设置的更多信息，请参阅 [Amazon VPC CNI 最佳实践](https://docs.aws.amazon.com/eks/latest/best-practices/vpc-cni.html#_overview)。

**注意**  
`WARM_ENI_TARGET` 和 `WARM_IP_TARGET` 设置是集群范围设置，适用于由 VPC CNI 管理的所有节点。目前无法按节点组或实例类型设置不同的值。如果您需要更精细地控制这些设置，请在 [containers-roadmap issue \#1834](https://github.com/aws/containers-roadmap/issues/1834) 上提供反馈。

## 安装 EFA DRA 驱动程序（DRANET）
<a name="efa-dra-driver"></a>

EFA DRA 驱动程序内置在上游 [DRANET](https://github.com/kubernetes-sigs/dranet) 项目中，该项目为 Kubernetes DRA 提供云感知的网络设备管理。在本文档中，*EFA DRA 驱动程序*和 *DRANET* 可互换使用，指的是同一个工具。

FA DRA 驱动程序将 EFA 设备作为 `ResourceSlice` 对象进行发布，驱动程序名称为 `dra.net`，`DeviceClass` 名称为 `efa.networking.k8s.aws`。EFA DRA 驱动程序作为 DaemonSet 在每个节点上运行，并自动发现 EFA 设备。

### 先决条件
<a name="_prerequisites"></a>
+ 运行 Kubernetes 1.34 或更高版本的 Amazon EKS 集群，使用 EKS 托管节点组或自行管理的节点组。
+ 具有启用 EFA 的 Amazon EC2 实例类型的节点。有关支持的实例类型的列表，请参阅*《Amazon EC2 用户指南》*中的[支持的实例类型](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html#efa-instance-types)。
+ 为 EFA 安装主机级组件的节点。有关更多信息，请参阅[安装 EFA 软件](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-enable)。EKS 优化版 AL2023 NVIDIA 和 Neuron AMI 以及 Bottlerocket AMI 都包含 EFA 主机级组件。
+ 在命令行环境中安装 Helm，有关更多信息，请参阅[安装 Helm 说明](helm.md)。
+  `kubectl` 配置为与您的集群通信，更多信息，请参阅 [安装或更新 `kubectl`](install-kubectl.md#kubectl-install-update)。

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

**重要**  
请勿在运行 EFA 设备插件的节点上安装 EFA DRA 驱动程序。这两种机制不能在同一节点上共存。有关更新，请参阅上游 Kubernetes [KEP–5004](https://github.com/kubernetes/enhancements/issues/5004)。

1. 添加 Helm 图表存储库。

   ```
   helm repo add eks https://aws.github.io/eks-charts
   ```

1. 更新本地 Helm 存储库。

   ```
   helm repo update
   ```

1. 使用 Helm 在集群上安装 EFA DRA 驱动程序。EFA DRA 驱动程序通过实例元数据服务（IMDS）自动检测其是否在 EC2 实例上运行，并启用 EFA 设备发现。默认情况下，EFA DRA 驱动程序以 DaemonSet 形式部署在 `kube-system` 命名空间中。有关可配置的参数，请参阅 [EKS Helm 图表 GitHub 存储库](https://github.com/aws/eks-charts/tree/master/stable/aws-dranet)中的 values.yaml。

   ```
   helm install aws-dranet eks/aws-dranet --namespace kube-system
   ```

1. 验证 DRANET DaemonSet 是否正在运行。

   ```
   kubectl get daemonset -n kube-system aws-dranet
   ```

   ```
   NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
   aws-dranet    2         2         2       2            2           <none>          60s
   ```

1. 验证 `DeviceClass` 是否已创建：

   ```
   kubectl get deviceclass
   ```

   ```
   NAME                    AGE
   efa.networking.k8s.aws  60s
   ```

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

   ```
   kubectl get resourceslices --field-selector spec.driver=dra.net
   ```

   如果您在执行上述步骤时遇到错误，可以使用以下命令查看 DRANET 的日志。

   ```
   kubectl logs -n kube-system -l app=aws-dranet
   ```

1. 要使用 DRA 驱动程序请求 EFA 设备，请创建一个引用 EFA `DeviceClass` 的 `ResourceClaim` 或 `ResourceClaimTemplate`，并在容器组（pod）规约中引用它。以下示例请求单个 EFA 设备。

   ```
   apiVersion: resource.k8s.io/v1
   kind: ResourceClaimTemplate
   metadata:
     name: single-efa-claim
   spec:
     spec:
       devices:
         requests:
         - name: efa
           exactly:
             deviceClassName: efa.networking.k8s.aws
             count: 1
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     name: efa-workload
   spec:
     containers:
     - name: app
       ...
       resources:
         claims:
         - name: efa-device
     resourceClaims:
     - name: efa-device
       resourceClaimTemplateName: single-efa-claim
   ```

## 拓扑感知的 EFA 和 GPU/Neuron 设备分配
<a name="efa-dra-topology-aware"></a>

EFA DRA 驱动程序支持拓扑感知分配，可将 EFA 接口与同一 PCIe 根上的 GPU 或 Neuron 设备配对。使用 `matchAttribute` 约束来对齐 EFA 和 GPU 或 Neuron 设备分配。要使用此功能，您还必须使用 NVIDIA 或 Neuron DRA 驱动程序。有关更多信息，请参阅[在 Amazon EKS 上管理 NVIDIA GPU 设备](device-management-nvidia.md)和[在 Amazon EKS 上管理 Neuron 设备](device-management-neuron.md)。

以下示例请求 1 个 EFA 接口，与 1 个 NVIDIA GPU 对齐：

```
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: aligned-efa-nvidia
spec:
  spec:
    devices:
      requests:
      - name: 1-efa
        exactly:
          deviceClassName: efa.networking.k8s.aws
          count: 1
      - name: 1-gpu
        exactly:
          deviceClassName: gpu.nvidia.com
          count: 1
      constraints:
      - requests: ["1-gpu", "1-efa"]
        matchAttribute: "resource.kubernetes.io/pcieRoot"
```

以下示例请求 4 个 EFA 接口，与 4 部 Neuron 设备对齐：

```
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: aligned-efa-neuron
spec:
  spec:
    devices:
      requests:
      - name: 4-neurons
        exactly:
          deviceClassName: neuron.aws.com
          count: 4
      - name: 4-efas
        exactly:
          deviceClassName: efa.networking.k8s.aws
          count: 4
      constraints:
      - requests: ["4-neurons", "4-efas"]
        matchAttribute: "resource.aws.com/devicegroup4_id"
```

`devicegroup` 属性名称中的数字对应于连接拓扑组中的 Neuron 设备数量。例如，`resource.aws.com/devicegroup1_id` 标识单个 Neuron 设备，`resource.aws.com/devicegroup4_id` 标识一个包含 4 部已连接设备的组，而 `resource.aws.com/devicegroup8_id` 和 `resource.aws.com/devicegroup16_id` 分别标识包含 8 部和 16 部已连接设备的组。选择与请求中的设备 `count` 匹配的 `matchAttribute`，以便分配的 Neuron 设备和 EFA 接口属于同一连接拓扑组。有关这些属性的更多信息，请参阅 [Neuron DRA 驱动程序文档](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/containers/neuron-dra.html)。

您可以使用 `allocationMode` 来简化 EFA 设备分配给对齐的 GPU 或 Neuron 加速器的方式。`allocationMode` 字段支持两个值：`ExactCount`（默认值）请求由 `count` 指定的特定设备数量，以及 `All` 请求池中的所有匹配设备。例如，在 `p5.48xlarge` 实例中，有四台 EFA 设备与一个 GPU 共享同一 PCIe 根。要分配这些 EFA 设备组并与 GPU 对齐，即使您不知道确切的 EFA-GPU 设备映射和对齐的 EFA 设备数量，也可以将 `ResourceClaimTemplate` 中的 EFA 设备配置为 `allocationMode: All`。

```
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: aligned-all-efa-one-nvidia
spec:
  spec:
    devices:
      requests:
      - name: all-efas
        exactly:
          deviceClassName: efa.networking.k8s.aws
          allocationMode: All
      - name: one-gpu
        exactly:
          deviceClassName: gpu.nvidia.com
          allocationMode: ExactCount
          count: 1
      constraints:
      - requests: ["all-efas", "one-gpu"]
        matchAttribute: "resource.kubernetes.io/pcieRoot"
```

## 在多个容器组（pod）之间共享 EFA 设备
<a name="efa-dra-share"></a>

EFA DRA 驱动程序支持通过使用 `ResourceClaim` 在多个容器组（pod）之间共享 EFA 设备。与为每个容器组（pod）生成独立声明的 `ResourceClaimTemplate` 不同，`ResourceClaim` 是一个独立创建的对象，可从多个容器组（pod）中引用。所有引用同一 `ResourceClaim` 的容器组（pod）会共享对同一组已分配 EFA 设备的访问权限，并调度到这些设备可用的同一节点上。

要在容器组（pod）之间共享 EFA 设备，请创建一个请求 EFA 设备的 `ResourceClaim`，然后在每个容器组（pod）的 `resourceClaims` 字段中使用 `resourceClaimName` 按名称引用该 Claim。在创建引用它的容器组（pod）之前，`ResourceClaim` 必须存在于集群中。如果引用的 `ResourceClaim` 不存在，容器组（pod）将保持待处理状态，直到创建 Claim。

以下示例创建了一个请求 4 台 EFA 设备的 `ResourceClaim`，以及两个共享这些设备访问权限的容器组（pod）。

1. 创建 `ResourceClaim`。

   ```
   apiVersion: resource.k8s.io/v1
   kind: ResourceClaim
   metadata:
     name: shared-efa
   spec:
     devices:
       requests:
       - name: efa
         exactly:
           deviceClassName: efa.networking.k8s.aws
           count: 4
   ```

1. 在每个需要访问 EFA 设备的容器组（pod）中，按名称引用 `ResourceClaim`。每个容器组（pod）都使用 `resourceClaimName` 来引用现有 Claim，而不是 `resourceClaimTemplateName`。

   ```
   apiVersion: v1
   kind: Pod
   metadata:
     name: training-worker
   spec:
     containers:
     - name: worker
       image: my-training-image
       resources:
         claims:
         - name: efa-devices
     resourceClaims:
     - name: efa-devices
       resourceClaimName: shared-efa
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     name: training-monitor
   spec:
     containers:
     - name: monitor
       image: my-monitor-image
       resources:
         claims:
         - name: efa-devices
     resourceClaims:
     - name: efa-devices
       resourceClaimName: shared-efa
   ```

两个容器组（pod）都引用同一个 `shared-efa` `ResourceClaim`，并被调度到分配了这些 EFA 设备的节点上。`ResourceClaim` 生命周期独立于容器组（pod），即使所有引用它的容器组（pod）都被删除，它也会一直存在，直到您将其删除，

## 安装 EFA Kubernetes 设备插件
<a name="eks-efa-device-plugin"></a>

EFA Kubernetes 设备插件将 EFA 设备作为 `vpc.amazonaws.com/efa` 扩展资源进行发布。您需要在容器的资源请求和限制中请求 EFA 设备。有关使用训练工作负载设置 EFA 的完整说明，请参阅[使用 Elastic Fabric Adapter 在 Amazon EKS 上运行机器学习训练](node-efa.md)。

**重要**  
使用 EKS 优化版 AL2023 加速 AMI 时，会自动发生 NVIDIA GPU 或 Neuron 设备与 EFA 接口的拓扑对齐分配。使用 Bottlerocket EKS 优化版 AMI 或自定义 AMI 时，不会发生这种自动对齐。如果您需要在使用 Bottlerocket 或自定义 AMI 时进行拓扑对齐的加速器和 EFA 设备分配，请使用 EFA DRA 驱动程序和相应的 Neuron DRA 驱动程序。不支持将 NVIDIA DRA 驱动程序与 Bottlerocket 结合使用。有关更多信息，请参阅 [拓扑感知的 EFA 和 GPU/Neuron 设备分配](#efa-dra-topology-aware)。

**重要**  
从 NVIDIA `k8s-device-plugin` v0.19.0 开始，`--mofed-enabled` 标志默认为 `true`，这会导致 NVIDIA 设备插件将所有 `/dev/infiniband/uverbs*` 设备挂载到请求 GPU 的容器中。这与 EFA 设备插件冲突，后者应该是管理 `/dev/infiniband` 处 EFA 设备分配的组件。如果您将 EKS 托管节点组或自行管理的节点与 NVIDIA 设备插件结合使用，则须明确禁用 MOFED。有关说明，请参阅[安装 NVIDIA Kubernetes 设备插件](device-management-nvidia.md#nvidia-device-plugin)。  
默认情况下，EKS 自动模式不会启用 MOFED，因此不受此问题影响。

### 先决条件
<a name="_prerequisites_2"></a>
+ 一个 Amazon EKS 集群。
+ 具有启用 EFA 的 Amazon EC2 实例类型的节点。有关支持的实例类型的列表，请参阅*《Amazon EC2 用户指南》*中的[支持的实例类型](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html#efa-instance-types)。
+ 为 EFA 安装主机级组件的节点。有关更多信息，请参阅[安装 EFA 软件](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-enable)。EKS 优化版 AL2023 NVIDIA 和 Neuron AMI 以及 Bottlerocket AMI 都包含 EFA 主机级组件。
+ 在命令行环境中安装 Helm，有关更多信息，请参阅[安装 Helm 说明](helm.md)。
+  `kubectl` 配置为与您的集群通信，更多信息，请参阅 [安装或更新 `kubectl`](install-kubectl.md#kubectl-install-update)。

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

1. 添加 Helm 图表存储库。

   ```
   helm repo add eks https://aws.github.io/eks-charts
   ```

1. 更新本地 Helm 存储库。

   ```
   helm repo update
   ```

1. 安装 EFA 设备插件。

   ```
   helm install efa eks/aws-efa-k8s-device-plugin -n kube-system
   ```

1. 验证 EFA 设备插件 DaemonSet 正在运行。

   ```
   kubectl get daemonset -n kube-system efa-aws-efa-k8s-device-plugin
   ```

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

1. 验证节点是否具有可分配的 EFA 资源。

   ```
   kubectl get nodes "-o=custom-columns=NAME:.metadata.name,EFA:.status.allocatable.vpc\.amazonaws\.com/efa"
   ```

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

1. 要使用设备插件请求 EFA 设备，请在容器的资源请求和限制中指定 `vpc.amazonaws.com/efa` 资源。

   ```
   apiVersion: v1
   kind: Pod
   metadata:
     name: efa-workload
   spec:
     containers:
     - name: app
       ...
       resources:
         limits:
           vpc.amazonaws.com/efa: 4
           hugepages-2Mi: ...
         requests:
           vpc.amazonaws.com/efa: 4
           hugepages-2Mi: ...
   ```