以下代码分析基于
kubernetes v1.12.0
版本。
scheduler的cmd
代码目录结构如下:
1 | kube-scheduler |
1. Main函数
此部分的代码为/cmd/kube-scheduler/scheduler.go
kube-scheduler
的入口函数Main
函数,仍然是采用统一的代码风格,使用Cobra命令行框架。
1 | func main() { |
核心代码:
1 | // 初始化scheduler命令结构体 |
2. NewSchedulerCommand
此部分的代码为/cmd/kube-scheduler/app/server.go
NewSchedulerCommand
主要用来构造和初始化SchedulerCommand结构体,
1 | // NewSchedulerCommand creates a *cobra.Command object with default parameters |
核心代码:
1 | // 构造option |
2.1. NewOptions
NewOptions主要用来构造SchedulerServer使用的参数和上下文,其中核心参数是KubeSchedulerConfiguration
。
1 | opts, err := options.NewOptions() |
NewOptions:
1 | // NewOptions returns default scheduler app options. |
2.2. Options.Config
Config初始化调度器的配置对象。
1 | c, err := opts.Config() |
Config函数主要执行以下操作:
- 构建scheduler client、leaderElectionClient、eventClient。
- 创建event recorder
- 设置leader选举
- 创建informer对象,主要函数有
NewSharedInformerFactory
和NewPodInformer
。
Config具体代码如下:
1 | // Config return a scheduler config object |
2.3. AddFlags
AddFlags
为SchedulerServer添加指定的参数。
1 | opts.AddFlags(cmd.Flags()) |
AddFlags函数的具体代码如下:
1 | // AddFlags adds flags for the scheduler options. |
3. Run
此部分的代码为/cmd/kube-scheduler/app/server.go
1 | err := Run(c.Complete(), stopCh) |
Run
运行一个不退出的常驻进程,来执行scheduler的相关操作。
Run函数的主要内容如下:
- 通过scheduler config来创建scheduler的结构体。
- 运行event broadcaster、healthz server、metrics server。
- 运行所有的informer并在调度前等待cache的同步(重点)。
- 执行
sched.Run()
来运行scheduler的调度逻辑。 - 如果多个scheduler并开启了
LeaderElect
,则执行leader选举。
以下对重点代码分开分析:
3.1. NewSchedulerConfig
NewSchedulerConfig初始化SchedulerConfig(此部分具体逻辑待后续专门分析),最后初始化生成scheduler结构体。
1 | // Build a scheduler config from the provided algorithm source. |
3.2. InformerFactory.Start
运行PodInformer,并运行InformerFactory。此部分的逻辑为client-go的informer机制,在Informer机制中有详细分析。
1 | // Start all informers. |
3.3. WaitForCacheSync
在调度前等待cache同步。
1 | // Wait for all caches to sync before scheduling. |
3.3.1. InformerFactory.WaitForCacheSync
InformerFactory.WaitForCacheSync
等待所有启动的informer的cache进行同步,保持本地的store信息与etcd的信息是最新一致的。
1 | // WaitForCacheSync waits for all started informers' cache were synced. |
接着调用cache.WaitForCacheSync
。
1 | // WaitForCacheSync waits for caches to populate. It returns true if it was successful, false |
3.3.2. controller.WaitForCacheSync
controller.WaitForCacheSync
是对cache.WaitForCacheSync
的一层封装,通过不同的controller的名字来记录不同controller等待cache同步。
1 | controller.WaitForCacheSync("scheduler", stop, s.PodInformer.Informer().HasSynced) |
controller.WaitForCacheSync
具体代码如下:
1 | // WaitForCacheSync is a wrapper around cache.WaitForCacheSync that generates log messages |
3.4. LeaderElection
如果有多个scheduler,并开启leader选举,则运行LeaderElector
直到选举结束或退出。
1 | // If leader election is enabled, run via LeaderElector until done and exit. |
3.5. Scheduler.Run
1 | // Prepare a reusable run function. |
Scheduler.Run
先等待cache同步,然后开启调度逻辑的goroutine。
Scheduler.Run的具体代码如下:
1 | // Run begins watching and scheduling. It waits for cache to be synced, then starts a goroutine and returns immediately. |
以上是对/cmd/kube-scheduler/scheduler.go
部分代码的分析,Scheduler.Run
后续的具体代码位于pkg/scheduler/scheduler.go
待后续文章分析。
参考:
赞赏一下