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