llm-wiki wiki · analysis 2026-09-27

当前上游核验(2026-09-27)

本节区分当前官方证据与下文 2026-07 的 KEP 设计/状态笔记;src-dra-driver-nvidia-gpu-architecture 是 2026-06 的 raw-backed Source 快照,保留其历史仓库/HEAD 和 ASCII 图。当前默认分支 commit 不代表 release,基础 DRA 稳定也不等于所有 Kubernetes 扩展或 NVIDIA driver 功能都已稳定。完整设备栈边界见 k8s-gpu-device-stack。

项目 当前 commit 当前证据边界
kubernetes 6c1c7702cf20 Kubernetes DRA API、scheduler allocation 与 kubelet Prepare/Unprepare;各扩展阶段按官方文档及该 commit 的 feature 定义单独核验
dra-driver-nvidia-gpu 495bf4c59b94 NVIDIA GPU/ComputeDomain 驱动实现;通过 NVIDIA 仓库入口查询时返回此规范链接,不以 Kubernetes 的 feature stage 替代厂商支持矩阵
能力 / feature gate 本次核验的阶段与版本 本页相关边界 / 官方依据
基础 DRA / DynamicResourceAllocation Stable,自 Kubernetes v1.35 DRA 概览;基础 Claim/设备分配稳定不覆盖下列所有扩展
Device binding conditions / DRADeviceBindingConditions Beta,自 v1.36,默认启用 延迟 Pod binding 以等待外部设备准备;当前 feature 定义;仍需对应 driver/status 支持
Consumable capacity / DRAConsumableCapacity Beta,自 v1.36,默认启用 多 Claim 消耗同一设备容量;DRA Features
Partitionable devices / DRAPartitionableDevices Beta,自 v1.36,默认启用 通过共享计数器表达逻辑设备资源重叠;DRA Features
Prioritized list / DRAPrioritizedList GA,自 v1.36;v1.37 锁定启用 按优先级尝试设备请求候选;当前 feature 定义
Device taints / DRADeviceTaints 当前源码 v1.37 条目标记 GA、默认启用;v1.38 条目锁定启用 设备 taint/toleration 的阶段不同于相关附加规则;当前 feature 定义,版本化源码条目不是未来 release 已发布的证明
Optional node operations / DRAOptionalNodeOperations Alpha,自 v1.37,默认关闭 driver 可声明跳过特定 node-local 操作,不能推广为所有 GPU 都无需 Prepare;DRA Features

该表只列本页相关且已核验的能力,不是完整 feature 清单。API 对象语义见 DRA API Objects。NVIDIA 侧须分别核对 锚定 driver README 和 GPU Operator 26.7 管理路径:独立仓库 GPU plugin 的支持说明与 Operator 管理版本的默认启用方式不能混用。下文 KEP 状态表属于历史演进记录,不覆盖本节的当前阶段核验。

M5-C 中的职责边界

k8s-gpu-device-stack 是设备栈入口,本页聚焦 kubernetes-dra 的 Claim、调度分配、节点准备与回收。Kubernetes 提供 DRA API 和 scheduler allocation;driver 发布 ResourceSlice 库存及设备约束,解释厂商配置并完成相应准备。DeviceClass 可由管理员或 driver 安装流程提供;node-feature-discovery 的节点标签不能替代它或 ResourceSlice。

kubelet 驱动节点侧 Prepare/Unprepare,dra-driver-nvidia-gpu 等插件操作具体设备,cdi 把已准备设备交给兼容 runtime 注入。gpu-operator 管理受管组件部署和升级,karpenter 管理节点容量;两者都不是单次 DRA Claim 的通用分配器。是否支持特定扩展仍以页首 feature-stage 表和目标 driver/release 为准,这里不重复或提升其阶段。

DRA Allocation / Binding Lifecycle

Admin / driver installation ── create selectors + config ──> DeviceClass
DRA driver - - publish inventory / attributes / capacities - -> ResourceSlice
User / workload controller ── create directly ──> ResourceClaim
User ── create ResourceClaimTemplate + referencing Pod ──> API
Pod/template - - watch / reconcile - -> resourceclaim controller
resourceclaim controller ── create owned Claim / record Pod claim reference ──> API

Pod + Claim + DeviceClass + ResourceSlice - - watch / scheduling input - -> scheduler
PreFilter / Filter ── evaluate feasible Node + devices ──> select compatible Node
Reserve ── retain candidate allocation in memory ──> PreBind
PreBind ── API write ──> Claim.status.allocation + reservedFor
  ├── no binding conditions ──> continue binding
  └── binding conditions enabled + present ──> wait in PreBind
