返回归档
📀Kubernetes

Kueue

Kueue 只决定 Job 何时解挂,不调度 Pod。

文章目录

Kueue 的核心原理

Kueue(Kubernetes-native Job Queueing)是一个轻量级、原生 Kubernetes 的批处理作业排队系统,其设计哲学非常明确:

  1. 不重复造轮子(核心原则):

    Kueue 不替换 kube-scheduler、kube-controller-manager 或 cluster-autoscaler 等成熟组件。它只在作业准入(admission)这一层介入,控制整个 Job 是否可以开始创建 Pod,后续 Pod 调度、节点分配、自动扩缩容全部交给 Kubernetes 原生组件。

  2. 以 Workload 为原子单位

    把一个完整的批处理任务(Job、RayJob、JobSet、MPIJob 等)视为一个不可分割的单元(Workload),实现 All-or-Nothing / Gang 调度,避免“部分 Pod 起来,剩下卡住”的资源浪费。

  3. 多租户公平配额 + 弹性借用

    通过 ClusterQueue(集群级配额) + Cohort(共享联盟)实现多团队/多项目间的名义配额(nominal quota) + 借用(borrowing) + 抢占(preemption) + 公平分享(fair sharing)

  4. 准入控制(Admission)而非实时调度

    Kueue 决定“什么时候让 Job 从 suspend 状态解挂”,而不是决定 Pod 放哪个节点。解挂后 kube-scheduler 正常接管。

一句话总结原理:

Kueue 是 Kubernetes 批处理作业的“门卫 + 配额管理员”:它在 Job 创建后立即 suspend 它,把它包装成 Workload 放进队列,根据配额、优先级、公平策略决定何时准入(admit),准入后解除 suspend,让 kube-scheduler 正常调度 Pod。

Workload 从提交到运行的完整流程

  1. 用户提交 Job

    用户创建 Kubernetes 原生 Job(或 RayJob 等),在 annotation 中指定 kueue.x-k8s.io/queue-name: my-local-queue

  2. Admission Webhook 拦截

    Kueue 的 MutatingAdmissionWebhook 立即把 Job 的 .spec.suspend = true(挂起,不创建 Pod)

  3. 创建 Workload 对象

    Kueue 的 controller 监听到 Job,自动创建一个对应的 Workload CR(这是 Kueue 内部的统一抽象对象)

  4. Workload 进入 LocalQueue

    根据 annotation 中的 queue-name,Workload 被放入对应 LocalQueue(命名空间级队列)

  5. LocalQueue → ClusterQueue

    LocalQueue 引用一个 ClusterQueue(集群级配额池)。Workload 被推送到 ClusterQueue 的待调度队列中。

  6. 排队 & 排序

    ClusterQueue 根据配置的 queueingStrategy(StrictFIFO / BestEffortFIFO) + priority 对 pending Workload 排序。

    同时评估 preemption(是否需要抢占低优先级运行中 Workload)。

  7. 配额检查 & Flavor 匹配

    Kueue 检查当前 ClusterQueue 的可用 quota(nominal + borrowing from cohort)。

    尝试按 flavors 顺序匹配(on-demand 先,spot 后),看是否能 fit 整个 Workload。

  8. Admission Checks(可选扩展)

    如果 ClusterQueue 配置了 AdmissionCheck(如 Provisioning、Topology 等),Kueue 等待这些 check 都 Ready。

  9. 准入(Admit)

    • 如果 quota 够 → Workload 状态变为 Admitted
    • Kueue 更新原 Job 的 .spec.suspend = false(解挂)
    • 注入 pod template 的 nodeSelector / affinity / taints(基于 Flavor)
    • 标记 quota 已消耗(reservation)
  10. Pod 创建 & kube-scheduler 接管

    Job controller 看到 suspend=false,开始创建 Pod

    kube-scheduler 正常调度 Pod 到节点(可能触发 cluster-autoscaler 扩容)

  11. 运行中监控 & 回收

    Workload 运行完成 → quota 释放,可被其他 Workload 借用

    如果优先级更高的新 Workload 需要资源 → 可 preempt(suspend 并删除 Pod)

  12. 失败/超时/用户删除 → Workload 被清理,quota 释放

Job → MutatingWebhook (suspend=true) → Workload → LocalQueue / ClusterQueue → Admit (suspend=false) → kube-scheduler

Job 一进来就被 MutatingWebhook 挂上 suspend=true。Controller 包成 Workload,进 LocalQueue,配额记在 ClusterQueue(Cohort 只是可选借用)。配额够了 Admit 把 suspend 翻回去,Pod 才交给 kube-scheduler。Kueue 是门卫,不是调度器。

关键组件总结

  • CRDs:ClusterQueue、LocalQueue、Cohort、Workload
  • Webhook:Mutating(suspend + 注入)、Validating(可选)
  • Controllers:Workload reconciler、Queueing reconciler、Admission controller
  • 不包含:Pod 调度(kube-scheduler)、节点管理(kubelet)、自动扩容(cluster-autoscaler)

这个架构让 Kueue 非常(thin),部署简单,侵入性低,但功能强大,尤其适合 AI 训练、多租户 GPU 共享、HPC 等场景。