change pic cdn

add-license-1
yinwenqin 5 years ago
parent cf8eba293c
commit d716970ffa

@ -56,8 +56,8 @@ matebook-x-pro:local ywq$ go run main.go
# 因需要多次测试这里所有的测试步骤就把build的步骤跳过直接使用go run main.go进行测试
```
**我们打开IDE来查看一下testapp的代码结构:**
![image](http://pwh8f9az4.bkt.clouddn.com/cobra1.jpg)
![image](http://pwh8f9az4.bkt.clouddn.com/cobra2.jpg)
![image](http://mycloudn.kokoerp.com/cobra1.jpg)
![image](http://mycloudn.kokoerp.com/cobra2.jpg)
```
# 现在还未创建子命令,那么来创建几个试试:
@ -90,7 +90,7 @@ add called
```
**来看看新增的子命令是怎么运行的呢?**
![image](http://pwh8f9az4.bkt.clouddn.com/cobra3.jpg)
![image](http://mycloudn.kokoerp.com/cobra3.jpg)
截图圈中部分可以看出子命令是在init()函数里为root级添加了一个子命令先不去管底层实现接着往下.
**测试cobra的强大简洁的flag处理**
@ -101,7 +101,7 @@ deleteCmd.PersistentFlags().StringVar(&obj,"object", "", "A function to delete a
```
在`Run:func()`匿名函数中添加一行输出:
`fmt.Println("delete obj:",cmd.Flag("object").Value)`
![image](http://pwh8f9az4.bkt.clouddn.com/cobra4.jpg)
![image](http://mycloudn.kokoerp.com/cobra4.jpg)
运行结果:
@ -112,7 +112,7 @@ delete obj: obj1
```
如果觉得`--`flag符号太麻烦cobra同样支持短符号`-`flag缩写:
![image](http://pwh8f9az4.bkt.clouddn.com/cobra5.jpg)
![image](http://mycloudn.kokoerp.com/cobra5.jpg)
运行结果:
@ -132,7 +132,7 @@ add.go delete.go get.go pods.go root.go
```
可以发现,cmd/目录下多了一个pods.go文件我们来看看它是怎么关联上delete父级命令的,同时为它添加一行输出:
![image](http://pwh8f9az4.bkt.clouddn.com/cobra6.jpg)
![image](http://mycloudn.kokoerp.com/cobra6.jpg)
执行命令:
```
@ -146,13 +146,13 @@ delete pods: pod1
## 入口
通过对上方cobra的基本了解我们不难知道`cmd/kube-scheduler/scheduler.go`内的main()方法内部实际调用的是`cobra.Command.Run`内的匿名函数,我们可以进入`NewSchedulerCommand()`内部确认:
![image](http://pwh8f9az4.bkt.clouddn.com/main1.jpg)
![image](http://mycloudn.kokoerp.com/main1.jpg)
可以看到,调用了`Run`内部`runCommand`方法再来看看Run方法内部需要重点关注的几个点
![image](http://pwh8f9az4.bkt.clouddn.com/runCommand.jpg)
![image](http://mycloudn.kokoerp.com/runCommand.jpg)
其中,上方是对命令行的参数、选项校验的步骤,跳过,重点关注两个变量:`cc和stopCh`,这两个变量会作为最后调用`Run()`方法的参数,其中`stopCh`作用是作为主程序退出的信号通知其他各协程进行相关的退出操作的另外一个cc变量非常重要可以点击`c.Complete()`方法,查看该方法的详情:
![image](http://pwh8f9az4.bkt.clouddn.com/runCommand.jpg)
![image](http://mycloudn.kokoerp.com/runCommand.jpg)
`Complete()`方法本质上返回的是一个Config结构体该结构体内部的元素非常丰富篇幅有限就不一一点开截图了大家可以自行深入查看这些元素的作用这里简单概括一下其中几个:
```
@ -175,14 +175,14 @@ Recorder record.EventRecorder
Broadcaster record.EventBroadcaster
```
这里层级非常深不便展示Config这一个结构体非常重要可以认真读一读代码。回到`cmd/kube-scheduler/app/server.go`.`runCommand`这里来,接着往下进入其最后return调用的`Run()`函数中函数中的前部分都是启动scheduler相关的组件如event broadcaster、informers、healthz server、metric server等重点看图中红框圈出的`sched.Run()`,这才是scheduler主程序的调用运行函数:
![image](http://pwh8f9az4.bkt.clouddn.com/Run.jpg)
![image](http://mycloudn.kokoerp.com/Run.jpg)
进入`sched.Run()`:
![image](http://pwh8f9az4.bkt.clouddn.com/scheRun.jpg)
![image](http://mycloudn.kokoerp.com/scheRun.jpg)
`wait.Until`这个调用的逻辑是直到收到stop信号才终止在此之前循环运行`sched.scheduleOne`。代码走到这里,终于找到启动入口最内部的主体啦:
![](http://pwh8f9az4.bkt.clouddn.com/image-20190827163439895.png)
![](http://mycloudn.kokoerp.com/image-20190827163439895.png)
`sched.scheduleOne`这个函数有代码点长,整体的功能可以概括为:

@ -145,7 +145,7 @@ ParallelizeUntil()的这种实现方式,可以很好地将并发实现和具
`pkg/scheduler/core/generic_scheduler.go:460 --> pkg/scheduler/internal/cache/node_tree.go:161`
![](http://pwh8f9az4.bkt.clouddn.com/zone.jpg)
![](http://mycloudn.kokoerp.com/zone.jpg)
可以看到这里有一个zone的逻辑层级这个层级仿佛没有见过google了一番才了解了这个颇为冷门的功能这是一个轻量级的支持集群联邦特性的实现单个cluster可以属于多个zone但这个功能目前只有GCE和AWS支持且绝大多数的使用场景也用不到可以说是颇为冷门。默认情况下cluster只属于一个zone可以理解为cluster和zone是同层级因此后面见到有关zone相关的层级我们直接越过它。有兴趣的朋友可以了解一下zone的概念:
@ -231,7 +231,7 @@ func podFitsOnNode(
有了以上理解,我们接着看代码,图中已注释:
![](http://pwh8f9az4.bkt.clouddn.com/podFitsOnNode.jpg)
![](http://mycloudn.kokoerp.com/podFitsOnNode.jpg)
图中`pkg/scheduler/core/generic_scheduler.go:608`位置正式开始了逐个计算筛选算法,那么筛选方法、筛选方法顺序在哪里呢?在上一篇[P2-框架篇]([https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/P2-%E8%B0%83%E5%BA%A6%E5%99%A8%E6%A1%86%E6%9E%B6.md](https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/P2-调度器框架.md))中已经有讲过,默认调度算法都在`pkg/scheduler/algorithm/`路径下,我们接着往下看.
@ -260,7 +260,7 @@ var (
[链接](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/predicates-ordering.md)
![](http://pwh8f9az4.bkt.clouddn.com/predicates.jpg)
![](http://mycloudn.kokoerp.com/predicates.jpg)
#### 筛选key
@ -385,4 +385,4 @@ func CheckNodeMemoryPressurePredicate(pod *v1.Pod, meta PredicateMetadata, nodeI
本篇调度器筛选算法篇到此结束,下一篇将学习调度器优先级排序的算法详情内容
本篇调度器筛选算法篇到此结束,下一篇将学习调度器优先级排序的算法详情内容

@ -18,7 +18,7 @@ Tips: 本篇篇幅较长,因调度优选算法较为复杂,但请耐心结
同上一篇,回到`pkg/scheduler/core/generic_scheduler.go`中的`Schedule()`函数,`pkg/scheduler/core/generic_scheduler.go:184`:
![](http://pwh8f9az4.bkt.clouddn.com/20190822165920.png)
![](http://mycloudn.kokoerp.com/20190822165920.png)
截图中有几处标注metric相关的几行是收集metric信息用以提供给prometheus使用的kubernetes的几个核心组件都有这个功能以后如果读prometheus的源码这个单独拎出来再讲。直接进入优先级函数`PrioritizeNodes()`内部`pkg/scheduler/core/generic_scheduler.go:215`
@ -201,7 +201,7 @@ func defaultPriorities() sets.String {
在注册的每一个计算维度都有专属的维度描述关键字即factory方法的第一个参数(str类型)。不难发现,这里的每一个关键字,`pkg/scheduler/algorithm/priorities`目录内都有与其对应的文件,图中圈出了几个例子(灵魂画笔请原谅):
![](http://pwh8f9az4.bkt.clouddn.com/image-20190821171031395.png)
![](http://mycloudn.kokoerp.com/image-20190821171031395.png)
显而易见,维度计算的内容就在这些文件中,可以自行通过编辑器的跳转功能逐级查看进行验证.
@ -239,7 +239,7 @@ func CalculateNodePreferAvoidPodsPriorityMap(pod *v1.Pod, meta interface{}, node
这也印证了前面说的当前仅剩pod亲和性这一个维度在使用传统的Function,虽然已经被DEPRECATED掉了传统的Function是直接计算出结果Map-Reduce是将这个过程解耦拆成了两个步骤且我们可以看到所有的factory函数很多形参`reduceFunction`接收到的实参实际是是`nil`:
![](http://pwh8f9az4.bkt.clouddn.com/image-20190822111624614.png)
![](http://mycloudn.kokoerp.com/image-20190822111624614.png)
这就说明这些维度的计算工作在map函数里面已经执行完成了不需要再执行reduce函数了。因此传统的Function的计算过程同样值得参考那么首先就来看看`InterPodAffinityPriority`维度是怎么计算的吧!
@ -634,4 +634,4 @@ fScore = float64(schedulerapi.MaxPriority) * ((pm.counts[node.Name] - minCount)
优先级算法相对而言比predicate断言算法要复杂一些并且在当前版本的维度计算中存在传统Function函数与Map-Reduce风格函数混用的现象一定程度上提高了阅读的难度但相信仔细重复阅读代码还是不难理解的毕竟数据量还未到达大数据的级别只是利用了其映射归纳的思想解耦的同时提高一定的并发性能。
下一篇讲什么呢我再研究研究have fun!
下一篇讲什么呢我再研究研究have fun!

Loading…
Cancel
Save