Volcano提供了一系列注解(Annotations),可以应用于Pod或PodGroup资源,用于控制调度行为和资源分配。这些注解提供了一种简单而强大的方式来影响Volcano的调度决策,而无需修改复杂的配置文件或自定义资源定义。
常用注解概览
| 注解 | 适用对象 | 作用 | 示例值 |
|---|---|---|---|
scheduling.volcano.sh/queue-name | Pod | 指定资源应该被分配到哪个队列 | "default" |
volcano.sh/preemptable | Pod | 标记Pod是否可被抢占 | "true","false" |
volcano.sh/task-spec | Pod | 指定Pod所属的任务类型 | "worker" |
volcano.sh/min-available | PodGroup | 指定PodGroup最小可用Pod数量 | "3" |
volcano.sh/priorityClassName | PodGroup | 指定PodGroup的优先级类名 | "high-priority" |
volcano.sh/task-priority | Pod | 指定Pod在任务中的优先级 | "10" |
volcano.sh/qos-level | Pod | 指定Pod的服务质量等级 | "LC","HLS","LS","BE" |
volcano.sh/sla-waiting-time | Job | 设置Job在Pending状态的最大等待时间 | "30m","1h" |
volcano.sh/resource-group | Pod | 标记Pod属于哪个资源组 | "gpu","cpu" |
volcano.sh/closed-by-parent | Queue | 标记队列是否由父队列关闭 | "true" |
volcano.sh/createdByJobTemplate | Job | 标记Job是否由作业模板创建 | "template-name" |
volcano.sh/createdByJobFlow | Job | 标记Job是否由作业流创建 | "flow-name" |
注解详细说明
下面是每个注解的详细说明和使用示例。
scheduling.volcano.sh/queue-name
作用:指定资源应该被分配到哪个队列。这个注解可以应用于Pod,不能用于deployment/statefulset等其他资源。
原理:使用该注解的关键前提是需要设置调度器名称为volcano(schedulerName: volcano),随后PodGroup Controller会监听Pod的创建,并为所有的Pod创建对应的PodGroup。在此流程中会通过Pod的scheduling.volcano.sh/queue-name注解来确定PodGroup的队列名称,随后PodGroup会使用队列的各种功能特性,如资源配额、优先级、抢占等。
重要性:队列是Volcano资源管理的基本单位,指定队列可以确保资源被正确分配并遵循队列的资源配额和策略。
注意事项:
- 截止
v1.12.1版本,只能通过annotations来设置队列,不能通过labels来设置队列。 - 截止
v1.12.1版本,针对常用的Deployment资源,只能在spec.template.metadata.annotations中设置队列名称,不能在metadata.annotations中设置队列名称。
示例:
创建测试队列:
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: test-queue
spec:
capability:
cpu: 10
memory: 10Gi
通过Pod测试:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
annotations:
# 需要注意,只能使用annotations,不能使用labels指定队列,
# 否则无法设置队列,生成的PodGroup的队列名称为默认的default
scheduling.volcano.sh/queue-name: "test-queue"
spec:
schedulerName: volcano
containers:
- name: example-container
image: nginx
通过Deployment测试:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
annotations:
# 只能在annotations中设置队列名称,不能在labels中设置
# 只能这里设置队列名称,不能在Deployment的annotations中设置
scheduling.volcano.sh/queue-name: "test-queue"
spec:
schedulerName: volcano
containers:
- name: nginx
image: nginx:1.14.2
volcano.sh/preemptable
作用:标记Pod是否可被抢占。当设置为"true"时,表示该Pod可以被高优先级的Pod抢占资源。
重要性:在资源紧张时,标记为可抢占的Pod可能会被终止以释放资源给高优先级任务。这对于区分关键和非关键工作负载非常重要。
示例:
apiVersion: v1
kind: Pod
metadata:
name: preemptable-pod
annotations:
volcano.sh/preemptable: "true"
spec:
schedulerName: volcano
containers:
- name: example-container
image: nginx
volcano.sh/task-spec
作用:指定Pod所属的任务类型。在分布式训练任务中,不同的Pod可能有不同的角色(如参数服务器、工作节点等)。
重要性:这个注解帮助调度器识别Pod的角色,从而应用相应的调度策略。对于需要特定网络拓扑的任务(如高性能计算),这一点尤为重要。
示例:
apiVersion: v1
kind: Pod
metadata:
name: worker-pod
annotations:
volcano.sh/task-spec: "worker"
spec:
schedulerName: volcano
containers:
- name: worker-container
image: tensorflow/tensorflow:latest-gpu
volcano.sh/min-available
作用:指定PodGroup最小可用Pod数量。只有当可用的Pod数量达到或超过这个值时,PodGroup才会被调度。
重要性:这个注解是Volcano实现Gang调度(整体调度)的关键。它确保了分布式任务的所有必要组件都能同时启动,避免资源浪费和死锁。
示例:
apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
metadata:
name: distributed-training
spec:
minMember: 3 # 等同于使用 volcano.sh/min-available: "3" 注解
volcano.sh/priorityClassName
作用:指定PodGroup的优先级类名。这个类名对应于Kubernetes中定义的PriorityClass资源。
重要性:当资源紧张时,高优先级的PodGroup可以抢占低优先级的PodGroup资源。这对于确保关键任务在资源竞争中获得优先处理非常重要。
示例:
# 首先定义PriorityClass
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for critical jobs"
---
# 然后在PodGroup中使用
apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
metadata:
name: critical-job
annotations:
volcano.sh/priorityClassName: "high-priority"
spec:
minMember: 3
volcano.sh/task-priority
作用:指定Pod在任务中的优先级。这个优先级值是一个整数,值越高表示优先级越高。
重要性:在复杂的工作流中,某些Pod可能需要先于其他Pod运行。这个注解允许在同一任务内设置不同的优先级。
与priorityClass的区别:
volcano.sh/task-priority:仅在同一个Volcano任务(Job)内部的Pod之间生效,用于设置同一任务内(Job)不同Pod的优先级关系priorityClass:在整个Kubernetes集群范围内生效,影响 不同的Job/Pod之间的全局优先级
资源抢占机制:
- 跨任务抢占:当不同任务之间发生资源竞争时,
Volcano使用Job级别的优先级(来自priorityClass)决定抢占顺序 - 任务内部抢占:同一任务内部的
Pod之间发生资源竞争时,Volcano使用Pod级别的优先级(通过volcano.sh/task-priority设置)决定抢占顺序
优先级设置顺序:Volcano首先使用Pod的.spec.priority(来自priorityClass),然后如果存在volcano.sh/task-priority注解,则会覆盖前者的值。
实际应用:
- 在大型机器学习工作流中,可以给数据预处理
Pod较高的task-priority,确保它们优先获取资源 - 在同一个分布式应用中,可以给主节点较高的
task-priority,确保它先于从节点启动
示例:
apiVersion: v1
kind: Pod
metadata:
name: high-priority-task
annotations:
volcano.sh/task-priority: "10"
spec:
schedulerName: volcano
containers:
- name: task-container
image: my-task-image
volcano.sh/closed-by-parent
作用:标记队列是否由父队列关闭。当设置为"true"时,表示该队列是因为其父队列关闭而关闭的。
重要性:在层级队列结构中,这个注解用于跟踪队列关闭的原因,帮助系统管理队列状态。
示例:
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: child-queue
annotations:
volcano.sh/closed-by-parent: "true"
spec:
weight: 1
volcano.sh/createdByJobTemplate
作用:标记Job是否由作业模板创建。当设置为特定值时,表示该Job是由指定的模板创建的。
重要性:这个注解用于跟踪Job的来源,帮助系统管理和组织相关的作业。
示例:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: templated-job
annotations:
volcano.sh/createdByJobTemplate: "ml-training-template"
spec:
minAvailable: 3
schedulerName: volcano
# 其他作业配置...
volcano.sh/createdByJobFlow
作用:标记Job是否由作业流创建。当设置为特定值时,表示该Job是由指定的作业流创建的。
重要性:这个注解用于跟踪复杂工作流中的Job关系,帮助系统管理和组织相关的作业。
示例:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: flow-job
annotations:
volcano.sh/createdByJobFlow: "data-processing-flow"
spec:
minAvailable: 2
schedulerName: volcano
# 其他作业配置...
volcano.sh/qos-level
作用:指定Pod的服务质量(QoS)等级。用于Volcano Agent的混部场景,标记Pod的服务质量等级,以便进行资源隔离和QoS保障。
适用场景:
- 在线/离线混部场景
- 需要对不同优先级的工作负载进行资源隔离和
QoS保障
可选值:
LC(Latency Critical) - 延迟关键型,优先级最高HLS(Highly Latency Sensitive) - 高度延迟敏感型LS(Latency Sensitive) - 延迟敏感型BE(Best Effort) - 尽力而为型,优先级最低
重要性:在混部场景中,通过QoS等级可以确保在线服务的延迟敏感性,同时充分利用离线任务填充空闲资源,提高整体资源利用率。
示例:
apiVersion: v1
kind: Pod
metadata:
name: online-service
annotations:
volcano.sh/qos-level: "LC" # 标记为延迟关键型
spec:
schedulerName: volcano
containers:
- name: app
image: my-app:latest
resources:
requests:
cpu: "2"
memory: "4Gi"
volcano.sh/sla-waiting-time
作用:设置Job在Pending状态下的最大等待时间。当Job等待时间超过此值后,将强制入队并创建Pending状态的Pod,即使集群资源不足。
适用场景:
- 需要保证
Job的SLA(服务级别协议) - 防止
Job因资源不足长时间等待 - 确保任务在规定时间内得到响应
时间格式:支持的时间单位包括 "ns", "us" (或 "µs"), "ms", "s", "m", "h"
配置方式:
- 全局配置(在调度器配置中):
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: sla
arguments:
sla-waiting-time: 1h # 全局等待时间
- 单个Job配置(在
Job的annotations中):
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: training-job
annotations:
volcano.sh/sla-waiting-time: "30m" # 单独设置等待时间,覆盖全局配置
spec:
minAvailable: 3
schedulerName: volcano
tasks:
- replicas: 3
name: worker
template:
spec:
containers:
- name: trainer
image: tensorflow:latest
resources:
requests:
cpu: "4"
memory: "8Gi"
重要性:通过设置SLA等待时间,可以避免Job因资源不足而无限期等待,确保任务在可接受的时间范围内得到处理,提高用户体验。
注意事项:
- 单个
Job的sla-waiting-time注解会覆盖全局配置 - 如果不设置此注解,
Job将无SLA限制,可能长时间处于等待状态
volcano.sh/resource-group
作用:标记Pod属于哪个资源组。用于Volcano Webhook的自动注入功能,根据资源组自动为Pod注入nodeSelector、tolerations、labels等配置。
适用场景:
- 需要根据资源组自动注入调度策略
- 实现基于资源组的
Pod自动调度 - 简化
Pod配置,避免重复编写相同的调度配置
工作原理:
- 在
Volcano Webhook配置中定义资源组及其对应的配置 Pod添加此注解后,Webhook会自动注入对应的配置- 简化用户配置,提高配置一致性
示例:
Webhook配置:
resourceGroups:
- resourceGroup: "gpu"
object:
key: "annotation"
value:
- "volcano.sh/resource-group: gpu"
schedulerName: "volcano"
labels:
volcano.sh/nodetype: "gpu"
tolerations:
- key: "gpu"
operator: "Exists"
effect: "NoSchedule"
Pod配置:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
annotations:
volcano.sh/resource-group: "gpu" # 标记为GPU资源组
spec:
schedulerName: volcano
containers:
- name: app
image: my-gpu-app:latest
resources:
requests:
nvidia.com/gpu: 1
自动注入效果:
Webhook会自动为上述Pod注入以下配置:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
annotations:
volcano.sh/resource-group: "gpu"
labels:
volcano.sh/nodetype: "gpu" # 自动注入
spec:
schedulerName: volcano
nodeSelector:
volcano.sh/nodetype: "gpu" # 自动注入
tolerations: # 自动注入
- key: "gpu"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: app
image: my-gpu-app:latest
resources:
requests:
nvidia.com/gpu: 1
重要性:通过资源组自动注入功能,可以大大简化Pod配置,确保同一资源组的Pod具有一致的调度策略,减少配置错误。