告别 Device Plugin:深度解析 Kubernetes 下一代异构资源管理利器--DRA
告别 Device Plugin: Kubernetes 下一代异构资源管理利器 —— DRA
在 AI 和 GPU 计算盛行的今天,如何高效地在 Kubernetes 中调度显卡、FPGA 等硬件资源,一直是开发者关注的焦点。过去,我们依赖 Device Plugin 框架,但随着业务复杂化,其局限性(如无法动态共享、缺乏复杂的调度参数)日益凸显。
为了解决这些痛点,Kubernetes 推出了 Dynamic Resource Allocation (DRA)。该特性在 v1.34 版本中已正式进入 GA(General Availability) 阶段,标志着 K8s 进入了异构资源管理的 2.0 时代。
一、 为什么需要 DRA?(痛点分析)
在 DRA 出现之前,Device Plugin 是管理硬件的主力,但它有三个致命伤:
- 静态分配:资源请求只能是整数(如
nvidia.com/gpu: 1),难以实现 GPU 分片或复杂的组合请求。 - 网络与存储隔离:硬件驱动无法深度参与调度决策,导致调度器可能把 Pod 调度到一个虽然有 GPU 但网络带宽不足的节点上。
- API 表达力弱:用户无法指定“我需要一个显存大于 24GB 且支持 NVLink 的 GPU”这类复杂逻辑。
DRA 的核心理念是:像管理存储(PVC)一样管理硬件资源。
二、 DRA 的核心架构:四大支柱
DRA 引入了几个关键的 API 对象,构建了一套声明式的资源分配逻辑:
-
DeviceClass(设备类):
类似于存储的 StorageClass。它定义了某种硬件的统称(如 “high-performance-gpu”),并包含了驱动名称和通用选择逻辑。
-
ResourceClaim(资源申请):
类似于 PersistentVolumeClaim (PVC)。Pod 不直接请求硬件数量,而是引用一个 ResourceClaim。它描述了具体的资源需求(如:型号、显存大小、是否需要共享)。
-
ResourceClaimTemplate(申请模板):
用于 StatefulSet 或 Deployment。每当创建一个 Pod,控制器就会根据模板自动生成一个独立的 ResourceClaim。
-
ResourceSlice(资源切片):
这是驱动程序上报的“账本”。它详细列出了节点上每个设备的属性(如 UUID、频率、显存等),供调度器精准匹配。
三、 DRA 的黑科技特性
1. 结构化参数与 CEL 过滤
DRA 支持使用 Common Expression Language (CEL)。你可以写出类似“要求显存 > 16GB 且 驱动版本 >= 535”的表达式。调度器会根据 ResourceSlice 中的属性进行过滤,实现真正的“按需匹配”。
2. 延迟绑定(Late Binding)
这解决了著名的“死锁”问题。调度器会等到 Pod 确定了调度节点后,再触发驱动程序进行实际的硬件分配。这保证了硬件资源和计算节点在空间位置上的完美契合。
3. 设备共享与动态拆分(Partitioning)
DRA 允许驱动动态地将一个物理设备拆分为多个逻辑设备(如 NVIDIA 的 MIG)。多个 Pod 可以共享同一个 ResourceClaim,或者将一个物理 GPU 动态划分为多个小切片分给不同的容器。
4. 优先级列表(Prioritized List)
你可以给调度器一个“备选方案”:首选 A100 GPU,如果没有,给两块 T4 也可以。调度器会按优先级尝试满足你的需求。
四、 使用示例
下面是一个使用 DRA 进行 GPU 资源申请的典型配置示例。
这个例子展示了如何通过 DeviceClass、ResourceClaim 和 Pod 三者联动来请求特定属性的硬件。
1. 定义设备类 (DeviceClass)
这是由集群管理员定义的,用于描述某种类型的资源(类似于定义“黄金级存储”)。
1 | apiVersion: resource.k8s.io/v1alpha3 |
在 DRA 架构中,DeviceClass 到具体物理资源的“对应”过程,实际上是由 DRA 驱动程序(Driver)、节点资源切片(ResourceSlice) 和 控制面(Control Plane) 共同完成的。
我们可以把这个过程拆解为以下三个步骤:
1. 资源上报:数据从哪里来?
在每个带有硬件资源的节点上,都会运行一个该硬件厂商提供的 DRA Driver(类似于以前的 Device Plugin Agent)。
-
驱动扫描硬件:驱动程序启动后,会扫描节点上的物理设备(如 GPU、FPGA)。
-
创建 ResourceSlice:驱动会为该节点创建一个名为
ResourceSlice的资源对象。 -
打标签(Attributes):在
ResourceSlice中,驱动会详细列出每个设备的属性。例如:YAML
1
2
3
4
5
6
7
8
9# 这是一个 ResourceSlice 的简化概念图
spec:
nodeName: "node-1"
devices:
- name: "gpu-0"
attributes:
"vendor.com/model": { stringValue: "A100" }
"vendor.com/vram-gb": { intValue: 80 }
"vendor.com/cuda-version": { stringValue: "12.2" }
2. 规则匹配:DeviceClass 扮演什么角色?
DeviceClass 就像是一个**“过滤器蓝图”**。它定义了全局通用的筛选规则。
- Selector(选择器):当你定义
DeviceClass时,你会使用 CEL (Common Expression Language) 表达式。 - 逻辑对应:当调度器看到一个
ResourceClaim引用了DeviceClass时,它会拿着DeviceClass里的表达式,去遍历集群中所有ResourceSlice里的设备属性。
匹配逻辑示例:
- 用户请求:
deviceClassName: high-vram-gpu - DeviceClass 定义:
expression: device.attributes["vendor.com/vram-gb"] >= 40 - 系统动作:K8s 控制面会自动匹配那些在
ResourceSlice中vram-gb属性大于等于 40 的设备。
3. 最终绑定:如何锁定到那个“它”?
这个过程被称为 Structured Parameters(结构化参数) 处理:
- 调度决策:K8s 调度器通过
ResourceSlice发现node-1的gpu-0符合DeviceClass的要求。 - 分配 (Allocation):调度器(或专门的资源管理控制器)会更新
ResourceClaim的状态,将其status.allocation指向具体的节点名和设备 ID(例如node-1上的gpu-0)。 - 驱动执行:当 Pod 调度到
node-1时,该节点上的 DRA Driver 收到通知,执行最后的“准备工作”(如挂载驱动、配置环境变量、切分显存等),确保容器启动时能看到对应的硬件。
总结:对应关系的链路
- 物理硬件 由 Driver 抽象为 ResourceSlice(带有属性标签)。
- ResourceSlice 由 DeviceClass(CEL 表达式)进行筛选过滤。
- DeviceClass 由 ResourceClaim 引用,完成意向表达。
- ResourceClaim 最终由 调度器 锁定到具体的物理节点和设备。
为什么这种方式比以前高级?
以前的 Device Plugin 只会数数(节点有几个 GPU),它不知道 GPU 是什么型号。而 DRA 的 DeviceClass 配合 ResourceSlice 实现了**“按属性查货”**,这就像从“我要买一件衣服”进化到了“我要买一件 XL 码、蓝色的、纯棉的衬衫”。
2. 创建资源申请 (ResourceClaim)
这是用户定义的,描述具体的 Pod 需要什么资源。
1 | apiVersion: resource.k8s.io/v1alpha3 |
3. 在 Pod 中引用资源 (Pod)
Pod 不再使用 resources.limits,而是通过 resourceClaims 字段引用上面创建的对象。
1 | apiVersion: v1 |
进阶场景:在 Deployment 中使用模板 (ResourceClaimTemplate)
如果你需要扩容多个副本(Replica),手动创建 ResourceClaim 显然不现实。这时可以使用模板,让 K8s 为每个 Pod 自动创建申请。
1 | apiVersion: apps/v1 |
关键点解析:
- 解耦:Pod 不再关心具体哪个节点有 GPU,它只声明“我要一个符合
high-vram-gpu条件的资源”。 - CEL 过滤:在
DeviceClass中你可以看到device.attributes,这允许你根据厂商提供的标签(如显存、架构、驱动版本)进行非常精细的筛选。 - 动态生成:使用
ResourceClaimTemplate时,当 Pod 销毁,对应的ResourceClaim也会自动清理,像管理临时磁盘一样方便。
这种方式比旧版的 nvidia.com/gpu: 1 提供了更强大的表达能力,支持复杂的资源拓扑和参数。
五、 迁移与未来:Device Plugin 还会存在吗?
虽然 DRA 非常强大,但 Kubernetes 社区并没有打算立即废除 Device Plugin。
- 兼容性桥接:DRA 支持将资源暴露为旧版的“扩展资源”,方便旧工作负载平滑过渡。
- 现状:目前 NVIDIA、AMD 等头部厂商已开始推出原生的 DRA 驱动。
六、 总结
DRA 的出现,将 Kubernetes 从简单的“容器编排器”推向了“数据中心级硬件资源调度器”的高度。对于大模型训练、自动驾驶仿真等重资产业务,DRA 提供的灵活性和高利用率将直接转化为成本的节省。
一句话总结:
如果你还在为 GPU 调度不均、利用率低而苦恼,那么基于 DRA 的新一代基础设施建设已经可以提上日程了!





