Device Plugin、CDI 与 DRA¶
Kubernetes 管理 GPU、NIC、FPGA 和 AI ASIC 时涉及三个容易混淆的机制:Device Plugin 负责将设备作为扩展资源提供给 kubelet,CDI 描述容器如何获得设备,Dynamic Resource Allocation(DRA)提供更丰富的设备选择和分配 API。
它们解决的是相互关联但不同的问题。
1. 职责对照¶
| 机制 | 主要回答 | 典型对象或文件 |
|---|---|---|
| Device Plugin | 节点上有多少可分配设备,容器分到哪些设备 | 扩展资源、kubelet Device Plugin API |
| CDI | 容器运行时如何注入设备节点、挂载和环境变量 | CDI JSON Spec |
| DRA | 工作负载需要什么属性的设备,如何声明和绑定 | DeviceClass、ResourceSlice、ResourceClaim |
| NFD/Node Labeller | 节点具有什么硬件或软件特征 | Node Label |
| Kueue | 哪个工作负载现在可以使用多少设备配额 | Workload、ClusterQueue、ResourceFlavor |
DRA 不替代驱动安装,CDI 不负责调度,Kueue 也不选择具体设备。
2. Device Plugin 工作方式¶
典型流程:
厂商 Device Plugin DaemonSet
→ 在每个节点发现设备
→ 向 kubelet 注册资源名
→ kubelet 更新 Node Capacity/Allocatable
→ Pod 通过 resources.limits 请求整数数量
→ scheduler 选择有足够扩展资源的节点
→ kubelet 调用 Allocate
→ Runtime 获得设备节点、挂载、环境变量或 CDI 设备名
请求示例:
Device Plugin 的优点:
- API 稳定、生态成熟;
- Pod 写法简单;
- 调度器、配额和监控广泛支持扩展资源;
- 适合整卡或预先配置好的 MIG/共享资源。
主要限制:
- 资源通常只是整数计数;
- 很难表达每块设备属性和跨设备关系;
- 复杂共享和动态重配置依赖厂商私有机制;
- 多种相关设备的联合分配能力有限;
- 选择逻辑经常退化为节点标签。
3. CDI 工作方式¶
一个概念性 CDI Spec:
{
"cdiVersion": "0.8.0",
"kind": "vendor.example/device",
"devices": [
{
"name": "device0",
"containerEdits": {
"deviceNodes": [
{"path": "/dev/example0"}
]
}
}
]
}
CDI 的价值是让设备注入从运行时特定 Hook 走向标准化描述。常见内容包括:
- Linux Device Node;
- 宿主文件或目录挂载;
- 环境变量;
- Hook;
- Intel、NVIDIA 等厂商设备的限定名称。
运维重点:
- CDI Spec 由谁生成;
- 文件目录和权限;
- 设备重配置后何时刷新;
- containerd/CRI-O 是否启用对应版本;
- 陈旧 Spec 是否会引用已不存在的设备;
- RuntimeClass 是否使用相同的 CDI 路径。
4. DRA API 模型¶
DRA 的核心角色:
设备厂商 / Driver
└── ResourceSlice:发布设备库存、属性和容量
集群管理员
└── DeviceClass:定义可申请的设备类别和选择规则
工作负载作者
├── ResourceClaimTemplate:随 Pod 创建 Claim
└── ResourceClaim:一次具体设备请求
scheduler + kubelet + DRA Driver
└── 选择、绑定、准备、注入和回收设备
DeviceClass 概念示例:
apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
name: high-memory-gpu
spec:
selectors:
- cel:
expression: device.attributes["gpu.example.com"].memoryGiB >= 80
具体 API 字段以目标 Kubernetes 版本和 Driver 文档为准。DRA 在 Kubernetes 1.34 将核心 API 推进到 GA,后续版本仍在增加共享、Workload ResourceClaim 和设备健康等能力。
参考:Kubernetes 1.34 DRA GA、Kubernetes 1.36 DRA
5. DRA 比节点标签多表达什么¶
传统方式:
节点标签描述“节点上存在某类设备”,但不能保证分到的具体设备具备某属性。DRA 可以将属性与每个 Device 关联,并支持:
- 显存、型号、固件或能力选择;
- 多个候选请求和回退;
- 多容器或多 Pod 的共享语义;
- GPU、NIC 等设备的拓扑关系;
- 可配置容量或分区;
- 工作负载级 Claim 生命周期;
- 更精确的设备健康和状态。
是否真正支持取决于 Kubernetes 版本和厂商 DRA Driver,不应只根据上游 API 存在就承诺功能。
6. ResourceClaim 生命周期¶
必须验证:
- Claim 在何时创建;
- scheduler 在何时选择设备;
- Pod 删除、失败和重建后是否复用;
- Driver 重启时分配状态如何恢复;
- 节点 NotReady 后 Claim 如何处理;
- 多 Pod Workload 是否能整体持有设备;
- Claim 删除后设备何时可重新分配;
- 控制面备份恢复后状态是否一致。
有状态设备分配不能只做一次“Pod 能跑”的 Smoke Test。
7. Device Plugin 与 DRA 如何选择¶
| 场景 | 建议 |
|---|---|
| 单一型号、整卡独占、生态稳定 | Device Plugin 仍然合适 |
| 已有 MIG/共享资源命名且运行稳定 | 暂不为追新强制迁移 |
| 需要设备属性选择和候选回退 | 评估 DRA |
| GPU 与 NIC 等多设备拓扑联合选择 | 优先验证 DRA Driver 能力 |
| 厂商只支持 Device Plugin | 使用 Device Plugin |
| DRA 与节点自动扩容尚不兼容 | 保留 Device Plugin 或分离节点池 |
| 新建平台且厂商提供受支持 DRA | 在 Canary 节点逐步引入 |
DRA 不是 Device Plugin 的立即替代品,而是设备 API 的长期演进方向。生产平台可以在不同节点池并行使用两种模式,但同一设备通常不能由两个 Driver 同时管理。
8. 迁移策略¶
第 1 阶段:库存与兼容性¶
- 固定 Kubernetes、Driver、Operator 和 Runtime 版本;
- 确认厂商支持,而不是只有实验仓库;
- 列出依赖扩展资源名的 Kueue、配额、策略和监控;
- 验证自动扩容、RuntimeClass、MIG/共享和多网卡组合。
第 2 阶段:独立节点池¶
- 准备 DRA Canary 节点池;
- 不在同一设备上运行 Device Plugin;
- 使用新的 Workload Template;
- 对比资源库存、Pod 状态和计费归属;
- 注入 Driver 重启、节点重启和 Claim 删除故障。
第 3 阶段:平台 API 双栈¶
平台接口可以暂时同时生成:
- Device Plugin 的
resources.limits; - DRA 的 ResourceClaimTemplate。
选择由 Accelerator Flavor 或 Runtime 版本决定,用户不必手工维护两套复杂清单。
第 4 阶段:逐池迁移¶
按硬件型号和业务风险迁移,保留回滚到旧节点池的能力。不要在一次集群升级中同时更换 Kubernetes、驱动、DRA 和训练框架。
9. 与队列和调度的关系¶
Kueue 的配额可能仍以资源 Flavor 表达,而 DRA Claim 选择具体设备。平台需要确保:
- 准入资源口径与实际设备数量一致;
- Gang/PodGroup 不会部分分配设备后长期等待;
- 拓扑约束同时考虑 Workload 和 Device;
- 抢占时 Claim 能正确释放或重用;
- 多集群分发前目标集群存在相同 DeviceClass 契约。
Kubernetes 1.36 的 Workload/PodGroup 与 ResourceClaim 集成代表这一层仍在快速演进,应在文档中明确目标版本和 Feature State。
10. 可观测性¶
至少采集:
- ResourceSlice 数量和最后更新时间;
- DeviceClass、Claim、Allocation 状态;
- Claim Pending/失败原因与耗时;
- Driver Controller 和 Node Plugin 错误;
- Pod、容器、Claim、物理设备 ID 的关联;
- 设备健康、共享容量和实际利用率;
- 删除后未释放的分配;
- Driver Reconcile 和 API 延迟。
使用 Device Plugin 时也应建立 Pod UID 到设备 UUID 的映射,不能只按节点聚合 GPU 指标。
11. 故障场景¶
| 故障 | 需要验证的行为 |
|---|---|
| Device Plugin/Node Plugin 重启 | 已运行容器不受影响,库存恢复 |
| DRA Controller 重启 | Claim 状态可恢复,不重复分配 |
| kubelet 重启 | Pod 和设备分配一致 |
| 节点突然掉电 | 设备不会永久泄漏 |
| 设备健康恶化 | 停止新分配并保留诊断 |
| Claim 被误删 | Owner 和准入策略阻止或安全处理 |
| API Server/etcd 恢复 | ResourceSlice/Claim 与节点实际状态一致 |
| Driver 升级失败 | 可回滚且旧 Claim 可读取 |
12. 安全边界¶
- Device Plugin、DRA Node Plugin 和 CDI 生成器通常具有主机权限;
- 限制其镜像来源、hostPath、ServiceAccount 和升级权限;
- 不允许租户任意创建系统级 DeviceClass 或配置 Driver;
- DeviceClass 的 CEL 选择规则应经过审查;
- CDI Spec 目录应只允许可信组件写入;
- 设备直通、共享和 Kata Runtime 需要独立威胁模型。
13. 生产检查清单¶
- 能区分 Driver 安装、设备发现、容器注入和配额准入。
- Device Plugin 或 DRA 的选择有明确业务理由。
- 同一物理设备没有被两个机制重复管理。
- CDI Spec 的生成、刷新和权限受控。
- Claim 生命周期覆盖 Pod 删除、节点故障和控制器重启。
- 队列、计费、策略和监控已适配新的设备模型。
- 自动扩容与 DRA 的目标组合经过厂商验证。
- 每种设备管理方式都有 Canary 节点池和回滚路径。
- Feature State、Kubernetes 版本和 Driver 版本写入平台契约。
- 设备健康能阻止新分配并触发诊断。