Kueue 是一个针对 Kubernetes 集群设计的作业队列系统,它旨在解决在大规模环境中运行批处理工作负载时遇到的资源管理和调度问题。Kubernetes 原生的 Job 控制器和调度器在处理大规模作业时存在一些限制,比如无法有效控制作业的启动顺序、资源分配不均等,以及缺乏对异构资源和自动扩缩容环境的支持。
Kueue 的设计目标和工作原理如下:
- 不复制 Kubernetes 组件:Kueue 不会替换 Kubernetes 中已有的稳定组件,如 kube-scheduler 或 Job 控制器,而是在它们的基础上增加新功能。
- 扩展 Job API:Kueue 对 Job API 进行了扩展,以支持更多用例,例如 IndexedJob,并解决与 Pod 跟踪相关的长期问题。
- 兼容云环境:Kueue 确保与云环境中的弹性和异构计算资源兼容,这在云环境中尤为重要,因为资源的供应模式和架构可能各不相同。
- 控制 Job 启动:Kueue 通过引入两个新特性来控制 Job 的启动:
- Suspend 字段:允许 Kueue 在 Job 启动或停止时向 Job 控制器发出信号。
- 可变调度指令:允许在启动 Job 之前更新 Job 的 .spec.template.spec.nodeSelector,这样 Kueue 就可以控制 Pod 的放置,同时将实际的 Pod 到节点的调度工作委托给 kube-scheduler。
- 资源模型:Kueue 采用一种资源模型,该模型允许对作业进行排队,决定哪些作业应该等待,哪些可以立即启动,以及它们可以使用哪些资源。这种模型支持配额和预算控制,确保租户之间公平共享资源,并允许在不同资源类型之间灵活放置作业。
总的来说,Kueue 旨在提供一个更加灵活和高效的作业队列解决方案,以满足大规模 Kubernetes 环境中对作业调度和管理的需求。通过扩展现有的 Kubernetes 组件和 API,Kueue 能够提供更好的资源控制、公平性以及对异构和可伸缩环境的支持。
资源模型
Kueue 定义了新的 API 来解决本文开头提到的需求。三个主要的 API 是:
ResourceFlavor:一个集群范围的 API,用于定义可供消费的资源模板,如 GPU 模型。 ResourceFlavor 的核心是一组标签,这些标签反映了提供这些资源的节点上的标签。
ClusterQueue: 一种集群范围的 API,通过为一个或多个 ResourceFlavor 设置配额来定义资源池。
LocalQueue: 用于分组和管理单租户 Jobs 的命名空间 API。 在最简单的形式中,LocalQueue 是指向集群队列的指针,租户(建模为命名空间)可以使用它来启动他们的 Jobs。
使用用例
在这个场景中,作为批处理系统的管理员,你将使用 Kueue 来定义和管理你的作业队列。以下是如何定义和使用 ResourceFlavor 来满足你的需求的步骤:
定义 ResourceFlavor:
首先,你需要定义两个 ResourceFlavor 对象,每个对象代表一种类型的节点组。
对于按需节点组(instance-type=ondemand),你将创建一个 ResourceFlavor,它具有适当的标签,例如 ondemand=true,并且指定它能够提供的最大核心数为 1000。
对于即用节点组(instance-type=spot),你将创建另一个 ResourceFlavor,它具有 spot=true 标签,并且指定它能够提供的最大核心数为 2000。
设置 ClusterQueue:
接下来,你将创建一个或多个 ClusterQueue 对象,为不同的作业类型或租户设置资源配额。
在 ClusterQueue 中,你可以为每个 ResourceFlavor 设置配额限制。例如,你可以为按需节点设置 1000 核心的配额,为即用节点设置 2000 核心的配额。
配置 LocalQueue:
对于每个租户或作业类型,你可以创建 LocalQueue 对象,这些对象指向相应的 ClusterQueue。
在 LocalQueue 中,你可以设置作业的调度偏好,例如,某些作业可能需要容忍即用节点,而其他作业则不能。
管理作业调度:
当作业提交时,Kueue 将根据 LocalQueue 中的设置和 ClusterQueue 中的配额来调度作业。
如果作业需要在即用节点上运行,Kueue 将检查作业的容忍度和即用节点的可用性,然后根据 ResourceFlavor 的定义和 ClusterQueue 的配额来调度作业。
监控和调整:
作为管理员,你需要监控作业的执行情况和资源的使用情况。
根据作业的执行情况和资源的实际使用情况,你可能需要调整 ResourceFlavor 的定义或 ClusterQueue 的配额设置,以优化成本和资源利用率。
通过这种方式,Kueue 可以帮助你在云上的 Kubernetes 集群上有效地管理批处理工作负载,同时平衡成本和资源可用性。通过精细的资源管理和调度策略,你可以确保作业在最合适的节点上运行,同时遵守资源使用的限制。
定义了两个 ResourceFlavor
---
apiVersion: kueue.x-k8s.io/v1alpha2
kind: ResourceFlavor
metadata:
name: ondemand
labels:
instance-type: ondemand
---
apiVersion: kueue.x-k8s.io/v1alpha2
kind: ResourceFlavor
metadata:
name: spot
labels:
instance-type: spot
taints:
- effect: NoSchedule
key: spot
value: "true"
然后通过创建 ClusterQueue 来定义配额,如下所示:
apiVersion: kueue.x-k8s.io/v1alpha2
kind: ClusterQueue
metadata:
name: research-pool
spec:
namespaceSelector: {}
resources:
- name: "cpu"
flavors:
- name: ondemand
quota:
min: 1000
- name: spot
quota:
min: 2000
对于每个命名空间,定义一个指向上述 ClusterQueue 的 LocalQueue:
apiVersion: kueue.x-k8s.io/v1alpha2
kind: LocalQueue
metadata:
name: training
namespace: team-ml
spec:
clusterQueue: research-pool
要提交作业,需要创建一个 Job 并设置 kueue.x-k8s.io/queue-name
注解,如下所示:
apiVersion: batch/v1
kind: Job
metadata:
generateName: sample-job-
annotations:
kueue.x-k8s.io/queue-name: training
spec:
parallelism: 3
completions: 3
template:
spec:
tolerations:
- key: spot
operator: "Exists"
effect: "NoSchedule"
containers:
- name: example-batch-workload
image: registry.example/batch/calculate-pi:3.14
args: ["30s"]
resources:
requests:
cpu: 1
restartPolicy: Never
Kueue 在创建 Job 后立即进行干预以暂停 Job。 一旦 Job 位于 ClusterQueue 的头部,Kueue 就会通过检查 Job 请求的资源是否符合可用配额来评估它是否可以启动。