本文共 2685 字,大约阅读时间需要 8 分钟。
本文原文QQ空间链接:
本文原文csdn博文链接:
前面分析了discovery,cluster,node。那这一篇就分析scheduler和api。
我们先回顾下Scheduler在manage中如何构建的
源码在swarm\manage.go
先构建了strategy和filter。
然后构建了Scheduler。
下面看看Scheduler的源码
源码在swarm\scheduler\scheduler.go
结构体很简单,就3个主要成员
下面先简单的看看Scheduler提供的接口
先选择node,然后调用cluster中的部署
选择有两个部分,一个是filter,一个是strategy
直接通过cluster来进行删除
Scheduler的表面功能还是很简单的。其最主要的还是于如何选择node。
说到选择node,那我们就来看看strategy
源码在swarm\scheduler\strategy\strategy.go
通过插件的方式,提供了两种模式的选择。上面的代码中是两个插件初始化注册
通过name来获取插件
源码在swarm\scheduler\strategy\binpacking.go
是一个空的结构体
那么看下提供的接口
遍历所有的node,然后判断memory和cpu是否满足条件
然后对memory和cpu进行计算分数,符合条件的就放到个队列中。
最后将队列进行排序,返回最好的那个。
源码在swarm\scheduler\strategy\random.go
结构体还是个空的
下面主要看下其提供的接口
这里就是随机返回了一个node。功能很简单
选择除了strategy,还有filter
源码在swarm\scheduler\filter\filter.go
依然是通过插件模式来设计的,一共提供了5种的模式。
通过names来进行filter的初始化。这里和strategy不同的是,strategy是只能选择一个插件,但filter可以多个一起工作
这就是filter的工作
源码在swarm\scheduler\filter\affinity.go
AffinityFilter是一个空结构体,主要看下其提供的接口
首先获取affinity的设置
然后依次针对nodes进行遍历处理。上图为对Container进行match
再有就是对image进行match。
将match到的nodes,然后再进行下一轮的affinity匹配。循环匹配,直至所有的affinity都匹配完全。
源码在swarm\scheduler\filter\health.go
直接遍历所有的nodes,讲非healthy的node剔除掉。
源码在swarm\scheduler\filter\constraint.go
这里和affinity类似,先获取constraint的设置
然后针对nodes进行循环match,直到所有的constraint都匹配完
源码在swarm\scheduler\filter\port.go
这个也很简单,就是判断node中的端口是否已经被占用。
源码在swarm\scheduler\filter\dependency.go
先获取与其他Container的link信息
再获取到与其他Container连接的端口信息
然后遍历nodes,对每个nodes上的Container都进行检查,看看是否含有link和net先关的Container。将都含有的返回nodes。
filter功能还是很清晰的,而且每个模块的功能都比较简单。
到了最后的地方了。先来看看在manage中api是如何初始化的
代码在swarm\manage.go
里面将cluster、Scheduler,都传入到了api中
下面继续看api
代码在swarm\api\server.go
上面有几个东西,比较关键。
1、context:包含了所有的信息,cluster,Scheduler,eventHandler等
2、createRouter:这个是关键入口。
然后根据不同类型的初始化了不同的listenr。
代码在swarm\api\api.go
上图中构建了一个mux.Router(github.com/gorilla/mux 这个代码在前面的docker源码分析中有分析过)
然后构建了很多的get请求所对应的路由以及handler
然后是post、delete、options路由,以及对应的handler。其中有部分handler没有实现。
将上面的handler,进行封装注册到router中。
api的handler数量过多,这里就以proxyContainer来做例子讲解
源码在swarm\api\api.go
首先是获取Container,然后通过proxy进行通信
通过cluster来获取Container,根据不同的参数,做不同的查找。
调用了proxyAsync
构建一个client,然后像node发起了url请求
api的结构依旧和docker api类似,逻辑简单直接。
swarm的源码分析就到此。从整个分析过程来看。swarm的框架设计的非常好。每个模块功能单一,清晰。并且在模块中又通过一些插件的形式进行设计。整个设计属于golang设计模式中的典型通用的模式设计。
文中如果有哪里讲解的不对的地方,还请见谅,望指正。
龚浩华
QQ 月牙寂 道长 29185807
2016年5月12日
(版权声明:本文为作者原创,如需转载请通知本人,并标明出处和作者。擅自转载的,保留追究其侵权的权利。)
如果你觉得本文对你有帮助,可以转到你的朋友圈,让更多人一起学习。
第一时间获取文章,可以关注本人公众号:月牙寂道长,也可以扫码关注