您可以使用动态资源分配 (DRA) 将 GPU 分配给 Google Kubernetes Engine (GKE) 工作负载。本文档介绍了 DRA 的基础知识、如何在 GKE 中使用 DRA,以及使用 DRA 的优势。
本文档适用于以下角色:
您应该已经熟悉以下内容:
DRA 简介
DRA 是一项内置的 Kubernetes 功能,可让您在集群中的 Pod 和容器之间灵活地请求、分配和共享硬件。DRA 允许设备供应商和平台管理员声明可请求和分配的设备类,从而改进了分配附加硬件(例如加速器)的体验。应用运维人员可以在这些类中请求特定的设备配置,然后在工作负载中请求这些配置。Kubernetes 和 GKE 会根据工作负载请求管理 Pod 调度、节点分配和设备分配。
例如,平台管理员可以定义仅包含 NVIDIA A100 GPU 的设备类。然后,应用运维人员可以根据工作负载要求过滤该设备类中的设备,例如过滤 GPU 内存至少为 80 GB 的设备。当应用运维人员部署请求过滤配置的工作负载时,GKE 会将 Pod 放置在符合所选条件的节点上。在此示例中,GKE 会查找具有可用 A100 (80 GB) GPU 的节点。应用运维人员无需在工作负载清单中选择特定节点或设备配置。
DRA 的优势
如果没有 DRA,在 Kubernetes 中分配硬件设备就要依赖于设备插件。如需使用设备插件将硬件资源关联到 Pod,您可以使用节点标签将 Pod 放置在特定节点上。此外,如需将整个节点的资源专用于单个 Pod,您可以请求连接到节点的设备的确切数量。
借助 DRA,将设备分配给 Pod 类似于为存储空间分配卷。您可以定义设备类,请求这些类中的设备,然后将所请求的设备分配给工作负载。DRA 提供了一个可大幅扩展的界面,可根据工作负载和业务需求过滤设备。使用表达式和模板来声明硬件和调度 Pod 的 DRA 方法具有以下优势:
- 声明式设备分配:平台管理员可以为特定类型的工作负载或团队定义设备配置。
- 降低跨团队复杂性:当平台管理员预配具有专用硬件配置的节点时,应用运维人员无需知道哪些节点具有特定配置。平台管理员无需标记节点,也无需向运营商传达有关特定节点和设备的信息。
- 降低了开发者的复杂度:Kubernetes 会根据引用的设备配置来调度 Pod。应用运维人员无需在其工作负载中选择特定节点,也无需确保每个 Pod 请求的设备数量与附加到这些节点的设备数量完全一致。
- 集中式基础架构管理:平台管理员可以集中定义满足特定业务要求的硬件配置。例如,平台管理员可以声明一个具有 H100 GPU 的高性能配置,以及一个具有 Tesla T4 GPU 的小型推理配置。
- 灵活的硬件选择:您可以使用 CEL 表达式过滤具有特定属性的设备。使用表达式可灵活地过滤出最适合特定工作负载的设备。
何时使用 DRA
在 GKE 中使用 DRA 的主要原因是,您可以灵活地为工作负载请求设备。您只需编写一次清单,即可将工作负载部署到具有不同设备类型的不同集群,而无需更改清单。这种灵活性非常适合以下使用场景:
- 提高 GPU 可获取性:对于需要访问 GPU 硬件的工作负载,您可以使用 DRA 请求集群中的任何可用 GPU,而无需指定 GPU 型号。如果这些工作负载对 GPU 内存 (VRAM) 有具体要求,您可以请求集群中内存量达到最低要求的任何 GPU。这种灵活的请求会扩大工作负载可运行的 GPU 节点集,从而降低因资源不可用而导致工作负载无法调度的风险。
在伸缩期间优化节点可用性:工作负载所需的设备数量可能会因设备类型及其功能等因素而异。您可以根据设备可用性,使用 GKE ComputeClasses 将加速 Pod 放置在特定节点池上。然后,您可以配置 Pod,使其能够声明 GKE 将 Pod 放置在任何节点中的设备。
将 DRA 与 ComputeClass 搭配使用,可最大限度地降低无计划工作负载的风险,同时帮助您在经过优化的硬件上运行工作负载。
术语
开源 Kubernetes 和 GKE 等托管式 Kubernetes 提供商使用以下核心 DRA API 种类:
- ResourceSlice
- ResourceSlice 列出了集群中节点可访问的一个或多个硬件设备。例如,在可以访问单个 GPU 的节点中,ResourceSlice 会列出 GPU 和节点的名称。每个节点上的 DRA 设备驱动程序都会创建 ResourceSlice。Kubernetes 调度器使用 ResourceSlice 来决定分配哪些设备以满足工作负载请求。
- DeviceClass
-
DeviceClass 定义了可供工作负载请求的设备类别,例如 GPU。某些设备驱动程序提供内置的 DeviceClass,例如 NVIDIA GPU 的
gpu.nvidia.comDeviceClass。平台管理员还可以创建自定义 DeviceClass,用于定义特定的设备配置。 - ResourceClaim
-
借助 ResourceClaim,Pod 或用户可以通过在 DeviceClass 中过滤特定参数来请求硬件资源。当工作负载引用 ResourceClaim 时,Kubernetes 会将符合指定参数的设备分配给该 ResourceClaim。
例如,假设您创建了一个针对一个 A100 (40 GB) GPU 的 ResourceClaim,然后部署了一个选择该 ResourceClaim 的工作负载。Kubernetes 会为 ResourceClaim 分配一个可用的 A100 (40 GB) GPU,并将您的 Pod 调度到可以访问该 GPU 的节点上。
- ResourceClaimTemplate
-
ResourceClaimTemplate 定义了一个模板,Pod 可使用该模板自动创建新的每个 Pod ResourceClaim。当您有多个工作负载需要访问类似的设备配置时,ResourceClaimTemplate 非常有用,尤其是在使用 Deployment 或 StatefulSet 等工作负载控制器时。
应用运维人员部署 ResourceClaimTemplate,然后在工作负载中引用这些模板。Kubernetes 会根据指定的模板为每个 Pod 创建 ResourceClaim,分配设备并调度 Pod。当 Pod 终止时,Kubernetes 会清理相应的 ResourceClaim。
如需详细了解 DRA API 种类,请参阅 DRA 术语。
DRA 的运作方式
在集群和工作负载中使用 DRA 的过程与使用 StorageClass、PersistentVolumeClaim 和 PersistentVolume 来为 Pod 动态预配卷的过程类似。
下图展示了集群管理员和应用运维人员使用 DRA 分配设备的步骤:
在此图中,集群管理员和应用运维人员执行以下操作:
- 集群管理员在节点中安装支持 DRA 的设备驱动程序。
- 集群管理员创建 DeviceClass,用于过滤符合特定要求的硬件,例如所有内存超过 40 GB 的 GPU。某些设备可能还包含内置的 DeviceClass。
- 应用运维人员创建请求设备配置的 ResourceClaimTemplate 或 ResourceClaim。每种声明的主要使用场景如下:
- 借助 ResourceClaim,多个 Pod 可以共享对同一设备的访问权限。
- 借助 ResourceClaimTemplate,多个 Pod 可以通过自动生成每个 Pod 的 ResourceClaim 来访问单独的类似设备。
- 应用运维人员将 ResourceClaimTemplate 或 ResourceClaim 添加到其工作负载清单中。
- 应用运维人员部署工作负载。
当您部署引用 ResourceClaimTemplate 或 ResourceClaim 的工作负载时,Kubernetes 会执行以下调度步骤:
- 如果工作负载引用了 ResourceClaimTemplate,Kubernetes 会为工作负载的每个实例(例如,Deployment 中的每个副本)创建一个新的
ResourceClaim对象。 - Kubernetes 调度器使用集群中的 ResourceSlice 将可用的符合条件的设备分配给每个 Pod 的 ResourceClaim。
- 调度器会将每个 Pod 放置在可以访问已分配给 Pod 的 ResourceClaim 的设备的节点上。
- 目标节点上的
kubelet调用节点上的 DRA 驱动程序,将分配的硬件挂接到 Pod 以满足其资源请求。
何时使用 ResourceClaim 和 ResourceClaimTemplate
您可以使用 ResourceClaim 或 ResourceClaimTemplate 向 Kubernetes 指示您需要满足特定要求的设备。当 Pod 中引用 ResourceClaim 时,Kubernetes 会在 Kubernetes API 服务器中为相应的 ResourceClaim API 资源分配设备。无论是由您创建 ResourceClaim,还是由 Kubernetes 从 ResourceClaimTemplate 创建 ResourceClaim,都会发生此分配。
如果您创建了一个 ResourceClaim,然后在多个 Pod 中引用它,那么所有这些 Pod 都可以访问 Kubernetes 为该 ResourceClaim 分配的设备。例如,如果您在具有多个副本的 Deployment 清单中引用了特定的 ResourceClaim,则可能会发生这种共享访问。不过,如果分配的设备未配置为可供多个进程共享,则跨 Pod 的这种共享设备访问可能会导致意外行为。
如需为 Pod 分配单独的设备,您可以使用 ResourceClaimTemplate,该模板可供 Kubernetes 用于自动创建各个 ResourceClaim。例如,如果您在具有多个副本的 Deployment 中引用 ResourceClaimTemplate,Kubernetes 会为每个复制的 Pod 创建单独的 ResourceClaim。因此,每个 Pod 都会获得自己的分配设备,而不是与其他 Pod 共享对设备的访问权限。这些自动生成的 ResourceClaim 会绑定到相应 Pod 的生命周期,并在 Pod 终止时被删除。如果您有需要访问类似设备配置的独立 Pod,请使用 ResourceClaimTemplate 为每个 Pod 单独分配设备。
下表说明了手动创建 ResourceClaim 与让 Kubernetes 从 ResourceClaimTemplate 创建 ResourceClaim 之间的一些区别:
| 手动创建的 ResourceClaim | 自动创建的 ResourceClaim |
|---|---|
| 由您管理 | 由 Kubernetes 管理 |
| 允许从多个 Pod 访问同一设备 | 提供从单个 Pod 访问设备的权限 |
| 独立于 Pod 存在于集群中 | 与相应 Pod 的生命周期绑定 |
| 非常适合需要共享特定设备的多个工作负载 | 非常适合需要独立设备访问权限的多个工作负载 |
DRA 与手动设备分配的比较
借助 DRA,分配附加设备与动态预配 PersistentVolume 的体验类似。Kubernetes 还支持使用设备插件来分配设备。此方法涉及以下步骤:
- 集群管理员创建已连接设备(例如 GPU)的节点。
- 集群管理员会向工作负载运营商传达有关特定节点及其连接的设备的信息。
- 工作负载运算符在工作负载清单中请求设备,如下所示:
- 使用
nodeSelector字段选择具有所需设备配置(例如 GPU 型号)的节点。 - 使用 Pod 规范中的
resources字段,指定容器要使用的确切设备数量。
- 使用
这种手动分配方法要求应用运维人员和集群管理员就哪些特定节点或节点池具有特定设备配置进行沟通。它们必须协调工作负载请求,以匹配节点上的设备,否则部署会失败。相比之下,DRA 可让您使用表达式根据属性灵活地过滤设备,并且不需要工作负载运算符了解集群中节点的精确配置。
下表比较了 DRA 与设备插件:
| DRA | 手动分配 |
|---|---|
| 使用 CEL 表达式灵活选择设备 | 使用选择器和资源请求选择特定节点 |
| Kubernetes 做出的调度决策 | 由运维人员使用节点选择器做出的调度决策 |
| 设备过滤与工作负载创建是分开的 | 必须在工作负载清单中完成设备过滤 |
| 由平台管理员管理的集中式设备过滤和基于需求的课程 | 由应用运维人员独立进行设备过滤 |
| 应用运维人员无需了解节点容量、节点标签信息或每个节点的连接设备型号 | 应用运维人员必须知道哪些节点连接了特定型号和和数量的设备。 |
DRA 和基础架构自动扩缩
如需自动调整 Standard 模式节点池中的节点数量,您可以使用集群自动扩缩器。您可以在任何手动创建的节点池(包括具有 DRA 驱动程序的节点池)中启用集群自动扩缩器。
对于使用 DRA 的节点池,设备利用率会影响集群自动扩缩器在节点池中添加和移除节点的方式。为了计算节点池中的设备利用率,集群自动扩缩器会考虑以下因素:
- 资源池中的所有设备都必须位于特定节点本地。如果 ResourceSlice 具有连接到多个节点的设备池,则集群自动扩缩器会忽略这些设备。
- 节点池中的所有设备都同等重要且完全相同。
- DRA 设备的优先级高于 CPU 或内存。在 DRA 节点池中,集群自动扩缩器会忽略 CPU 和内存使用量。
这些因素可能意味着,您会发现 DRA 节点池中的缩容行为与其他节点池中的缩容行为不同。
支持 DRA 的 GKE 设备
下表介绍了您可以在 GKE 中使用 DRA 为工作负载分配的设备:
| 支持 DRA 的设备 | |
|---|---|
| GPU | 您所在位置提供的任何 GPU 类型。如需了解详情,请参阅 GPU 位置。 |
| 网络接口 | 通过安装受管理的 DRANET 驱动程序,支持多种类型的网络接口,例如支持 RDMA 的接口。如需了解详情,请参阅使用 GKE 托管的 DRANET 来分配网络资源。 |
限制
使用 DRA 时,存在以下限制:
操作模式:DRA 仅在标准模式集群中可用。
加速器类型:在预览版期间,GKE 中的 DRA 仅支持 GPU。
GPU:
- 您无法使用分时 GPU、多实例 GPU 或多进程服务 (MPS)。
- 对于使用 DRA GPU 驱动程序的节点,您无法使用受管理的 NVIDIA 数据中心 GPU 管理器 (DCGM) 指标软件包将 DCGM 指标发送到 Cloud Monitoring。
- DRA 的 GPU 驱动程序归 NVIDIA 所有,而非 GKE 所有。如需了解详情,请参阅 NVIDIA 文档。
网络接口(预览版):请参阅“使用 GKE 托管的 DRANET 来分配网络资源”中的限制。
自动扩缩:
- 对于您安装的第三方 DRA 驱动程序,集群自动扩缩器要求您的节点池至少有一个节点。为防止使用第三方驱动程序的节点池伸缩到零个节点,请将节点数下限设置为至少
1。 - 集群自动扩缩器可能无法与第三方 DRA 驱动程序正常搭配使用。如果您确实要使用第三方驱动程序,请验证这些驱动程序是否仅针对特定节点本地的设备发布信息。
- 对于使用静态 ResourceClaim 在 Pod 之间共享设备访问权限的自动扩缩节点池中的 DaemonSet,自动扩缩最多支持 128 个 DaemonSet Pod。如需避免此限制,请执行以下操作之一:
- 通过设置节点数上限,防止节点池伸缩到超过 128 个节点。
- 使用 ResourceClaim 中的
adminAccess字段(Beta 版),该字段可让 DaemonSet 访问正在使用的设备。
- 如果您的 Pod 引用了 ResourceClaims,并且其 PriorityClass 将抢占政策设置为
PreemptLowerPriority,则自动扩缩延迟时间可能会增加。PreemptLowerPriority是 PriorityClass 的默认抢占政策,因此请确保您的 PriorityClass 将preemptionPolicy字段明确设置为Never。如需了解详情,请参阅非抢占型 PriorityClass。
- 对于您安装的第三方 DRA 驱动程序,集群自动扩缩器要求您的节点池至少有一个节点。为防止使用第三方驱动程序的节点池伸缩到零个节点,请将节点数下限设置为至少
建议掌握的技能:了解和使用 DRA
本部分为希望使用 DRA 将设备分配给工作负载的平台管理员或应用运维人员提供建议。DRA 大幅改变了您在 GKE 和 Kubernetes 中请求连接设备的方法。如需受益于更高级的应用场景(例如跨设备回退或精细的设备过滤和选择),请考虑以下指导:
了解 CEL:借助 DRA,您可以使用 CEL 表达式在资源分配请求和 DeviceClass 中执行精细的设备过滤。以下资源可能有助于您学习 CEL:
了解 GKE 中的 ComputeClass:您可以将 ComputeClass 与 DRA 搭配使用,以满足业务需求,例如预配 Spot 虚拟机来运行需要经济高效的 GPU 的推理工作负载。以下资源可帮助您了解 ComputeClass: