k8s之kueue详细解析

Kubernetes 批处理调度框架 Kueue 核心资源与高级特性深度解析

一、核心资源对象体系

1. ResourceFlavor(资源规格)

定义:描述集群中可用的异构资源类型,通过标签/污点机制与物理节点建立映射关系

核心功能

  • 资源类型标记:区分不同特性的计算资源(如 CPU/GPU、按需/Spot 实例)
  • 调度约束管理:通过污点机制控制资源使用权限
  • 动态资源适配:自动注入节点选择器到工作负载

关键配置属性

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "gpu-a100"
spec:
  nodeLabels:          # 节点标识标签
    accelerator: nvidia-a100
  nodeTaints:          # 资源访问控制
  - key: gpu-tier
    value: premium
    effect: NoSchedule
  tolerations:         # 自动注入的污点容忍
  - key: "gpu-tier"
    operator: "Exists"
    effect: "NoSchedule"

版本兼容性

  • Kubernetes ≥1.23 支持标签动态注入
  • v1beta1 API 版本需配合 Kueue 0.6.0+ 使用
  • 污点容忍自动注入要求启用 MutatingWebhook

校验机制

func ValidateWorkload(workload *Workload) error {
    for _, flavor := range GetClusterFlavors() {
        if !CheckTolerations(workload, flavor.Tolerations) {
            return ErrIncompatibleTaint
        }
        if !CheckNodeAffinity(workload, flavor.NodeLabels) {
            return ErrNodeSelectorMismatch
        }
    }
    return nil
}
2. ClusterQueue(集群队列)

资源池化模型:定义跨命名空间的全局资源配额池,支持多级资源借用策略

架构设计

ClusterQueue 资源模型
+-----------------------+
|  ResourceGroup         |
|  - coveredResources    |
|  +-------------------+ |
|  | Flavor            | |
|  | - nominalQuota    | |  -> 静态配额
|  | - borrowingLimit  | |  -> 跨队列借用上限
|  | - lendingLimit    | |  -> 资源出借上限(Alpha)
+-----------------------+

高级配置参数

apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: "ai-training"
spec:
  namespaceSelector:    # 命名空间过滤
    matchLabels:
      env: production
  queueingStrategy: "BestEffortFIFO"  # 队列策略
  cohort: "gpu-cluster"  # 资源联盟组
  preemption:           # 抢占策略三要素
    reclaimWithinCohort: 
      policy: LowerPriority
    borrowWithinCohort:
      policy: Any
      maxPriorityThreshold: 200
    withinClusterQueue: LowerOrNewerEqualPriority
  flavorFungibility:    # 规格降级策略
    whenCanBorrow: TryNextFlavor
    whenCanPreempt: Preempt
  stopPolicy: HoldAndDrain  # 队列停止策略

队列策略对比

策略类型调度特点适用场景
StrictFIFO严格顺序执行,可能产生队头阻塞作业依赖性强,需顺序执行
BestEffortFIFO跳过不可调度作业,资源利用率高异构作业混合场景

资源借用规则

  1. 借用总量 ≤ nominalQuota + borrowingLimit
  2. 仅限同 Cohort 内 ClusterQueue 间借用
  3. 单作业只能借用单一 Flavor 资源
  4. 借入方优先级高于贷出方时可触发抢占
3. LocalQueue(本地队列)

租户隔离机制:命名空间维度的虚拟队列,实现资源配额二次分配

配置示例

apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: ml-team-a
  name: high-prio-queue
spec:
  clusterQueue: "ai-training"  # 绑定集群队列
  priority: 
    className: "critical-job"  # 自定义优先级类
    value: 1000

运行特征

  • 单 LocalQueue 只能绑定一个 ClusterQueue
  • 支持跨命名空间资源共享(需 ClusterQueue 开放访问)
  • 优先级可覆盖 ClusterQueue 全局设置
4. Workload(工作负载)

单元化设计:Kubernetes 原生 Job 的增强抽象,支持多框架集成

优先级继承模型

Job/Pod PriorityClass
是否定义
WorkloadPriorityClass?
使用 Workload 优先级
继承 Pod 优先级
影响队列调度顺序
实际节点调度

多框架支持

apiVersion: kubeflow.org/v1
kind: TFJob
metadata:
  annotations:
    kueue.x-k8s.io/queue-name: "ml-queue"
spec:
  tfReplicaSpecs:
    Worker:
      replicas: 4
      template:
        spec:
          containers:
          - name: tensorflow
            resources:
              requests:
                cpu: 8
                memory: 32Gi
                nvidia.com/gpu: 1