Claim allocation - - observed by external driver controller - -> device preparation
driver controller ── write device conditions ──> Claim.status.devices
device conditions - - observed ready / failed / timeout - -> PreBind result
PreBind success ──> Bind Pod to compatible Node
PreBind failure ──> Unreserve / cleanup this attempt - - retry feedback - -> queue

图例:实线 ── label ──> 表示有序调用、API 写入或节点动作,虚线 - - label - -> 表示发布、watch、反馈与重试。图按引用 Claim 的普通 Pod 路径展开:已经分配的 Claim 会被校验和复用,不能把每一轮都理解成覆盖 allocation;模板需要由 resourceclaim controller 实例化,不是 scheduler 直接把模板当作已存在的 Claim。API 写入者也分开:scheduler 负责本次分配与消费者 reservation,外部 driver/controller 按协议更新设备 conditions,resourceclaim controller 管理派生 Claim 与消费者生命周期。

锚定版本的 DynamicResources 插件 在 Reserve 记录候选,在 PreBind 的 bindClaim 写回 allocation/reservation,然后按启用的扩展与设备声明等待 binding conditions。没有该条件时直接继续 binding;出现 failure condition 或超时则本次绑定失败。后续 Filter/PostFilter 可按 Claim 的消费者限制决定是否清除失败 allocation,不能把 Unreserve 等同于无条件清空所有共享 Claim。

binding conditions 允许外部准备发生在 Pod binding 前;它不是节点侧 NodePrepareResources 的另一种名字。后者通常在 Pod 已绑定、kubelet 准备容器时发生。Claim 分配成功、外部条件就绪、Pod 绑定成功、节点准备成功和容器运行是不同检查点。对象语义与模板控制器分别见 DRA API Objects 和 resourceclaim controller。

kubelet Prepare / CDI / Release

Bound Pod + allocated/reserved Claim - - observed state - -> kubelet DRA manager
kubelet ── track Pod/Claim reference + checkpoint ──> node-local state
kubelet ── NodePrepareResources ──> vendor DRA plugin
plugin ── validate allocation / configure device / recover own state ──> device + checkpoint
plugin ── prepare CDI spec + return CDI device IDs ──> kubelet
kubelet ── checkpoint prepared result / CRI device configuration ──> runtime
runtime ── resolve CDI spec / inject devices / start container ──> running workload

Pod termination - - node reconciliation - -> kubelet drops this Pod reference
  ├── other local Pods still use Claim ──> retain shared prepared state
  └── no local users ──> NodeUnprepareResources ──> plugin cleanup
      ── successful result ──> kubelet updates cache / checkpoint
Pod completion / deletion - - API watch - -> resourceclaim controller
controller ── remove completed consumer reservation ──> Claim status
last consumer released ── eligible deallocation / finalizer cleanup ──> reusable Claim
owned Claim deletion ── owner / GC lifecycle ──> Claim removed when cleanup permits

两条终止分支分别处理节点状态和 API 状态,不是跨组件事务,也不保证总按图中文字顺序完成。当前 kubelet DRA manager 在 RPC 前后记录 Claim/Pod 与准备结果;其他本地 Pod 仍引用同一 Claim 时延迟 Unprepare。kubelet checkpoint 与 vendor plugin 自己的 checkpoint/config 是不同责任:重启恢复需同时对照 API、节点记录及真实硬件,不能把删除任一记录当作已完成设备释放。

当前 resourceclaim controller 在最后消费者从“仍使用”转为“不再使用”时,可清除相应 allocation 和不再需要的 finalizer,使保留的 Claim 以后重新分配。模板派生 Claim 随 owner 生命周期回收;用户直接创建的持久 Claim 对象可以保留,但保留对象不意味着永久保留同一设备。多消费者场景不能因其中一个 Pod 退出就清空全部 reservation 或拆掉共享准备状态。

图中 Prepare/Unprepare 是常规 node-local 路径。页首 DRAOptionalNodeOperations 仍为独立 Alpha 扩展:只有启用该能力且 allocation 携带合法 skip 声明时,kubelet 才跳过指定节点操作;这不是所有 GPU 默认行为。CDI 负责容器注入,不保证硬件准备、健康或隔离策略本身正确。正式 RPC 名称为复数 NodePrepareResources / NodeUnprepareResources,下方历史笔记的单数简写不应作为接口名使用。

DRA 失败与恢复路径

失败点 / 可见影响 自动恢复 / API 与节点边界 Operator 与人工处理边界
ResourceSlice 陈旧或 pool 不完整:设备不可选或节点准备发现不符 driver 重新发布完整库存,scheduler 根据相关更新重试;节点 plugin 仍须校验设备现状 Operator 可恢复受管 driver,但错误设备 identity/generation、权限或硬件丢失需修复
Allocation / reservation 并发冲突:PreBind status 写入失败 API 并发检查拒绝冲突写入,scheduler 重读重算并清理本次保留;不覆盖其他消费者 持续争用、错误 UID/字段所有权或自定义控制器乱写 status 需修正
Binding conditions 超时或失败:有 allocation 但 Pod 未绑定 PreBind 失败触发 Unreserve/重试;后续 deallocation 受 Claim reservation 条件限制,不保证立即换设备 修复外部准备 controller、设备条件/RBAC 协议或不可恢复资源故障;延长超时不能制造 Ready
Driver / kubelet 重启及 checkpoint 不一致:准备状态难以恢复 kubelet 重连插件并依据引用/准备记录重试;vendor plugin 按自己的幂等恢复规则核对硬件 Operator 重建进程不等于硬件回滚;损坏/丢失 checkpoint、升级不兼容需受控恢复
Prepare 或 Unprepare 失败:容器无法启动或节点清理未完成 kubelet 对可重试错误再次调用,插件需容忍重复 RPC 和部分完成;共享 Claim 按本地引用计数处理 检查配置、权限、设备占用和插件错误;永久错误需人工处置,不能仅删除 finalizer
CDI spec / runtime 不匹配:Claim 与 Prepare 成功但容器启动失败 修复配置后启动路径可重试;CDI 注入不负责重新选择设备 核对 CDI IDs、spec 路径、runtime 支持与 driver/toolkit 版本;Operator 只修复其管理范围
MIG / VFIO / ComputeDomain 部分变更:API、checkpoint 与硬件/IMEX 不一致 driver/controller 按具体模式重放或清理;API 重试没有通用硬件补偿保证 确认其他消费者后处理 MIG 实例、驱动绑定、域成员或排空节点;不能假设一次重启全部恢复
节点失联或非优雅关机:NodeUnprepare 可能未执行 控制面继续观察消费者和节点状态;节点返回后由 kubelet/plugin 重新协调,外部设备可能需独立清理 对无法返回的节点须核实设备/网络连接已隔离及外部状态已释放,再处理遗留 Claim;API 删除不证明旧节点已停止使用

排障应分别核对 Claim allocation/reservedFor/device conditions、Pod binding、kubelet checkpoint、vendor plugin 状态及 runtime 配置。上表是当前职责归纳;下方保留的 KEP 风险条目不能直接当成所有版本/driver 的通用恢复保证。

KEP 设计与演进(历史笔记)

以下保留 Kubernetes Dynamic Resource Allocation 的历史设计脉络。核心是 sig-node/4381-dra-structured-parameters,它把早期 3063-dynamic-resource-allocation 的 opaque driver 协商路线反转为主线:设备参数必须结构化地暴露给 scheduler 和 autoscaler,Kubernetes 才能可靠做调度和容量推理。逐个 KEP 的 Alpha/Beta/GA、是否实现和 feature gate 见 kubernetes-keps-implementation-matrix;当前阶段以页首核验表为准。

一句话定位

DRA 是 Kubernetes 对 GPU、NIC、FPGA、DPU、network-attached accelerator、可分区设备和共享容量的下一代设备资源模型。它不是 device plugin 的简单替代,而是把“设备发现、设备选择、claim 状态、节点准备、CDI 注入、scheduler 推理、autoscaler 模拟”放到同一个 API 体系里。

为什么 device plugin 不够

Device Plugin API 适合“节点本地、离散、可计数”的资源,例如 nvidia.com/gpu: 1。但新设备场景更复杂:

如果设备选择完全由 vendor driver 在调度后 opaque 决定,scheduler 只能猜,Cluster Autoscaler / karpenter 也无法模拟。

4381 的核心模型

历史模型按四个角色拆分:DRA driver 发布带 devices/attributes/capacities 的 ResourceSlice;用户/controller 创建带 requests/selectors/config 的 ResourceClaim 或模板;kube-scheduler 对照库存评估请求并写 allocation status;kubelet 调用 DRA plugin Prepare/Unprepare,再将 CDI 设备交给 runtime。当前完整顺序与模板实例化、条件等待的细分见上方两张图。

