帮助改进此页面
要帮助改进本用户指南,请选择位于每个页面右侧窗格中的在 GitHub 上编辑此页面链接。
管理 Amazon EKS 上的 EFA 设备
Elastic Fabric Adapter(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 设备插件与 Karpenter 和 EKS 自动模式结合使用。EFA 设备插件仍然支持与 EKS 托管节点组和自行管理的节点结合使用。
EFA DRA 驱动程序与 EFA 设备插件
| 功能 | EFA DRA 驱动程序 | EFA 设备插件 |
|---|---|---|
|
最低 Kubernetes 版本 |
1.34 |
所有 EKS 支持的 Kubernetes 版本 |
|
EKS 计算 |
托管节点组、自行管理的节点 |
EKS 自动模式、Karpenter、托管节点组、自行管理的节点 |
|
EKS 优化型 AMI |
AL2023(NVIDIA、Neuron)、Bottlerocket |
AL2023(NVIDIA、Neuron)、Bottlerocket |
|
设备发布方式 |
通过 |
以整数计数形式发布 |
|
GPU-EFA 亲和性 |
DRA 原生拓扑感知 |
自动拓扑感知(仅限 EKS 优化版 AL2023 AMI) |
|
Neuron-EFA 亲和性 |
DRA 原生拓扑感知 |
自动拓扑感知(仅限 EKS 优化版 AL2023 AMI) |
|
设备共享 |
多个容器组(pod)可以通过共享 |
不支持。每个 EFA 设备专用于一个容器组(pod)。 |
创建带有 EFA 接口的 EKS 节点
当您创建带有 EFA 接口的 EKS 节点时,EFA 接口会在实例预置期间附加到实例。您可以自定义每台设备的 EFA 配置,并将置放群组与 Karpenter、EKS 托管节点组或 EKS 自行管理的节点组结合使用。使用 Karpenter 时,您可以通过 NodeClass 传递每个网络接口的配置。使用 EKS 托管节点组或自行管理的节点时,您可以通过启动模板传递每个网络接口的配置。即将推出 EKS 自动模式对每台设备 EFA 配置和置放群组的支持。
当使用 eksctl 并以 efaEnabled 设置配置 EKS 节点时,所有接口都要配置接口类型 EFA,系统会创建一个特定于 EFA 的安全组,并在集群上安装 EFA 设备插件。如果您在使用 eksctl 时需要自定义每设备的 EFA 配置,建议使用 eksctl 对启动模板的支持。
以下示例演示了如何配置具有 EFA 接口的 NodeClass 和启动模板。这对于自定义用于 EFA 和基于 IP 的标准流量的接口非常有用。有关每种实例类型支持的 EFA 接口数量以及如何为最大网络带宽配置它们的信息,请参阅《Amazon EC2 用户指南》中的最大限度地提高启用 EFA 的实例类型的网络带宽。
Karpenter
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 的接口。
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 托管节点组与自行管理的节点
使用 EKS 托管节点组或自行管理的节点时,您可以通过启动模板传递每个网络接口的配置。
以下示例演示了为 P6-B200 实例配置的启动模板,具有 1 个 ENA 接口和 8 个仅限 EFA 的接口。主网络接口(网卡 0,设备索引 0)使用 interface 标准类型处理 IP 流量,而附加接口则使用 efa-only 处理专用 RDMA 流量。根据实例类型调整 efa-only 接口数量。有关每种实例类型支持的 EFA 接口数量,请参阅《Amazon EC2 用户指南》中的最大限度地提高启用 EFA 的实例类型的网络带宽。
将
security-group-id
替换为您自己的值。安全组必须允许进出其本身的所有入站和出站流量,以启用 EFA 操作系统绕过功能。有关更多信息,请参阅《Amazon EC2 用户指南》中的步骤 1:准备启用 EFA 的安全组。
重要
使用 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 配合使用
EKS 优化版 AL2023 加速型 AMI(NVIDIA 和 Neuron)和所有 Bottlerocket AMI 都包含使用 EFA 所需的主机级组件(即由 aws-efa-installer 安装的组件)。EKS AL2023 和 Bottlerocket AMI 不包含 EFA DRA 驱动程序或 EFA 设备插件,在部署工作负载之前必须将其单独安装到集群上。
节省 IP 地址分配
启用 EFA 的实例(例如 p5.48xlarge 和 p6-b200.48xlarge)支持许多网络接口。默认情况下,Amazon VPC CNI 会在所有启用 IP 的附加 ENI 上分配 IP 地址,即使这些地址未被容器组(pod)积极使用,也可能消耗子网中的大量 IP 地址。在具有数十个网络接口的实例上,这可能会迅速耗尽子网的可用 IP 空间。
要减少启用 EFA 的节点上的 IP 地址消耗,请将除主接口外的所有接口配置为使用 efa-only。仅限 EFA 的接口专用于 RDMA 流量且不分配 IP 地址,因此它们不会消耗子网中的地址。有关示例配置,请参阅 Karpenter 和 EKS 托管节点组与自行管理的节点。有关每种实例类型的推荐接口布局,《Amazon EC2 用户指南》中的最大限度地提高启用 EFA 的实例类型的网络带宽。
除了使用 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 最佳实践。
注意
WARM_ENI_TARGET 和 WARM_IP_TARGET 设置是集群范围设置,适用于由 VPC CNI 管理的所有节点。目前无法按节点组或实例类型设置不同的值。如果您需要更精细地控制这些设置,请在 containers-roadmap issue #1834
安装 EFA DRA 驱动程序(DRANET)
EFA DRA 驱动程序内置在上游 DRANET
FA DRA 驱动程序将 EFA 设备作为 ResourceSlice 对象进行发布,驱动程序名称为 dra.net,DeviceClass 名称为 efa.networking.k8s.aws。EFA DRA 驱动程序作为 DaemonSet 在每个节点上运行,并自动发现 EFA 设备。
先决条件
-
运行 Kubernetes 1.34 或更高版本的 Amazon EKS 集群,使用 EKS 托管节点组或自行管理的节点组。
-
具有启用 EFA 的 Amazon EC2 实例类型的节点。有关支持的实例类型的列表,请参阅《Amazon EC2 用户指南》中的支持的实例类型。
-
为 EFA 安装主机级组件的节点。有关更多信息,请参阅安装 EFA 软件。EKS 优化版 AL2023 NVIDIA 和 Neuron AMI 以及 Bottlerocket AMI 都包含 EFA 主机级组件。
-
在命令行环境中安装 Helm,有关更多信息,请参阅安装 Helm 说明。
-
kubectl配置为与您的集群通信,更多信息,请参阅 安装或更新 kubectl。
过程
重要
请勿在运行 EFA 设备插件的节点上安装 EFA DRA 驱动程序。这两种机制不能在同一节点上共存。有关更新,请参阅上游 Kubernetes KEP–5004
-
添加 Helm 图表存储库。
helm repo add eks https://aws.github.io/eks-charts -
更新本地 Helm 存储库。
helm repo update -
使用 Helm 在集群上安装 EFA DRA 驱动程序。EFA DRA 驱动程序通过实例元数据服务(IMDS)自动检测其是否在 EC2 实例上运行,并启用 EFA 设备发现。默认情况下,EFA DRA 驱动程序以 DaemonSet 形式部署在
kube-system命名空间中。有关可配置的参数,请参阅 EKS Helm 图表 GitHub 存储库中的 values.yaml。 helm install aws-dranet eks/aws-dranet --namespace kube-system -
验证 DRANET DaemonSet 是否正在运行。
kubectl get daemonset -n kube-system aws-dranetNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE aws-dranet 2 2 2 2 2 <none> 60s -
验证
DeviceClass是否已创建:kubectl get deviceclassNAME AGE efa.networking.k8s.aws 60s -
验证是否为您的节点发布了
ResourceSlice对象。kubectl get resourceslices --field-selector spec.driver=dra.net如果您在执行上述步骤时遇到错误,可以使用以下命令查看 DRANET 的日志。
kubectl logs -n kube-system -l app=aws-dranet -
要使用 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 设备分配
EFA DRA 驱动程序支持拓扑感知分配,可将 EFA 接口与同一 PCIe 根上的 GPU 或 Neuron 设备配对。使用 matchAttribute 约束来对齐 EFA 和 GPU 或 Neuron 设备分配。要使用此功能,您还必须使用 NVIDIA 或 Neuron DRA 驱动程序。有关更多信息,请参阅在 Amazon EKS 上管理 NVIDIA GPU 设备和在 Amazon EKS 上管理 Neuron 设备。
以下示例请求 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 驱动程序文档
您可以使用 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 设备
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)。
-
创建
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 -
在每个需要访问 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 设备插件
EFA Kubernetes 设备插件将 EFA 设备作为 vpc.amazonaws.com/efa 扩展资源进行发布。您需要在容器的资源请求和限制中请求 EFA 设备。有关使用训练工作负载设置 EFA 的完整说明,请参阅使用 Elastic Fabric Adapter 在 Amazon EKS 上运行机器学习训练。
重要
使用 EKS 优化版 AL2023 加速 AMI 时,会自动发生 NVIDIA GPU 或 Neuron 设备与 EFA 接口的拓扑对齐分配。使用 Bottlerocket EKS 优化版 AMI 或自定义 AMI 时,不会发生这种自动对齐。如果您需要在使用 Bottlerocket 或自定义 AMI 时进行拓扑对齐的加速器和 EFA 设备分配,请使用 EFA DRA 驱动程序和相应的 Neuron DRA 驱动程序。不支持将 NVIDIA DRA 驱动程序与 Bottlerocket 结合使用。有关更多信息,请参阅 拓扑感知的 EFA 和 GPU/Neuron 设备分配。
重要
从 NVIDIA k8s-device-plugin v0.19.0 开始,--mofed-enabled 标志默认为 true,这会导致 NVIDIA 设备插件将所有 /dev/infiniband/uverbs* 设备挂载到请求 GPU 的容器中。这与 EFA 设备插件冲突,后者应该是管理 /dev/infiniband 处 EFA 设备分配的组件。如果您将 EKS 托管节点组或自行管理的节点与 NVIDIA 设备插件结合使用,则须明确禁用 MOFED。有关说明,请参阅安装 NVIDIA Kubernetes 设备插件。
默认情况下,EKS 自动模式不会启用 MOFED,因此不受此问题影响。
先决条件
-
一个 Amazon EKS 集群。
-
具有启用 EFA 的 Amazon EC2 实例类型的节点。有关支持的实例类型的列表,请参阅《Amazon EC2 用户指南》中的支持的实例类型。
-
为 EFA 安装主机级组件的节点。有关更多信息,请参阅安装 EFA 软件。EKS 优化版 AL2023 NVIDIA 和 Neuron AMI 以及 Bottlerocket AMI 都包含 EFA 主机级组件。
-
在命令行环境中安装 Helm,有关更多信息,请参阅安装 Helm 说明。
-
kubectl配置为与您的集群通信,更多信息,请参阅 安装或更新 kubectl。
过程
-
添加 Helm 图表存储库。
helm repo add eks https://aws.github.io/eks-charts -
更新本地 Helm 存储库。
helm repo update -
安装 EFA 设备插件。
helm install efa eks/aws-efa-k8s-device-plugin -n kube-system -
验证 EFA 设备插件 DaemonSet 正在运行。
kubectl get daemonset -n kube-system efa-aws-efa-k8s-device-pluginNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE efa-aws-efa-k8s-device-plugin 2 2 2 2 2 <none> 60s -
验证节点是否具有可分配的 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 -
要使用设备插件请求 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: ...