状态流转机制

Workload 生命周期
Created → Pending → Admitted → Running 
                   → Inadmissible (资源不足)
                   → Preempted (被抢占)
                   → Evicted (手动驱逐)

二、高级调度策略解析

1. 多维度抢占机制

三级抢占策略

  1. 队列内抢占(withinClusterQueue)

    • 策略类型:LowerPriority / LowerOrNewerEqualPriority
    • 触发条件:新作业优先级 ≥ 运行中作业优先级 + 阈值
  2. Cohort 内回收(reclaimWithinCohort)

    • 回收模式:
      func ShouldReclaim(resource *Resource, borrower *Workload) bool {
          if currentUsage > nominalQuota && 
             borrower.Priority < current.Priority {
              return true
          }
          return false
      }
      
  3. 跨队列抢占(borrowWithinCohort)

    • 需开启 reclaimWithinCohort
    • 水位线控制:maxPriorityThreshold

抢占执行流程

  1. 检查目标作业的 PreemptionPolicy
  2. 计算可释放资源量
  3. 按优先级逆序选择牺牲者
  4. 驱逐选定 Pod 并回收资源
  5. 重试目标作业调度
2. 资源弹性伸缩

与 Cluster Autoscaler 集成

弹性扩缩流程:
1. Kueue 检测到待调度作业
2. 计算所需节点类型及数量
3. 通过 Annotation 标记未调度 Pod
4. Cluster Autoscaler 识别需求并扩容
5. 节点就绪后触发 Pod 调度

弹性配置最佳实践

apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
spec:
  resourceGroups:
  - flavors:
    - name: spot
      resources:
      - name: "cpu"
        nominalQuota: 100
        borrowingLimit: 500  # 允许突发借用
    - name: ondemand
      resources:
      - name: "cpu"
        nominalQuota: 200
        lendingLimit: 100    # 控制资源外借量
3. 拓扑感知调度

NUMA 亲和性优化

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: numa-node-0
spec:
  nodeLabels:
    topology.kubernetes.io/zone: zone-a
    numa-node: "0"
---
apiVersion: batch/v1
kind: Job
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: numa-node
                operator: In
                values: ["0"]

调度优化效果

  • 减少跨 NUMA 内存访问延迟
  • 提升 GPU 间 NVLINK 带宽利用率
  • 降低网络层跳跃(Hops)

三、生产环境实践指南

1. 多租户配额规划

配额分配矩阵

租户团队GPU QuotaCPU Quota优先级资源类型偏好
ML-Prod40 A100400 Cores1000OnDemand (80%)
Research20 V100200 Cores500Spot (70%)
CI/CD0100 Cores300Preemptible (90%)

对应 ClusterQueue 配置

apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: ml-prod-pool
spec:
  resourceGroups:
  - coveredResources: ["nvidia.com/gpu", "cpu"]
    flavors:
    - name: a100-ondemand
      resources:
      - name: "nvidia.com/gpu"
        nominalQuota: 32   # 80% of 40
        borrowingLimit: 8
      - name: "cpu"
        nominalQuota: 320
    - name: a100-spot
      resources:
      - name: "nvidia.com/gpu"
        nominalQuota: 8
2. 监控与可观测性

关键 Prometheus 指标

kueue_clusterqueue_usage{resource="cpu",flavor="spot"} 750
kueue_clusterqueue_borrowing{resource="gpu"} 12
kueue_workload_preemption_count{clusterqueue="ml-prod"} 5
kueue_scheduling_delay_seconds{quantile="0.99"} 12.7

Grafana 看板配置要点

  • 队列深度趋势图
  • 资源借用率环形图
  • 调度延迟热力图
  • 抢占事件流监控
3. 灾备与优雅降级

多集群容灾方案

MultiKueue 架构:
[Cluster A] ←→ [Central Kueue] ←→ [Cluster B]
                   ↑
                [Backup Cluster]

降级策略配置

apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
spec:
  stopPolicy: Hold  # 停止接受新作业但不驱逐运行中任务
  flavorFungibility:
    whenCanPreempt: TryNextFlavor  # 优先尝试降级而非抢占

四、简单使用实例

  • 定义 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 的配额设置,以优化成本和资源利用率。
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

LocalQueue

对于每个命名空间,定义一个指向上述 ClusterQueue 的 LocalQueue:

apiVersion: kueue.x-k8s.io/v1alpha2
kind: LocalQueue
metadata:
  name: training
  namespace: team-ml
spec:
  clusterQueue: research-pool

Job

要提交作业,需要创建一个 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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值