题干与适用场景
一个多租户 GPU 推理平台使用 Kubernetes Device Plugin 和 Dynamic Resource Allocation(DRA)。驱动发现某张卡掉线后,旧系统只能在节点日志中看到错误,Pod 继续重启并反复领取同一设备。请设计一套利用 Pod .status 中 allocatedResourcesStatus 的故障治理方案:让运维和控制器看到设备健康,隔离坏卡,安全处理 Unknown,并避免大规模误删。
Kubernetes v1.36 将资源健康状态提升为 Beta。官方发布说明指出,状态可在 Pod 中报告已分配设备的健康,并可通过 kubectl describe pod 诊断 Unhealthy 或 Unknown;该机制同时覆盖传统 Device Plugin 和 DRA 路径。
面试官考察点
- 能否区分设备分配成功、设备健康、容器就绪和业务 SLO。
- 能否画出驱动、kubelet、Pod status、控制器、调度器和告警系统的数据流。
- 能否对
Unhealthy与Unknown使用不同处置,避免把观测缺失当成硬故障。 - 能否设计幂等隔离、租约、重试、限流和恢复后的再入场。
- 能否说明状态是诊断信号,不会自动替代调度策略或业务探针。
回答前需要澄清的问题
- 健康状态由哪些驱动产生,更新延迟和心跳周期是多少?
- 一个 Pod 可能分配多张卡;只坏一张卡时,任务能否部分降级,还是必须整体迁移?
Unknown是暂时失联、节点下线还是驱动不支持?容忍窗口多长?- 隔离粒度是设备、节点、ResourceClaim 还是租户工作负载?谁有权恢复?
- 任务是否有检查点、幂等提交和最大重试预算?迁移会造成多少 GPU 抖动?
30 秒回答框架
“我会把设备健康当作状态输入,而不是直接删除 Pod 的命令。驱动和 kubelet 更新 allocatedResourcesStatus 后,控制器按设备 ID 聚合状态:Unhealthy 进入隔离和告警,Unknown 先经过心跳容忍窗口。控制器用幂等键和租约标记坏设备,阻止新分配,已有任务按检查点迁移;限流每个节点的重调度。恢复时先做探针和短 canary,再解除隔离,并用状态延迟、误报率、迁移成功率和业务 SLO 验证。”
分步骤深入解答
- 定义状态模型。 记录设备标识、Pod、容器、ResourceClaim、节点、健康值、消息、观察时间和状态版本。把
Unhealthy(明确故障)与Unknown(无法确认)分开,避免一个布尔值驱动所有自动化。
- 建立数据流。 DRA 或 Device Plugin 把设备分配给 Pod,kubelet 将驱动报告的健康信息写入 Pod status。状态观察器订阅 Pod 变化,按设备键去重后写入可重放的设备目录;告警和控制器都从该目录读取,避免各自直接扫 API 造成压力。
- 隔离新分配。 对明确不健康的设备设置内部 quarantine 记录,并让调度扩展、ResourceClaim 选择或节点容量视图排除它。不要直接修改 Pod status,也不要把单次异常立刻转换成节点 NotReady;隔离动作必须带原因、操作者和过期时间。
- 处理运行中任务。 控制器先判断任务是否有检查点和幂等提交,再按租约获得迁移权。可恢复任务先停止接收新请求、保存检查点、释放设备并在健康设备上重建;不可恢复任务保留失败证据并通知租户。每个设备和任务只允许一个迁移流程。
- 设计 Unknown 护栏。 Unknown 可能来自 kubelet、驱动或节点网络中断。设置基于心跳的容忍窗口和指数退避;窗口内只告警,超过窗口才限制新分配。节点整体失联时,使用节点租约和现有故障检测,不能仅凭一个 Pod status 推断所有设备损坏。
- 恢复与验证。 设备重新报告健康后,先执行驱动探针、分配小任务和持续观察,再解除 quarantine。指标包括状态年龄、Unknown 持续时间、误隔离率、迁移成功率、GPU 空闲时间和业务错误率;用回放事件测试重复更新、乱序状态和控制器重启。
Device health event
-> Pod status observer
-> deduplicate by (node, deviceID, statusVersion)
-> device quarantine record with lease and expiry
-> scheduler/claim filter excludes unhealthy device
-> checkpointed workload migration
-> probe + canary
-> release quarantine高质量示范回答
我会先建立设备级状态目录,把驱动、kubelet、Pod、ResourceClaim 和业务任务关联起来。Unhealthy 是明确故障,立即创建带租约和过期时间的 quarantine,阻止新分配并告警;Unknown 先走心跳容忍窗口,期间只告警,超过窗口再限制分配。控制器按设备 ID 去重,重启后可从事件和状态目录恢复,不依赖内存标记。
运行中任务是否迁移由检查点、幂等提交和租户优先级决定。可恢复任务保存检查点、释放设备并在健康设备上重建;不可恢复任务保留失败证据。恢复时先做驱动探针和小规模 canary,再解除隔离。调度插件、DRA 选择和节点容量视图都要消费隔离记录,状态本身只提供诊断信号,不替代 readiness 或业务 SLO。我要用状态延迟、误报率、迁移成功率和业务错误率证明系统有效。
常见错误
- 错误表现: 看到
Unknown就立刻删除所有 Pod → 失败原因: 短暂观测中断被放大成集群抖动 → 修正方法: 使用租约、心跳窗口和限流。 - 错误表现: 只按节点隔离,不记录设备 ID → 失败原因: 一张坏卡拖垮同节点健康设备 → 修正方法: 以设备和 ResourceClaim 为主键,必要时再提升到节点。
- 错误表现: 直接修改 Pod status 让它看起来健康 → 失败原因: 状态来源失真,控制器可能错误恢复 → 修正方法: 保留 kubelet 来源,另建可审计 quarantine 状态。
- 错误表现: 设备恢复后立即接收满载任务 → 失败原因: 瞬时恢复或驱动状态尚未稳定 → 修正方法: 先探针、短 canary、逐步放量。
追问及应对
一张 GPU 失效但 Pod 还有其他 GPU,是否只迁移部分任务?
先确认框架是否支持动态缩容和重新绑定。若模型需要固定设备拓扑,就整体迁移;若可分片,则只迁移受影响分片,并为剩余设备保留一致的 ResourceClaim 和检查点语义。
状态消息很旧但值仍是 Healthy,怎么办?
把健康值和状态年龄分开。超过心跳上限后转为 Unknown,不要继续把旧 Healthy 当作实时证明;告警和调度策略按状态年龄设置护栏。
如何防止多个控制器重复迁移?
以设备 ID、任务 ID 和状态版本组成幂等键,使用带过期时间的租约或乐观版本更新。失去租约的控制器必须停止动作,新的控制器从持久化记录继续。
什么时候可以把设备重新放回容量池?
驱动报告健康只是必要条件。还要通过设备探针、分配小任务、持续观察窗口,并确认 quarantine 原因已关闭;任一步失败就延长隔离,不做人工强制放行。
参考资料
- Kubernetes v1.36:Haru
- Kubernetes v1.36:More Drivers, New Features, and the Next Era of DRA
- Kubernetes v1.34:Pods Report DRA Resource Health
- Dynamic Resource Allocation 文档
面试作答要点
先画出驱动到 Pod status、观察器、隔离记录和调度过滤的数据流,再区分 Unhealthy 与 Unknown,最后补租约、检查点、限流、恢复 canary 和指标。
一句话总结
设备健康状态让 Kubernetes 能观察硬件故障,但安全恢复仍需要设备级隔离、Unknown 护栏、幂等迁移和分阶段复用。