抢占

抢占是指驱逐一个或多个已准入的工作负载以容纳另一个工作负载的过程。

在抢占中,以下术语是相关的

  • 被抢占者:被抢占的工作负载。
  • 目标 ClusterQueue:被抢占者所属的 ClusterQueue。
  • 抢占者:正在容纳的工作负载。
  • 抢占 ClusterQueue:抢占方所属的 ClusterQueue。

抢占原因

如果工作负载在启用了抢占的 ClusterQueue 中被接纳,并且发生了以下任何事件,则该工作负载可以抢占一个或多个工作负载

  • 被抢占方属于与抢占方相同的 ClusterQueue,并且被抢占方的优先级较低。
  • 被抢占方属于与抢占方相同的 队列,并且被抢占方的 ClusterQueue 对被抢占方和抢占方所需至少一种资源的使用量高于 标称配额

除了上述条件之外,Kueue 配置ClusterQueue 中针对抢占配置的设置可以限制工作负载是否可以抢占其他工作负载。

在抢占工作负载时,Kueue 会在被抢占工作负载的 .status.conditions 字段中添加类似于以下内容的条目

status:
  conditions:
  - lastTransitionTime: "2024-05-31T18:42:33Z"
    message: 'Preempted to accommodate a workload (UID: 5515f7da-d2ea-4851-9e9c-6b8b3333734d)
      in the ClusterQueue'
    observedGeneration: 1
    reason: Preempted
    status: "True"
    type: Evicted
  - lastTransitionTime: "2024-05-31T18:42:33Z"
    message: 'Preempted to accommodate a workload (UID: 5515f7da-d2ea-4851-9e9c-6b8b3333734d)
      in the ClusterQueue'
    reason: InClusterQueue
    status: "True"
    type: Preempted

Evicted 条件表示工作负载因 Preempted 原因而被驱逐,而 Preempted 条件则提供了有关抢占原因的更多详细信息。

抢占算法

Kueue 提供两种抢占算法。它们之间的主要区别在于允许从一个 ClusterQueue 抢占队列中的其他 ClusterQueue 的条件,当抢占 ClusterQueue 的使用量已经高于标称配额时。算法如下

  • 经典抢占:队列中的抢占仅在以下情况下发生:抢占 ClusterQueue 的使用量在正在进行的接纳流程后将低于标称配额,或者所有抢占候选者都属于与抢占工作负载相同的 ClusterQueue。换句话说,ClusterQueue 只能从队列中的其他 ClusterQueue 借用配额,如果它们不会抢占其他 ClusterQueue 中已接纳的工作负载。队列中的 ClusterQueue 以先到先得的方式借用资源。此算法是两者中最轻量级的。
  • 公平共享:具有待处理工作负载的 ClusterQueues 可以抢占其队列中的其他工作负载,直到抢占的 ClusterQueue 获得可借用资源的相等或加权份额。可借用资源是队列中所有 ClusterQueues 的未用标称配额。

经典抢占

不符合未用配额的工作负载在以下情况之一为真时有资格发出抢占

  • 工作负载的请求低于风味的标称配额,或
  • borrowWithinCohort 已启用。

候选

抢占候选列表是从满足 withinClusterQueue 策略的 Cluster Queue 中的工作负载以及满足 reclaimWithinCohort 策略的队列中的工作负载中编译的。

候选列表根据以下优先级检查进行排序,以进行平局打破

  • 队列中借用队列的工作负载
  • 优先级最低的工作负载
  • 最近被录取的工作负载。

目标

经典抢占算法使用以下启发式方法将候选者限定为抢占目标

  1. 如果所有候选者都属于目标队列,则 Kueue 贪婪地限定候选者,直到抢占的工作负载能够适应,允许 ClusterQueue 的使用高于标称配额,直到 borrowingLimit。这在以下几点中称为“借用”。

  2. 如果启用了 borrowWithinCohort,则 Kueue 会贪婪地筛选候选者(遵循 borrowWithinCohort.maxPriorityThreshold 阈值),直到抢占工作负载可以适应,允许借用。

  3. 如果目标队列的当前使用量低于标称配额,则 Kueue 会贪婪地筛选候选者,直到抢占工作负载可以适应,不允许借用。

  4. 如果工作负载无法使用之前的启发式方法适应,则 Kueue 会贪婪地筛选仅属于抢占集群队列的候选者,直到抢占工作负载可以适应,允许借用。

