1. 资源抢占的背景和用途
1.1 什么是资源抢占
在Kubernetes
集群中,资源抢占(Preemption
)是指当高优先级的工作负载需要资源但集群资源不足时,调度系统会终止低优先级的工作负载以释放资源,从而确保高优先级工作负载能够正常运行的机制。
资源抢占是解决资源竞争问题的关键技术,特别是在以下场景中尤为重要:
- 资源紧张环境:在计算资源有限的集群中,需要确保关键业务获得足够资源
- 混合负载场景:同一集群中同时运行在线服务和批处理作业时,需要保证在线服务的资源优先级
- 弹性计算:在需求波动较大的环境中,通过优先级机制实现资源的动态分配
- 多租户环境:在多用户共享集群的情况下,通过优先级和抢占机制实现资源隔离和公平分配
1.2 Kubernetes原生抢占机制的局限性
Kubernetes
原生的抢占机制主要基于Pod
级别的PriorityClass
实现,虽然提供了基本的资源抢占能力,但在复杂的高性能计算和AI/ML
工作负载场景中存在以下局限性:
-
层级抢占机制不完善:
- 虽然
Job
可以通过PriorityClass
设置优先级,但缺乏队列级别的资源管理 - 无法实现多层级、多维度的资源抢占策略
- 虽然
-
缺乏作业感知:
- 无法识别同一作业中不同
Pod
之间的关系 - 在资源紧张时可能导致
Gang
调度失败,造成资源碎片
- 无法识别同一作业中不同
-
抢占策略单一:
- 仅支持基于优先级的简单抢占
- 无法根据不同场景和业务需求定制复杂的抢占策略
-
多租户支持有限:
- 缺乏队列级资源保障和隔离机制
- 难以为不同部门或团队提供差异化的资源配额和服务质量保障
1.3 Volcano抢占机制的优势
Volcano
作为一个面向高性能计算和AI/ML
工作负载的调度系统,提供了更加完善的资源抢占机制:
- 多层级抢占:支持
Queue
(队列)、Job
(作业)和Pod
(容器组)三个层级的资源抢占 - 作业感知:理解批处理作业的特性,支持
Gang
调度等高级特性 - 丰富的抢占策略:提供多种可配置的抢占策略,满足不同场景需求
- 队列级资源管理:支持队列级别的资源分配和抢占,适合多租户环境
- 公平性保障:通过
DRF
(主导资源公平)算法等机制,确保资源分配的公平性
2. Volcano资源抢占的设计与实现
Volcano
的资源抢占机制设计为三个层级:Queue
(队列)、Job
(作业)和Pod
(容器组),形成了一个层级分明的抢占体系。
2.1 Queue级别抢占
2.1.1 设计原理
Queue
是Volcano
中最高层级的资源管理单位,代表一个租户或一个业务线。Queue
级别的抢占主要基于以下原则:
- 优先级机制:每个
Queue
可以设置优先级(priority
),高优先级Queue
可以抢占低优先级Queue
的资源 - 资源配额:
Queue
可以设置最小保障资源(guarantee
)和最大资源上限(capacity
) - 权重分配:当多个
Queue
优先级相同时,可以通过权重(weight
)决定资源分配比例
2.1.2 实现方式
Volcano
主要通过以下核心组件实现Queue
级别的资源抢占:
reclaim action
:资源回收动作,是实现不同队列间资源抢占的核心机制- 队列
priority
属性:在Queue
定义中设置的优先级值,决定了队列间的抢占顺序
下面是Volcano
调度器的配置示例,展示了资源抢占相关的动作:
# volcano-scheduler-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: volcano-scheduler-config
namespace: volcano-system
data:
volcano-scheduler.conf: |
# 调度器执行的动作序列,包含资源回收和抢占动作
actions: "enqueue, allocate, preempt, reclaim, backfill"
# 其他插件配置...
上述配置中,资源抢占相关的核心动作是:
-
reclaim
:实现不同队列间的资源抢占,高优先级队列可以从低优先级队列抢占资源apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: high-priority-queue
spec:
weight: 10
capability:
cpu: 100
memory: 100Gi
reclaimable: true # 允许其他Queue抢占此Queue的资源
priority: 100 # 队列优先级,值越大优先级越高
2.2 Job级别抢占
2.2.1 设计原理
Job
代表一个完整的工作单元,如一个AI
训练任务或批处理作业。Job
级别的抢占主要基于以下原则:
-
优先级机制:
Job
通过priorityClassName
字段关联到Kubernetes
的PriorityClass
资源- 高优先级
Job
可以抢占同一Queue
中低优先级Job
的资源 Job
的优先级会传递给其创建的所有Pod
,除非Pod
模板中明确指定了不同的priorityClassName
-
最小资源保障:
Job
可以设置minResources
确保获得最小资源保障- 结合
minAvailable
参数确保关键任务的资源需求
-
Gang调度:
- 支持
All-or-Nothing
的调度模式 - 确保作业所有关键任务同时调度,避免资源碎片化
- 支持
2.2.2 实现方式
Volcano
主要通过以下核心组件实现Job
级别的抢占:
preempt action
:资源抢占动作,是实现同一队列内不同作业间资源抢占的核心机制priorityClassName
:与Job
关联的优先级类,决定了作业间的抢占顺序
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: high-priority-job
spec:
minAvailable: 3
priorityClassName: high-priority # 关联PriorityClass设置作业优先级
queue: research # 指定所属队列
tasks:
- replicas: 3
name: worker
template:
spec:
containers:
- image: training-image
name: worker
2.3 Pod级别抢占
2.3.1 设计原理
Pod
是Kubernetes
中最小的调度单位,也是Volcano
调度的基本单位。Pod
级别的抢占主要基于以下原则:
- 优先级机制:
Pod
可以通过PriorityClass
或task-priority
注解设置优先级 - 可抢占性:
Pod
可以通过volcano.sh/preemptable
注解标记是否可被抢占 - 资源需求:
Pod
的资源请求(requests
)决定了需要多少资源
2.3.2 实现方式
Volcano
主要通过以下核心组件实现Pod
级别的抢占:
volcano.sh/task-priority
注解:设置同一Job
内不同Pod
的优先级,是实现Pod
间抢占的核心volcano.sh/preemptable
注解:标记Pod
是否可被抢占,控制Pod
的可抢占性PreemptionPolicy
:控制Pod
的抢占策略,可设置为PreemptLowerPriority
或Never
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
annotations:
volcano.sh/task-priority: "10" # 设置Pod在Job内的优先级
volcano.sh/preemptable: "false" # 标记Pod不可被抢占
spec:
priorityClassName: high-priority # 设置Pod的全局优先级
schedulerName: volcano # 使用Volcano调度器
3. 资源抢占的层级关系
在Volcano
的抢占体系中,Queue
、Job
和Pod
三个层级之间存在明确的优先级关系,形成了一个层级化的抢占机制。
3.1 Queue
与Queue
之间的抢占
当集群资源紧张时,Queue
之间的抢占遵循以下规则:
- 优先级决定性:高优先级
Queue
可以抢占低优先级Queue
的资源 - 权重影响:当优先级相同时,权重较高的
Queue
可以获得更多资源 - 最小保障:每个
Queue
的guarantee
资源是受保护的,不会被抢占 - 资源回收:当高优先级
Queue
不需要资源时,被抢占的Queue
可以重新获得资源
抢占过程:
Volcano
调度器检测到高优先级Queue
资源不足- 根据优先级和权重策略选择低优先级的
Queue
- 从低优先级
Queue
中选择可抢占的Job
和Pod
- 驱逐选中的
Pod
,释放资源给高优先级Queue
3.2 Job
与Job
之间的抢占
在同一Queue
内,Job
之间的抢占遵循以下规则:
- 优先级决定性:高优先级
Job
可以抢占低优先级Job
的资源 - 创建时间:当优先级相同时,通常先创建的
Job
优先级更高 - 最小资源:每个
Job
的minAvailable
资源需求会影响抢占决策 - Gang调度:支持
All-or-Nothing
的调度模式,确保作业完整性
抢占过程:
Volcano
检测到高优先级Job
资源不足- 根据
PriorityClass
和创建时间选择同一Queue
中优先级较低的Job
- 从低优先级
Job
中选择可抢占的Pod
- 驱逐选中的
Pod
,释放资源给高优先级Job
3.3 Pod
与Pod
之间的抢占
在同一Job
内,Pod
之间的抢占遵循以下规则:
- task-priority决定性:高
task-priority
的Pod
可以抢占低task-priority
的Pod
- 可抢占性:只有标记为可抢占(
preemptable=true
)的Pod
才能被抢占 - BestEffort限制:
BestEffort Pod
不能抢占非BestEffort Pod
- 状态限制:只有处于
Running
状态的Pod
才能被抢占
抢占过程:
Volcano
检测到高优先级Pod
无法调度- 根据任务优先级找到同一
Job
中优先级较低的Pod
- 检查
Pod
的可抢占性和其他约束条件 - 驱逐选中的
Pod
,释放资源给高优先级Pod
3.4 跨层级抢占的优先顺序
当涉及跨层级的资源抢占时,Volcano
遵循以下优先顺序:
- Queue优先级最高:不同
Queue
之间的优先级高于Queue
内部的Job
优先级 - Job优先级次之:同一
Queue
内不同Job
之间的优先级高于Job
内部的Pod
优先级 - Pod优先级最低:同一
Job
内不同Pod
之间的优先级最低
这意味着:
- 即使是低优先级
Queue
中的高优先级Job
,也会被高优先级Queue
中的低优先级Job
抢占 - 即使是低优先级
Job
中的高task-priority
Pod
,也会被高优先级Job
中的低task-priority
Pod
抢占
重要说明:要实现这种层级化的资源抢占机制,必须统一使用Volcano调度器。在所有需要参与这种资源管理的
Job
中指定schedulerName: volcano
。如果混用不同的调度器(如Kubernetes
默认调度器),将无法保证这种层级化的资源抢占机制正常工作,因为其他调度器不理解Queue
概念和层级关系。
4. 实际应用场景与最佳实践
4.1 多租户资源管理
在多租户环境中,可以为不同部门或团队创建独立的Queue
,通过优先级和资源配额实现资源隔离和保障:
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: production
spec:
weight: 20
capability:
cpu: 1000
memory: 2000Gi
guarantee:
cpu: 500
memory: 1000Gi
priority: 100
---
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: development
spec:
weight: 10
capability:
cpu: 500
memory: 1000Gi
priority: 50
4.2 关键业务保障
对于关键业务,可以设置高优先级和不可抢占属性,确保资源稳定性:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-service
value: 1000000
globalDefault: false
description: "Critical business services"
---
apiVersion: v1
kind: Pod
metadata:
name: critical-service-pod
annotations:
volcano.sh/preemptable: "false"
spec:
priorityClassName: critical-service
schedulerName: volcano
4.3 AI训练任务优化
对于AI
训练任务,可以通过Gang
调度和任务内部优先级优化资源利用:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: training-job
spec:
minAvailable: 4
priorityClassName: high-priority
queue: research
tasks:
- replicas: 1
name: ps
template:
metadata:
annotations:
volcano.sh/task-priority: "10" # 参数服务器优先级高
volcano.sh/preemptable: "false" # 参数服务器不可抢占
- replicas: 3
name: worker
template:
metadata:
annotations:
volcano.sh/task-priority: "5" # 工作节点优先级低
volcano.sh/preemptable: "true" # 工作节点可被抢占
4.4 混合负载管理
在同时运行在线服务和批处理作业的环境中,可以通过优先级和抢占机制实现资源平衡:
- 为在线服务创建高优先级
Queue
,设置适当的guarantee
资源 - 为批处理作业创建低优先级
Queue
,允许被抢占 - 对关键批处理作业设置较高的
Job
优先级,但低于在线服务Queue
的优先级
5. 总结
Volcano
的资源抢占设计提供了一个层级化、灵活且强大的资源管理机制,通过Queue
、Job
和Pod
三个层级的抢占关系,满足了复杂环境下的资源调度需求。
核心优势包括:
- 多层级抢占:支持从
Queue
到Pod
的完整抢占体系 - 灵活配置:提供丰富的配置选项,适应不同场景需求
- 公平性保障:通过多种算法确保资源分配的公平性
- 作业感知:理解批处理作业的特性,支持Gang调度等高级特性
- 多租户支持:为多租户环境提供资源隔离和保障机制
通过合理配置Volcano
的资源抢占机制,可以显著提高集群资源利用率,同时确保关键业务的资源保障,为AI训练、高性能计算和混合负载环境提供强大的调度支持。