ResourceSlice 是 driver 发布的资源库存。每个 device 有名字、属性和 capacity。属性可以被 CEL selector 匹配,capacity 用 quantity 表达。

DeviceClass 是集群管理员定义的设备类别,承载通用 selector 和配置。用户侧 ResourceClaim 引用它,并可继续补充 request selector 和 config。

ResourceClaim 是用户或 controller 要的资源。它的 spec 不变,status 由系统写入 allocation result、reservation、设备结果等状态。

结构化参数的关键价值

早期 3063 让 DRA driver 通过 control-plane controller 参与 allocation。问题是 scheduler / autoscaler 看不懂 driver 的自定义逻辑。4381 的结构化参数让 Kubernetes 至少能理解:

这不是为了让 Kubernetes 理解所有 vendor 细节,而是把“调度必须知道的部分”变成 API 结构,剩下的配置参数仍可 opaque 地传给 driver。

Scheduler 插件路径

DRA scheduler plugin 不是只在 Filter 阶段做一次检查。它覆盖多个 extension point:

阶段 作用
EventsToRegister 注册 ResourceClaim、ResourceSlice、DeviceClass 等事件,并通过 queueing hints 精准唤醒相关 Pod。
PreEnqueue 快速检查 Pod 引用的 claim 是否存在,不存在就先不要进入正常调度。
PreFilter 收集 claim、class、slice、已分配资源和 in-flight allocation,准备高效 filter。
Filter 判断候选节点是否能满足 claim,执行 selector/capacity/match-attribute 等检查。
Reserve 节点已选定后,在内存里计算 allocation result。
PreBind 在独立 goroutine 中把 allocation/reservation 写回 ResourceClaim status。
Unreserve 绑定失败或调度失败时释放 reservation,避免 deadlock。

这个设计把昂贵或阻塞 API 写操作放到 PreBind 旁路,减少主 scheduling cycle 的阻塞。

ResourceClaim 状态机

DRA 的状态核心在 ResourceClaim.status:

历史状态模型依次描述:unallocated;scheduler 选择 node/device 后 allocated;reservedFor 纳入消费者后被 Pod 或其他 consumer 使用;消费者退出后进入 deallocated/reusable。它概括的是控制面生命周期,不应把其中一条状态转换当成所有节点准备状态已经同步释放,具体回收边界见上方 kubelet Prepare / CDI / Release。

几个设计点很关键:

kubelet 和 DRA plugin

kubelet 通过 plugin registration 发现 DRA kubelet plugin。Pod 绑定到节点并且 claim 已 allocated/reserved 后,kubelet 调用:

这条路径的关键是:scheduler 决定“用哪个设备”,kubelet/driver 负责“把设备准备好并注入容器”。如果设备在 scheduler 决定后消失,kubelet plugin 必须二次确认,Pod 可能保持无法启动直到资源恢复或被重新处理。

DRA 与 Autoscaler

DRA 最重要的教训来自 3063 到 4381 的路线变化:Cluster Autoscaler 需要模拟未来节点上的资源可用性。对于 node-local 设备,如果 claim 参数 opaque,autoscaler 无法知道加哪类节点能满足 Pod。

结构化参数让 autoscaler 至少可以读取 ResourceSlice 模型和 claim selector,判断“创建某个 node group 的节点是否可能让 pending Pod 调度成功”。这也是 DRA 为什么不能只停留在 driver 自定义 allocation 的原因。

关键扩展 KEP

KEP 解决的问题 设计意义
5007-device-attach-before-pod-scheduled 设备 attach/初始化可能是异步的,Pod 不应先绑定再失败。 把 device binding conditions 放入 scheduler PreBind 等待路径。
5075-dra-consumable-capacity 设备不一定是离散实例,也可能有可消费容量。 支撑 GPU memory、带宽、license、共享 buffer 等容量型设备。
5941-dra-shared-consumable-capacity 多个设备共享一组 capacity。 处理多个 logical device 背后共享同一个物理资源池。
4815-dra-partitionable-devices 设备可以动态切分。 让 MIG-like 或 TPU-like partition 不再只能预先静态发布。
4816-dra-prioritized-list 用户可接受多种设备配置。 用优先级备选列表表达“首选 A,不行则 B”。
5055-dra-device-taints-and-tolerations 设备健康或策略需要暂时排除。 将 node taint 思路下沉到 device 层。
6080-dra-derived-attributes 不同 driver 属性表达不一致。 用派生属性对齐调度可用的 topology/compatibility 语义。