该算法的最后一步是最小化目标集。为此,Kueue 会贪婪地反向遍历初始目标列表,如果在计算目标工作负载的配额使用量时,抢占工作负载仍然可以被接纳,则从目标列表中移除一个工作负载。

公平共享

功能状态自 Kueue v0.7 起稳定

要启用公平共享,使用类似于以下内容的 Kueue 配置

apiVersion: config.kueue.x-k8s.io/v1beta1
kind: Configuration
fairSharing:
  enable: true
  preemptionStrategies: [LessThanOrEqualToFinalShare, LessThanInitialShare]

本 Kueue 配置中的属性在以下部分中进行了说明。

ClusterQueue 共享值

启用公平共享时,Kueue 会为每个 ClusterQueue 分配一个数字共享值,以总结 ClusterQueue 中借用资源的使用情况,与同一队列中的其他资源相比。共享值由 ClusterQueue 中定义的 .spec.fairSharing.weight 加权。

在接纳期间,Kueue 优先接纳来自共享值最低的 ClusterQueue 的工作负载。在抢占期间,Kueue 优先抢占来自共享值最高的 ClusterQueue 的工作负载。

你可以在 .status.fairSharing.weightedShare 字段中获取 ClusterQueue 的共享值,或查询 kueue_cluster_queue_weighted_share 指标

抢占策略

队列配置中的 preemptionStrategies 字段指示抢占在抢占特定工作负载之前和之后应满足哪些约束,具体取决于目标和抢占集群队列的份额值。

不同的 preemptionStrategies 可能会在特定场景下导致抢占次数减少或增加。在配置 preemptionStrategies 时,您应考虑以下因素

  • 对中断的容忍度,特别是当单个工作负载使用大量可借用资源时。
  • 收敛速度,换句话说,尽快达到稳定的公平状态有多重要。
  • 总体利用率,因为某些策略可能会降低集群的利用率以追求公平性。

当您定义多个 preemptionStrategies 时,抢占算法只有在没有更多满足当前策略的候选抢占工作负载且抢占者仍不合适时,才会使用列表中的下一个策略。

您可以在 preemptionStrategies 列表中设置的值为

  • LessThanOrEqualToFinalShare:仅在抢占集群队列的份额(包含抢占者工作负载)小于或等于目标集群队列的份额(不包含被抢占工作负载)时才抢占工作负载。此策略可能会优先抢占目标集群队列中较小的工作负载,而不管优先级或开始时间如何,目的是尽可能保持集群队列的份额。
  • LessThanInitialShare:仅在抢占集群队列的份额(包含抢占者工作负载)严格小于目标集群队列的份额时才抢占工作负载。请注意,此策略不依赖于被抢占工作负载的份额使用情况。因此,该策略选择首先抢占目标集群队列中优先级最低且开始时间最新的工作负载。默认策略为 [LessThanOrEqualToFinalShare, LessThanInitialShare]

算法概述

算法的初始步骤是识别候选抢占工作负载,其标准和顺序与经典抢占相同,并按集群队列分组。

接下来,按照可总结为以下内容的算法,上述候选者有资格作为抢占目标

FindFairPreemptionTargets(X ClusterQueue, W Workload)
  For each preemption strategy:
    While W does not fit and there are workloads that are preemption candidates:
      Find the ClusterQueue Y with the highest share value.
      For each admitted Workload U in ClusterQueue Y:
        If Workload U satisfies the preemption strategy:
          Add workload U to the list of targets
  In the reverse order of the list of targets:
    Attempt to remove a Workload from the targets, while W still fits.