官网:
https://volcano.sh/zh/
git:
https://github.com/volcano-sh/volcano/tree/v1.0.1
gitee码云:
https://gitee.com/ascend/ascend-for-volcano
社区(Mind X DL):
https://bbs.huaweicloud.com/forum/forumdisplay-fid-1231-orderby-lastpost-filter-typeid-typeid-1695.html
Volcano是在Kubernetes上运行高性能工作负载的容器批量计算引擎。 它提供了Kubernetes目前缺少的一套机制,这些机制通常是许多高性能 工作负载所必需的,包括:
- 机器学习/深度学习
- 生物学计算/基因计算
- 大数据应用
这些类型的应用程序通常运行在像Tensorflow、Spark、PyTorch、 MPI等通用领域框架上,Volcano无缝对接这些框架。
Volcano是基于Kubernetes的高性能批量计算平台,目前支持几乎所有的主流计算框架,包括MindSpore、TensorFlow、Kubeflow、MPI、PyTorch、飞浆、Spark、HOROVOD 等。
计算框架遇到的问题:
e.g. fair-share, gang-scheduling
e.g. multiple pod template, error handling
e.g. GPU, FPGA
e.g. scalability, throughput, network, runtime
e.g. Queue, Reclaim
Volcano面向主流计算框架提供:
CRD方式
3个核心的API:Volcano Job、PodGroup、Queue
Admission、ControllerManager、Scheduler 。
Admission对Volcano CRD API提供校验能力;ControllerManager负责对Volcano CRD进行资源管理;Scheduler对任务提供丰富的调度能力。
从零开始运行Volcano作业:
1)用户创建一个 Volcano 作业。三种方式:api,kubctl,vcctl
2)Volcano Admission 拦截作业的创建请求,并进行合法性校验。可以修改参数,再认证。
3)Kubernetes 持久化存储 Volcano Job 到 ETCD。
4)ControllerManager 通过 List-Watch 机制观察到Job 资源的创建,创建任务(Pod)。
5)Scheduler 负责任务的调度,绑定 Node。
6)Kubelet Watch 到 Pod的创建,接管 Pod 的运行。
7)ControllerManager 监控所有任务的运行状态,保证所有的任务在期望的状态下运行。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: test-job
spec:
minAvailable: 3
schedulerName: volcano
priorityClassName: high-priority
policies:
- event: PodEvicted
action: RestartJob
plugins:
ssh: []
env: []
svc: []
maxRetry: 5
queue: default
volumes:
- mountPath: "/myinput"
- mountPath: "/myoutput"
volumeClaimName: "testvolumeclaimname"
volumeClaim:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
tasks:
- replicas: 6
name: "default-nginx"
template:
metadata:
name: web
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources:
requests:
cpu: "1"
restartPolicy: OnFailure
schedulerName表示该job的pod所使用的调度器,默认值为volcano,也可指定为default-scheduler。它也是tasks.template.spec.schedulerName的默认值。
minAvailable表示运行该job所要运行的最少pod数量。只有当job中处于running状态的pod数量不小于minAvailable时,才认为该job运行正常。
volumes表示该job的挂卷配置。volumes配置遵从kubernetes volumes配置要求。
tasks.replicas表示某个task pod的副本数。
tasks.template表示某个task pod的具体配置定义。
tasks.policies表示某个task的生命周期策略。
policies表示job中所有task的默认生命周期策略,在tasks.policies不配置时使用该策略。
plugins表示该job在调度过程中使用的插件。
queue表示该job所属的队列。
priorityClassName表示该job优先级,在抢占调度和优先级排序中生效。
maxRetry表示当该job可以进行的最大重启次数。
pending表示job还在等待调度中,处于排队的状态。
aborting表示job因为某种外界原因正处于中止状态,即将进入aborted状态。
aborted表示job因为某种外界原因已处于中止状态。
running表示job中至少有minAvailable个pod正在运行状态。
restarting表示job正处于重启状态,正在中止当前的job实例并重新创建新的实例。
completing表示job中至少有minAvailable个数的task已经完成,该job正在进行最后的清理工作。
completing表示job中至少有minAvailable个数的task已经完成,该job已经完成了最后的清理工作。
terminating表示job因为某种内部原因正处于终止状态,正在等到pod或task释放资源。
terminated表示job因为某种内部原因已经处于终止状态,job没有达到预期就结束了。
failed表示job经过了maxRetry次重启,依然没有正常启动。
以tensorflow为例,创建一个具有1个ps和2个worker的工作负载。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: tensorflow-dist-mnist
spec:
minAvailable: 3 // 该job的3个pod必须都可用
schedulerName: volcano // 指定volcano为调度器
plugins:
env: []
svc: []
policies:
- event: PodEvicted // 当pod被驱逐时,重启该job
action: RestartJob
tasks:
- replicas: 1 // 指定1个ps pod
name: ps
template: // ps pod的具体定义
spec:
containers:
- command:
- sh
- -c
- |
PS_HOST=`cat /etc/volcano/ps.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
WORKER_HOST=`cat /etc/volcano/worker.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
export TF_CONFIG={\"cluster\":{\"ps\":[${PS_HOST}],\"worker\":[${WORKER_HOST}]},\"task\":{\"type\":\"ps\",\"index\":${VK_TASK_INDEX}},\"environment\":\"cloud\"};
python /var/tf_dist_mnist/dist_mnist.py
image: volcanosh/dist-mnist-tf-example:0.0.1
name: tensorflow
ports:
- containerPort: 2222
name: tfjob-port
resources: {}
restartPolicy: Never
- replicas: 2 // 指定2个worker pod
name: worker
policies:
- event: TaskCompleted // 2个worker完成任务时认为该job完成任务
action: CompleteJob
template: // worker pod的具体定义
spec:
containers:
- command:
- sh
- -c
- |
PS_HOST=`cat /etc/volcano/ps.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
WORKER_HOST=`cat /etc/volcano/worker.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
export TF_CONFIG={\"cluster\":{\"ps\":[${PS_HOST}],\"worker\":[${WORKER_HOST}]},\"task\":{\"type\":\"worker\",\"index\":${VK_TASK_INDEX}},\"environment\":\"cloud\"};
python /var/tf_dist_mnist/dist_mnist.py
image: volcanosh/dist-mnist-tf-example:0.0.1
name: tensorflow
ports:
- containerPort: 2222
name: tfjob-port
resources: {}
restartPolicy: Never
以mindspore为例,创建一个具有8个pod副本的工作负载,要求1个可用即可。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: mindspore-cpu
spec:
minAvailable: 1
schedulerName: volcano
policies:
- event: PodEvicted
action: RestartJob
plugins:
ssh: []
env: []
svc: []
maxRetry: 5
queue: default
tasks:
- replicas: 8
name: "pod"
template:
spec:
containers:
- command: ["/bin/bash", "-c", "python /tmp/lenet.py"]
image: lyd911/mindspore-cpu-example:0.2.0
imagePullPolicy: IfNotPresent
name: mindspore-cpu-job
resources:
limits:
cpu: "1"
requests:
cpu: "1"
restartPolicy: OnFailure
volcano job对当前主流的计算框架均能很好的支持,具体如下:
与default-scheduler相比,volcano在批处理方面进行了增强。它更适用于高性能计算场景,如机器学习、大数据应用和科学计算。
Queue的概念源于 Yarn,它是Cluster 级别的资源对象,可为其声明资源配额,也可由多namespace 共享,并且提供 soft isolation
queue是容纳一组podgroup的队列,也是该组podgroup获取集群资源的划分依据
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
creationTimestamp: "2020-08-10T11:54:36Z"
generation: 1
name: default
resourceVersion: "559"
selfLink: /apis/scheduling.volcano.sh/v1beta1/queues/default
uid: 14082e4c-bef6-4248-a414-1e06d8352bf0
spec:
reclaimable: true
weight: 1
capability:
cpu: "4"
memory: "4096Mi"
status:
state: Open
weight表示该queue在集群资源划分中所占的相对比重,该queue应得资源总量为 (weight/total-weight) * total-resource。其中, total-weight表示所有的queue的weight总和,total-resource表示集群的资源总量。weight是一个软约束,取值范围为[1, 2^31-1]
capability表示该queue内所有podgroup使用资源量之和的上限,它是一个硬约束
reclaimable表示该queue在资源使用量超过该queue所应得的资源份额时,是否允许其他queue回收该queue使用超额的资源,默认值为true
该queue当前处于可用状态,可接收新的podgroup
该queue当前处于不可用状态,不可接收新的podgroup
该Queue正在转化为不可用状态,不可接收新的podgroup
该queue当前处于不可知状态,可能是网络或其他原因导致queue的状态暂时无法感知
volcano启动后,会默认创建名为default的queue,weight为1。后续下发的job,若未指定queue,默认属于default queue
weight的软约束是指weight决定的queue应得资源的份额并不是不能超出使用的。当其他queue的资源未充分利用时,需要超出使用资源的queue可临时多占。但其 他queue后续若有任务下发需要用到这部分资源,将驱逐该queue多占资源的任务以达到weight规定的份额(前提是queue的reclaimable为true)。这种设计可以 保证集群资源的最大化利用。
apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
metadata:
creationTimestamp: "2020-08-11T12:28:55Z"
generation: 5
name: test
namespace: default
ownerReferences:
- apiVersion: batch.volcano.sh/v1alpha1
blockOwnerDeletion: true
controller: true
kind: Job
name: test
uid: 028ecfe8-0ff9-477d-836c-ac5676491a38
resourceVersion: "109074"
selfLink: /apis/scheduling.volcano.sh/v1beta1/namespaces/default/podgroups/job-1
uid: eb2508f5-3349-439c-b94d-4ac23afd71ff
spec:
minMember: 1
minResources:
cpu: "3"
memory: "2048Mi"
priorityClassName: high-prority
queue: default
status:
conditions:
- lastTransitionTime: "2020-08-11T12:28:57Z"
message: '1/0 tasks in gang unschedulable: pod group is not ready, 1 minAvailable.'
reason: NotEnoughResources
status: "True"
transitionID: 77d5be3f-6169-4f86-8e65-0bdc621ce983
type: Unschedulable
- lastTransitionTime: "2020-08-11T12:29:02Z"
reason: tasks in gang are ready to be scheduled
status: "True"
transitionID: 54514401-5c90-4b11-840d-90c1cda93096
type: Scheduled
phase: Running
running: 1
minMember表示该podgroup下最少需要运行的pod或任务数量。如果集群资源不满足miniMember数量任务的运行需求,调度器将不会调度任何一个该podgroup 内的任务。
queue表示该podgroup所属的queue。queue必须提前已创建且状态为open。
priorityClassName表示该podgroup的优先级,用于调度器为该queue中所有podgroup进行调度时进行排序。system-node-critical和system-cluster-critical 是2个预留的值,表示最高优先级。不特别指定时,默认使用default优先级或zero优先级。
minResources表示运行该podgroup所需要的最少资源。当集群可分配资源不满足minResources时,调度器将不会调度任何一个该podgroup内的任务。
phase表示该podgroup当前的状态。
conditions表示该podgroup的具体状态日志,包含了podgroup生命周期中的关键事件。
running表示该podgroup中当前处于running状态的pod或任务的数量。
succeed表示该podgroup中当前处于succeed状态的pod或任务的数量。
failed表示该podgroup中当前处于failed状态的pod或任务的数量。
pending表示该podgroup已经被volcano接纳,但是集群资源暂时不能满足它的需求。一旦资源满足,该podgroup将转变为running状态。
running表示该podgroup至少有minMember个pod或任务处于running状态。
unknown表示该podgroup中minMember数量的pod或任务分为2种状态,部分处于running状态,部分没有被调度。没有被调度的原因可能是资源不够等。调度 器将等待controller重新拉起这些pod或任务。
inqueue表示该podgroup已经通过了调度器的校验并入队,即将为它分配资源。inqueue是一种处于pending和running之间的中间状态。
在某些场景下,可能会只需要某个任务的子任务运行达到一定的数量,即可认为本次任务可以运行,如机器学习训练。这种情况下适合使用minMember字段。
priorityClassName用于podgroup的优先级排序,可用于任务抢占调度场景。它本身也是一种资源。
在某些场景下,任务的运行必须满足最小资源要求,不满足则不能运行该任务,如某些大数据分析场景。这种情况下适合使用minResources字段。
当创建vcjob(volcano job的简称)时,若没有指定该vcjob所属的podgroup,默认会为该vcjob创建同名的podgroup
左边为Volcano Job Controller,不只调度使用的Volcano,Job的生命周期管理、作业管理都在这里面包含。我们提供了统一的作业管理,你只要使用Volcano,也不需要创建各种各样的操作,就可以直接运行作业。
右边为CRD Job Controller,通过下面的PodGroup去做集成。
Scheduler支持动态配置和加载。左边为apiserver,右边为整个Scheduler,apiserver里有Job、Pod、Pod Group;Scheduler分为三部分,第一层为Cache,中间层为整个调度的过程,右边是以插件形式存在的调度算法。Cache会将apiserver里创建的Pod、Pod Group这些信息存储并加工为Jobinfors。中间层的OpenSession会从Cache里拉取Pod、Pod Group,同时将右边的算法插件一起获取,从而运行它的调度工作。
状态之间根据不同的操作进行转换,见下图。
**volcano在Pod和Pod的状态方面增加了很多状态,图中蓝色部分为K8s自带的状态;**绿色部分是session级别的状态,一个调度周期,我们会创建一个session,它只在调度周期内发挥作用,一旦过了调度周期,这几个状态它是失效的;黄色部分的状态是放在Cache内的。我们加这些状态的目的是减少调度和API之间的一个交互,从而来优化调度性能。
**Pod的这些状态为调度器提供了更多优化的可能。**例如,当进行Pod驱逐时,驱逐在Binding和Bound状态的Pod要比较驱逐Running状态的Pod的代价要小 (思考:还有其它状态的Pod可以驱逐吗?);并且状态都是记录在Volcano调度内部,减少了与kube-apiserver的通信。但目前Volcano调度器仅使用了状态的部分功能,比如现在的preemption/reclaim仅会驱逐Running状态下的Pod;这主要是由于分布式系统中很难做到完全的状态同步,在驱逐Binding和Bound状态的Pod会有很多的状态竞争。
以上设计的好处
支持多种类型作业混合部署
支持多队列用于多租户资源共享,资源规划;并分时复用资源
支持多种高级调度策略,有效提升整集群资源利用率
支持资源实时监控,用于高精度资源调度,例如 热点,网络带宽;容器引擎,网络性能优化, e.g. 免加载
所有组件启动入口。
volcano配置。
安装时的配置。
dockerfile,helm等安装所需模板。
设计文档。
简单例子。
安装时的配置。
核心代码。包括 api、controller、scheduler 、webhook 等代码。test 提供了e2e测试用例, vendor是依赖库。
Volcano Install
Volcano安装部署有多种方式:若已存在K8S集群,建议通过 Helm方式安装部署,该方式支持自定义安装配置;开发者建议通过Development Yaml方式部署。
对于开发者,Volcano已内置一键式安装部署脚本,路径为 volcano. sh/volcano/hack/local-up-volcano. sh。运行该脚本时,默认会使用kind创建 Docker in Docker的模拟集群,并安装部署Volcano。
Volcano 组件