题目与背景
你负责一个 Kubernetes GPU 平台。租户提交的训练和批推理作业需要等待配额、节点资源、维护窗口和安全策略全部满足后才能创建 Pod。请用 Kueue 的 Workload、ClusterQueue、ResourceFlavor 和 AdmissionCheck 设计准入流程,并说明如何避免饥饿和错误放行。
面试官考察什么
考察你能否把“排队”和“准入”分开:Workload 进入队列不等于可以创建 Pod,ClusterQueue 根据资源组与 nominal quota 选择 flavor,AdmissionCheck 则让外部或内部控制器参与放行。高质量答案还要覆盖状态一致性、撤销、部分准入、租户公平、重试退避和审计。
先问清楚的澄清问题
资源与优先级
确认 GPU 型号、显存、CPU、内存、拓扑和可抢占性,以及租户优先级、队列公平和最大等待时间。只按 GPU 数量计费可能导致显存或拓扑不足时的假容量。
外部准入依赖
确认维护窗口、镜像扫描、预算审批和数据权限由哪些控制器检查,检查结果是否可重放,超时后是拒绝还是等待。外部检查必须有明确 owner 和 TTL。
失败与撤销策略
明确已准入 Workload 在节点变更、配额回收或策略撤销时如何处理。准入记录、Pod 创建和外部检查之间需要幂等关联,避免重复放行。
30 秒回答框架
“用户提交的 Workload 先进入 LocalQueue,再由 ClusterQueue 根据资源组、flavor 和 cohort 配额判断是否可分配。所有 AdmissionCheckState 必须为 Ready 才能准入;检查 Pending 就继续排队,Rejected 或超时按策略重试或终止。准入写入可追踪的 workload 状态,创建 Pod 前再次确认资源与策略仍有效,并通过配额利用率、等待时间、检查延迟、拒绝和撤销指标验证公平性与安全性。”
深入解答步骤
第一步:定义 Workload 与队列边界
把用户 Job 转换成可调度的 Workload,记录 PodSet、资源请求、优先级和租户队列。LocalQueue 只负责等待和排序;它不应直接创建 Pod 或绕过 ClusterQueue 的资源约束。
第二步:用 ClusterQueue 选择资源 flavor
ClusterQueue 按 ResourceGroup 描述 CPU、内存和 GPU 资源,并从 flavor 列表选择满足 nominal quota 的组合。将 GPU 型号、区域、节点标签和拓扑作为 flavor 约束,防止“数量够但硬件不匹配”的假准入。
第三步:编排 AdmissionCheck 状态机
每个检查都暴露 Pending、Ready、Rejected 或终止等可观察状态。安全扫描、维护窗口和预算控制器应使用幂等 workload UID 更新状态;Kueue 只有在所有必需检查 Ready 后才准入。Pending 不应被误写成失败,Rejected 也不能被调度器静默忽略。
第四步:处理部分准入与资源变化
若平台允许部分准入,要明确 PodSet 可减少的并行度、最小规模和后续扩容规则。资源释放或节点失效时重新评估 flavor 和检查状态;不能继续使用过期的准入快照。对于不可满足的请求,提供可解释的原因而不是无限重试。
第五步:保证公平、配额与防饥饿
按租户、队列和优先级定义 cohort 共享配额与借用边界。限制高优先级作业长期占满稀缺 GPU,为低优先级队列设置等待或老化策略。把配额分配、检查等待和实际 Pod 启动分开观测,才能发现“准入很快但节点启动很慢”的假成功。
第六步:设计撤销、重试和审计
检查控制器超时或失败时,采用带抖动的退避并限制重试次数。准入撤销必须触发 Workload 和 PodSet 的安全处置,不能只修改一个状态字段。记录状态变更者、时间、原因、资源 flavor、配额版本和外部检查版本,支持重放和追责。
第七步:验证可观测性与故障演练
监控排队等待、准入延迟、各检查 Pending 时长、拒绝率、撤销数、quota 利用率、flavor 命中、GPU 空闲和 Pod 启动延迟。演练检查控制器宕机、重复回调、配额回收、节点故障和网络分区,确认不会错误放行或永久卡死。
高质量示例回答
我会让 Workload 先进入 LocalQueue,ClusterQueue 根据资源组、flavor 和 cohort 配额选择可行资源;AdmissionCheck 控制外部安全、维护和预算条件。只有所有必需检查为 Ready 且资源快照仍有效时才准入并创建 Pod。Pending 继续排队,Rejected 或超时使用有限退避。
GPU 型号、拓扑和区域写入 flavor,避免只看数量。按租户设置共享配额和老化策略,监控等待、检查延迟、拒绝、撤销、利用率与启动延迟。控制器回调必须幂等,撤销要能安全传播到 Workload 和 PodSet。
常见错误
- 错误: Workload 入队就等于 Pod 已获准创建。→ 原因: 排队与准入是不同状态。→ 改进: 只让 ClusterQueue 和全部检查 Ready 触发准入。
- 错误: 只按 GPU 数量选择资源。→ 原因: 型号、显存、拓扑或区域可能不匹配。→ 改进: 用 ResourceFlavor 表达硬件约束。
- 错误: Pending 检查超时就无限重试。→ 原因: 可能掩盖永久不可满足或控制器故障。→ 改进: 区分 Pending、Rejected 和不可满足原因,使用上限与退避。
- 错误: 撤销只改 Workload 状态,不处理 Pod。→ 原因: 已运行的 Pod 可能继续消耗或访问资源。→ 改进: 定义 PodSet 处置、审计和回滚流程。
追问与回答
追问 1:AdmissionCheck 与 Kubernetes Admission Webhook 有什么区别?
AdmissionCheck 是 Kueue Workload 是否可开始的业务准入状态,允许外部控制器参与批作业队列;Webhook 是 API 请求层的准入扩展。两者可以协作,但不能把 Webhook 通过就当成资源已分配。
追问 2:为什么需要 ResourceFlavor?
同一资源数量可能来自不同 GPU 型号、区域或节点拓扑。Flavor 把这些可调度属性和资源组配额绑定,让选择过程可解释并避免错误放行。
追问 3:如何防止检查控制器重复回调造成状态倒退?
以 Workload UID、检查名和版本作为幂等键,拒绝旧版本覆盖新状态;记录资源版本和更新时间,并让重复 Ready 更新不触发第二次 Pod 创建。
追问 4:什么时候应该拒绝而不是继续等待?
当请求永远不可能满足资源 flavor、策略或预算条件时应明确拒绝并给出原因。短暂节点不足、维护窗口或控制器重试则适合 Pending,但必须有最大等待时间和告警。