在上一篇安装篇之后,我们已经初步拥有了一个k8s集群,并且运行着k8s-device-plugin,能够将gpu任务分配到装有gpu的node上。
但是,如果我们想让任务调度更加灵活呢?
首先,我们必须要了解k8s任务调度机制
kube-scheduler
https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/
简单的说,k8s的scheduler主要作了以下两个工作:
筛选和打分。
首先,k8s会筛选掉资源条件不允许的node,比如某个pod需要1个gpu资源,那么scheduler会首先排除掉没有gpu的node。
其次,scheduler会筛选掉因其他原因,不能运行该pod的node。
然后,会有一个打分机制,根据各种维度的打分选出最优的pod。其中,不同的分数有不同的权重。
那么,如果要更改这些机制,人为添加条件,该如何做呢?
第一种方法:git clone k8s的官方源码,然后修改scheduler,自己编译k8s
这种方法显然会带来非常多的麻烦,尤其是后期维护的开销。我们知道,k8s是允许master和node使用不同版本的k8s运行的,这一点我们可以在get nodes里面观察到。如果自行修改源代码,可靠性难以保证,对整个集群后期维护也会埋下隐患。
第二种方法:自己写一个scheduler,和kube-scheduler同时运行。
这一种方法的想法是,默认的scheduler和你自己写的scheduler分别管不同的pod,可以通过在pod里添加schedulerName字段来实现。但是,这样做也会带来问题,因为集群是分布式的,存在cache同步一致性的问题。比如,有这样一个pod,提交到k8s,被两个scheduler同时分配到同一个node上。这样的问题不是不能解决,但是要花费相当大的精力。
第三种方法:写一个scheduler extender
第四种方法:scheduling framework
在笔者写这篇文章时(2020年4月),其实第三种方法第四种方法看上去都比较实用,因为没有破坏k8s原有的代码和架构,也兼容默认的kube-scheduler。但是不知为何,在kubernetes官方文档里,关于scheduling这部分
没有任何关于scheduler extender的介绍,只有scheduling framework的介绍,而scheduling framework目前还处于alpha版本。目前我们计划写一个scheduling framework的plugin。