失败模式和风险

风险 解释 设计处理
stale ResourceSlice driver 发布的设备状态过期。 kubelet plugin 在 NodePrepare 时二次确认。
scheduler filter 成本高 CEL、设备数量、claim 数量、match attributes 会放大计算成本。 Filter timeout、queueing hints、scheduler metrics。
claim 并发 reservation 多 scheduler 或多个 Pod 争同一 claim。 ResourceVersion/UID/status conflict 作为同步点。
node reboot / kubelet restart 旧 ResourceSlice 可能残留。 kubelet 启动时删除本节点 ResourceSlices,等待 driver 重建。
opaque 参数过多 autoscaler 和 scheduler 无法推理。 structured parameters 作为 GA 主线,opaque config 仅用于 driver 准备。
non-graceful node shutdown NodeUnprepare 不一定被调用。 driver 需要在 Deallocate 或外部状态中恢复。

和 GPU 生态的关系

阅读顺序

  1. 4381-dra-structured-parameters:DRA 主线设计。
  2. 3063-dynamic-resource-allocation:理解为什么 opaque control-plane allocation 被降级。
  3. 4815 / 5075 / 5941:理解 partition 和 capacity。
  4. 5007:理解 device attach/readiness 如何进入调度。
  5. 5055 / 4816 / 6080:理解生产化调度表达。

关键 KEP 实现状态

KEP 当前状态 Alpha / Beta / GA Feature gate 关键实现路径
4381-dra-structured-parameters implemented / stable,已实现/GA v1.30 / v1.32 / v1.34 DynamicResourceAllocation, DRASchedulerFilterTimeout ResourceSlice/ResourceClaim/DeviceClass 结构化参数,scheduler 和 autoscaler 可推理。
3063-dynamic-resource-allocation withdrawn / alpha,已撤回 v1.26 / - / - DynamicResourceAllocation, DRAControlPlaneController opaque control-plane allocation 路线,因调度和 autoscaler 不可推理被 4381 取代。
5007-device-attach-before-pod-scheduled implementable / beta,仍在 beta v1.34 / v1.36 / v1.37 DRADeviceBindingConditions device binding/readiness 条件进入 scheduler PreBind 等待路径。
5075-dra-consumable-capacity implementable / beta,仍在 beta v1.34 / v1.36 / v1.38 DRAConsumableCapacity 设备可表达可消费 capacity,而不是只表达离散实例。
5729-resourceclaim-support-for-workloads implementable / beta,仍在 beta v1.36 / v1.37 / - DRAWorkloadResourceClaims ResourceClaim 支持 workload 级消费者,连接 DRA 和 PodGroup。
5941-dra-shared-consumable-capacity implementable / alpha,仍在 alpha v1.37 / v1.38 / v1.39 DRASharedConsumableCapacity 多个设备共享同一 capacity pool。
5963-device-compatibility-groups implementable / alpha,仍在 alpha v1.37 / v1.38 / v1.39 DRADeviceCompatibilityGroups 表达多设备组合兼容性。
4815-dra-partitionable-devices implementable / beta,仍在 beta v1.33 / v1.36 / - DRAPartitionableDevices 动态或逻辑分区设备进入 ResourceSlice 模型。
4816-dra-prioritized-list implementable / stable,GA 目标已达 v1.33 / v1.34 / v1.36 DRAPrioritizedList 用户可声明设备请求的优先级备选列表。
5055-dra-device-taints-and-tolerations implementable / stable,GA 目标已达 v1.33 / v1.36 / v1.37 DRADeviceTaints, DRADeviceTaintRules 设备级 taints/tolerations,支持健康和策略隔离。
4817-resource-claim-device-status implementable / stable,GA 目标已达 v1.32 / v1.33 / v1.37 DRAResourceClaimDeviceStatus 分配结果和设备信息进入 ResourceClaim status。
5304-dra-attributes-downward-api implementable / beta,仍在 beta v1.36 / v1.37 / v1.38 NA 将 DRA device attributes 暴露给 Pod 内 workload。
4680-add-resource-health-to-pod-status implementable / beta,仍在 beta v1.31 / v1.36 / v1.37 ResourceHealthStatus Device Plugin/DRA resource health 进入 Pod status。

追踪重点