代表性面试主题

系统设计面试:如何用 Kubernetes 设备健康状态治理 GPU 故障?

系统设计困难
Offer.cc 编辑团队发布 更新

题干

一个 GPU 推理平台偶尔把任务调度到已失效的设备。请设计基于 Pod 设备健康状态的检测与恢复系统,并说明 Unhealthy、Unknown、控制器幂等、租约和回滚边界。

题干与适用场景

一个多租户 GPU 推理平台使用 Kubernetes Device Plugin 和 Dynamic Resource Allocation(DRA)。驱动发现某张卡掉线后,旧系统只能在节点日志中看到错误,Pod 继续重启并反复领取同一设备。请设计一套利用 Pod .statusallocatedResourcesStatus 的故障治理方案:让运维和控制器看到设备健康,隔离坏卡,安全处理 Unknown,并避免大规模误删。

Kubernetes v1.36 将资源健康状态提升为 Beta。官方发布说明指出,状态可在 Pod 中报告已分配设备的健康,并可通过 kubectl describe pod 诊断 UnhealthyUnknown;该机制同时覆盖传统 Device Plugin 和 DRA 路径。

面试官考察点

  • 能否区分设备分配成功、设备健康、容器就绪和业务 SLO。
  • 能否画出驱动、kubelet、Pod status、控制器、调度器和告警系统的数据流。
  • 能否对 UnhealthyUnknown 使用不同处置,避免把观测缺失当成硬故障。
  • 能否设计幂等隔离、租约、重试、限流和恢复后的再入场。
  • 能否说明状态是诊断信号,不会自动替代调度策略或业务探针。

回答前需要澄清的问题

  • 健康状态由哪些驱动产生,更新延迟和心跳周期是多少?
  • 一个 Pod 可能分配多张卡;只坏一张卡时,任务能否部分降级,还是必须整体迁移?
  • Unknown 是暂时失联、节点下线还是驱动不支持?容忍窗口多长?
  • 隔离粒度是设备、节点、ResourceClaim 还是租户工作负载?谁有权恢复?
  • 任务是否有检查点、幂等提交和最大重试预算?迁移会造成多少 GPU 抖动?

30 秒回答框架

“我会把设备健康当作状态输入,而不是直接删除 Pod 的命令。驱动和 kubelet 更新 allocatedResourcesStatus 后,控制器按设备 ID 聚合状态:Unhealthy 进入隔离和告警,Unknown 先经过心跳容忍窗口。控制器用幂等键和租约标记坏设备,阻止新分配,已有任务按检查点迁移;限流每个节点的重调度。恢复时先做探针和短 canary,再解除隔离,并用状态延迟、误报率、迁移成功率和业务 SLO 验证。”

分步骤深入解答

  1. 定义状态模型。 记录设备标识、Pod、容器、ResourceClaim、节点、健康值、消息、观察时间和状态版本。把 Unhealthy(明确故障)与 Unknown(无法确认)分开,避免一个布尔值驱动所有自动化。
  1. 建立数据流。 DRA 或 Device Plugin 把设备分配给 Pod,kubelet 将驱动报告的健康信息写入 Pod status。状态观察器订阅 Pod 变化,按设备键去重后写入可重放的设备目录;告警和控制器都从该目录读取,避免各自直接扫 API 造成压力。
  1. 隔离新分配。 对明确不健康的设备设置内部 quarantine 记录,并让调度扩展、ResourceClaim 选择或节点容量视图排除它。不要直接修改 Pod status,也不要把单次异常立刻转换成节点 NotReady;隔离动作必须带原因、操作者和过期时间。
  1. 处理运行中任务。 控制器先判断任务是否有检查点和幂等提交,再按租约获得迁移权。可恢复任务先停止接收新请求、保存检查点、释放设备并在健康设备上重建;不可恢复任务保留失败证据并通知租户。每个设备和任务只允许一个迁移流程。
  1. 设计 Unknown 护栏。 Unknown 可能来自 kubelet、驱动或节点网络中断。设置基于心跳的容忍窗口和指数退避;窗口内只告警,超过窗口才限制新分配。节点整体失联时,使用节点租约和现有故障检测,不能仅凭一个 Pod status 推断所有设备损坏。
  1. 恢复与验证。 设备重新报告健康后,先执行驱动探针、分配小任务和持续观察,再解除 quarantine。指标包括状态年龄、Unknown 持续时间、误隔离率、迁移成功率、GPU 空闲时间和业务错误率;用回放事件测试重复更新、乱序状态和控制器重启。
text
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 护栏、幂等迁移和分阶段复用。

公开来源

同类题目

相关面试工具

用 Solve 整理系统设计回答

从澄清需求开始,展开规模、架构、组件选择和取舍。

查看工具