上篇简单说了下在集群中安装kube-batch且成功运行起来之后, 现在开始对kube-batch中的一些概念进行阐明, 先从podgroup及queue说起
Queue
queue在kube-batch中属于集群级别的资源,配置如下:
1 | apiVersion: scheduling.incubator.k8s.io/v1alpha1 |
默认,如果集群中不存在queue,kube-batch会默认创建一个如上的queue,这个默认的queue主要用来存放没有绑定queue的job(这个job不是kubernetes中job资源,而是特指使用了kube-batch的对象,有可能是kubernetes job,也可能是pod等)
前面提到过,kube-batch对多租户的支持、多租户间的资源分配就是通过queue来实现的
queue本身就是一种排除机制,kube-batch也是如此,对于资源的消耗,如果资源得不到满足,同样会进行排除处理.
这里举个最简单的例子:
假如一个k8s集群中存在的资源有,cpu: 12c, mem: 120Gi, GPU: 4c
假如现在创建了2个queue
1 | apiVersion: scheduling.incubator.k8s.io/v1alpha1 |
其中,weight表示权重,那么集群中的所有资源会被分成3等份,所属default-1的queue占1/3, 即cpu:4c,mem:40ci,gpu:4c
,而所属default-2的queue占2/3, 即cpu:8c,mem:80ci,gpu:8c
当然,前面也提过,这个不是绝对的,因为kube-batch存在插件机制,租户之间可以指定优先级等插件对其它租户的资源进行抢占,使资源的资源更加偏向重要的任务
如果集群中没有多租户的概念,则可以不进行资源的划分,所有的任务都属于一个queue.
PodGroup
podgroup在kube-batch是个很重要的资源对象,kube-batch会监听集群中所有podgroup,然后计算(由插件决定)所属这个group中的pod所需要的资源,如果集群中没有这些资源,则所有的pod会处理pendding状态,在queue中进行排队,如果存在,则进行调度
使用方法来看官方一个简单的例子:
1 |
|
The yaml file means a Job named qj-01
to create 6 pods(it is specified by parallelism
), these pods will be scheduled by scheduler kube-batch
(it is specified by schedulerName
). kube-batch
will watch PodGroup
, and the annotation scheduling.k8s.io/group-name
identify which group the pod belongs to. kube-batch
will start .spec.minMember
pods for a Job at the same time; otherwise, such as resources are not sufficient, kube-batch
will not start any pods for the Job.
上面的yaml文件生成了个podgroup对象及一个kubernetes中的job对象
其中:
- podgroup中的minMember表明至少需要满足6个pods的资源时才会进行调度,pods则是通过annotations进行绑定
- 在job中存在有annotations,通过scheduling.k8s.io/group-name绑定的podgroup.
- 在job中指定了schedulerName为Kube-batch
通过这样的绑定关系就将podgroup与pod进行了关联,当然,podgroup中的minMember只是最小的pod数,如果满足这个条件也只是表明这个podgroup可以调度,但是并不一定调度成功,但是如果不满足最小pod数,则一定不会调度
还是以上面的例子来说明:
假如集群中只有4个CPU, 这时minMember设置为1,那么这个podgroup会进行调度,但是由于CPU只有4个,而job中需要同时启动6个(job的parallelism
参数指定 )pod,也就是需要6个cpu,显然有2个无法获取到cpu,也即会有2外pod处于pendding状态,其它4个运行正常
而如果将minMember指定为6,则一个pod都不会调度,整个job会处理pendding状态.
上面这种最简单的场景在训练任务中非常常见, 往往一个训练任务由N多个pod一起进行,且每个pod都负责其中的一部分,如果不考虑增量训练的话,其中其中任一个pod的资源不能满足的话,则就不应该对其它pod进行调度,这样可以合理地利用资源
shadowPodGroup
从上面的例子可以看到,每一个任务都需要创建一个podgroup,对于懒人来说,有没有办法直接关联podgroup呢?
答案是肯定的,这就是shadowpodgroup,顾名思义就是podgroup的影子,作用就是不再需要手工地创建podgroup对象
只需要在annotation中指定minMemeber,kube-batch即会自动创建shadowPodgroup对象
因此,上面的例子则直接变成
1 | apiVersion: batch/v1 |
通过在annotation中指定scheduling.k8s.io/group-min-member
,则会由kube-batch自动生成逻辑的podgroup,是不是很方便.
这里要注意的是,podgroup在kubernetes中是属于crd对象,是可以通过kubectl get 命令查询的,而shadowpodgroup则是kube-batch逻辑对象,通过kubectl get 命令无法查询
以下是shawpodgroup的源码
1 | func createShadowPodGroup(pod *v1.Pod) *api.PodGroup { |
从这段代码也可以看出,最后其实还是生成的podgroup对象.
这篇文章中介绍了queue及podgroup的使用方法,相信大家有一定的了解,但是还没有一些重要的东西未涉及,比如podgroup中的资源是如何计算的,插件又是如何工作的,这些都会在后续进行更新.