Kueue 是 Kubernetes 原生的批调度队列系统,专为管理批量工作负载的资源分配而设计。它通过三个核心概念——ResourceFlavor、ClusterQueue 和 LocalQueue——构建了一个多层次、灵活的资源管理体系。本文将深入解析这三个组件的功能、关联关系以及它们如何协同工作。
ResourceFlavor 是 Kueue 中资源类型的抽象描述,它定义了计算节点的特性和约束条件,相当于为集群中的资源打上分类标签。
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: gpu-a100
spec:
nodeLabels:
gpu-type: a100 # 匹配节点标签
nodeTaints:
- key: gpu # 定义节点污点
value: "true"
effect: NoSchedule
tolerations: # 自动添加的容忍度
- key: gpu
operator: Equal
value: "true"
effect: NoSchedule
nodeLabels
关联特定节点nodeTaints
限制资源使用版本注意:使用节点标签匹配需要 Kubernetes 1.23+
ClusterQueue 是 Kueue 的核心资源池概念,它定义了:
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: ai-training
spec:
namespaceSelector: # 命名空间选择器
matchLabels:
team: ai
resourceGroups:
- coveredResources: ["cpu", "memory", "nvidia.com/gpu"]
flavors:
- name: "gpu-a100" # 引用 ResourceFlavor
resources:
- name: "nvidia.com/gpu"
nominalQuota: 8 # 基准配额
borrowingLimit: 4 # 最大可借用量
queueingStrategy: BestEffortFIFO
cohort: ai-cluster # 队列集团
字段 | 说明 |
---|---|
nominalQuota |
基准配额,保障性资源量 |
borrowingLimit |
可借用其他队列的资源上限 |
lendingLimit |
可借出给其他队列的资源量 |
queueingStrategy:
StrictFIFO
:严格先进先出,可能阻塞BestEffortFIFO
:尽力而为,提高利用率cohort:
spec:
preemption:
reclaimWithinCohort: LowerPriority
borrowWithinCohort:
policy: LowerPriority
maxPriorityThreshold: 100
withinClusterQueue: LowerOrNewerEqualPriority
ClusterQueue
必须绑定 ResourceFlavor
才能正常工作ClusterQueue
必须绑定 ResourceFlavor
才能正常工作,不能完全独立使用。这是由 Kueue 的资源管理模型决定的,但具体约束的严格程度取决于配置方式。以下是详细说明:ClusterQueue
的核心功能是 管理资源配额,而配额必须关联到具体的资源类型(即 ResourceFlavor
)。这是因为:
ResourceFlavor
的配额是分开管理的(例如:队列可以同时有 cpu-flavor
和 gpu-flavor
的独立配额)。虽然必须绑定 ResourceFlavor
,但可以通过以下方式灵活配置:
如果集群只有一种通用资源类型,可以创建一个空的 ResourceFlavor
(如你提供的示例),作为默认资源池:
# 空 ResourceFlavor(逻辑分组)
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: default-flavor
spec: {} # 无特殊属性
然后在 ClusterQueue
中引用它:
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: default-queue
spec:
resourceGroups:
- coveredResources: ["cpu", "memory"] # 管理的资源类型
flavors:
- name: "default-flavor" # 绑定空 ResourceFlavor
resources:
- name: "cpu"
nominalQuota: 100
- name: "memory"
nominalQuota: 100Gi
对于复杂场景,可以绑定多个 ResourceFlavor
:
spec:
resourceGroups:
- coveredResources: ["cpu", "nvidia.com/gpu"]
flavors:
- name: "gpu-flavor" # 高优先级 GPU 资源
resources:
- name: "nvidia.com/gpu"
nominalQuota: 8
- name: "default-flavor" # 普通 CPU
resources:
- name: "cpu"
nominalQuota: 50
ClusterQueue
时会报错:Kueue 的校验逻辑会要求 spec.resourceGroups.flavors
至少包含一个有效的 ResourceFlavor
。ClusterQueue
创建成功,没有关联的 ResourceFlavor
会导致工作负载找不到可用资源。某些 Kueue 实现可能允许:
ResourceFlavor
(如果未显式指定)。ResourceFlavor
(例如通过控制器自动发现节点标签)。但这类行为依赖具体实现,并非标准特性。
ResourceFlavor
:即使只有一种资源类型,也明确声明。ResourceFlavor
作为兜底:如你的示例所示,可用于简单场景。ResourceFlavor
的 spec.nodeSelector
精确控制资源匹配。问题 | 答案 |
---|---|
ClusterQueue 能否单独使用? |
不能,必须至少绑定一个 ResourceFlavor (即使是空的逻辑分组)。 |
为什么需要绑定? | 资源配额必须关联到具体的资源类型(ResourceFlavor )。 |
如何简化配置? | 使用空的 ResourceFlavor 作为默认资源池。 |
这种设计确保了资源分配的明确性和可审计性,避免了模糊的全局默认值导致的调度冲突。
LocalQueue 是 ClusterQueue 在命名空间维度的映射,它:
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
namespace: ai-team-a
name: training-queue
spec:
clusterQueue: ai-training # 关联的 ClusterQueue
ResourceFlavor (资源类型定义)
↑
ClusterQueue (核心资源池)
↑
LocalQueue (命名空间接入点)
↑
Workload (用户任务)
资源定义阶段:
工作负载提交阶段:
apiVersion: kueue.x-k8s.io/v1beta1
kind: Workload
metadata:
namespace: ai-team-a
spec:
queueName: training-queue # 指定 LocalQueue
podSets:
- name: "trainer"
template:
spec:
containers:
- name: cuda
resources:
requests:
nvidia.com/gpu: 2
调度决策阶段:
ResourceFlavor 必须性:
命名空间隔离:
namespaceSelector
二次验证资源借用规则:
# 共享集群核心配置
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: shared-core
spec:
cohort: shared-pool
resourceGroups:
- coveredResources: ["cpu"]
flavors:
- name: "default"
resources:
- name: "cpu"
nominalQuota: 1000
lendingLimit: 500 # 允许借出50%资源
ResourceFlavor 设计:
ClusterQueue 规划:
StrictFIFO
保证公平性BestEffortFIFO
提高利用率LocalQueue 管理:
Q:能否绕过 LocalQueue 直接使用 ClusterQueue?
A:技术上可以,但会破坏多租户隔离,不建议在生产环境这样做。
Q:ResourceFlavor 必须对应实际的节点标签吗?
A:是的,nodeLabels
必须与节点上存在的标签匹配,否则无法调度。
Q:如何监控资源借用情况?
A:通过 Kueue 的 Metrics 或检查 ClusterQueue 状态中的 flavorUsage
字段。
通过这种三层架构,Kueue 实现了灵活而强大的资源管理能力,既能满足复杂的异构环境需求,又能保持清晰的权限和配额隔离。