kubernetes scheduler 模块分析 - 续

1.前言

在上一篇《kubernetes scheduler 模块分析》中,分析了scheduler调度的流程和主要的算法。从整体上把握了scheduler的调度机制,今天想继续分析下更为细节的内容。

2.概要

今天主要分析scheduler的缓存机制,Extender扩展机制及Taint&Toleration机制。这三个方面虽然不是那么宏观,但是对于深入了解scheduler,甚至整个k8s的设计里面有着非常重要的帮助,鉴于其他的模块也通过list-watch实现了缓存机制,通过这里可以窥见整个k8s的设计精髓。

1)scheduler 通过list-watch机制,从apiserver端获取数据并缓存,缓存数据通过list-watch绑定的三个方法-update/add/delete来维护缓存数据与apiserver端数据的一致性。list watch 的机制比较复杂,这里不做深入分析。

2)上一篇提到算法中提供的判断和排序算法,这些算法用户是可以用户自定义的,而且scheduler本身就提供了extender接口,在做判断和排序的过程中,已经调用了extender中的接口,如果实现了这些接口,会自动注入进去。下面在详细分析中我们可以看到。

3)Taint 和 Toleration 是成对使用的。是一种灵活的亲和度/反亲和度适配,能够替代很多通过属性设定的特性。Kubernetes v1.3.0-alpha.5 版本的release log 中可以看到这些内容,详细信息见:http://www.open-open.com/news/view/25b17e27 ,kubernetes github 关于这个特性的PR可以在这里: https://github.com/kubernetes/kubernetes/pull/24134

社区对这个特性的使用还是很强烈的,把之前一些用结构体属性标注的内容换成了使用这种方式来判别,具体信息见:https://github.com/kubernetes/kubernetes/issues/28082

3.详细分析

1)缓存机制

在调度模块中,缓存是单独的一部分,在plugin/pkg/scheduler/schedulercache目录下,主要分为两个部分,一个部分是接口,另一部分是接口的实现。在关注缓存的接口之前,我们先看看结构体:


结构体中缓存了nodes的信息,在做判断和排序的时候都会用到。这个nodes是一个map,key是node的name,value 是一个封装的NodeInfo,非常值得一提的是,NodeInfo包含了node上的pod的一个集合:


从NodeInfo集合我们可以看出,里面包含了node上已经被pods使用了的资源,这样在判断及排序的时候才可以做出决策。注意,这里的pods数组是pod的指针的数组,所以pod很多时,数组也不会很大,这里也体现了k8s设计的细微之处,这个结构体里面全部是指针形式出现的,所以在复杂的逻辑中,也不太会影响效率。

回到重点,我们来看看接口的情况:


跟我们开始想的一样,是对缓存的CRUD操作。这里的Assume Pod比较特殊,关于这个的解释,请看注释,不再赘述。

下面我们看看缓存方法的实现,其实也没什么特殊的,是一些基本的操作。


这里需要说的是对缓存的基础操作都是线程安全的,这里定义的方法通常是成对的,比如removePod和RemovePod,这是因为要暴露给list-watch使用,来更新缓存,接下来才是我们分析缓存的重点部分了,我们看看如何在list-watch和cache之间连接起来的:


看到这里我想应该明白了,尤其是两个红色方框里面的提示。缓存的更新就是这样做到的,将缓存操作的方法"注册"到list-watch相应的handler上去,感谢Go简洁的语法。

2)Extender 机制

extender 可谓见名知意,就是一种扩展,针对判断和排序的算法进行扩展。下面是在排序中的使用:


下面我们再看看在predict中的使用:


从上面两处,大家应该已经知道如何使用这个extender来做扩展了。

3)Taint 和 Toleration 

主要的文件在plugin/pkg/scheduler/algorithm/priorities目录下,下面看看主要内容:


这里一个主要的方法很扎眼-ComputeTaintTolerationPriority,这个是根据tain和toleration来计算排序得分的。那么这个是如何使用起来的呢?


这个文件位于plugin/pkg/algorithmprovider/default目录下,在默认的排序算法中,与默认的判断算法一起在init()中被调用,后面的流程在前一篇中已经分析过了。

4.总结

调度模块的基本面貌我们看到了,但这只是kubernetes插件的冰山一角而已,如果要了解这个庞大的体系,还需要更多的精力。

猜你喜欢

转载自blog.csdn.net/afandaafandaafanda/article/details/52141877