3.2.1 Manager初始化
通过构建 CRD的 API、Controller,我们已经明确,CRD 是用户自定义的资源,用户自定义它的协调逻辑。那么要想实现自定义 CRDController 协调逻辑的安装、运行,这离不开 Manager结构对象。那么Manager 是如何来初始化的呢?在介绍之前,我们先明确Kubernetes是一套以Go语言来实现的 PaaS编排平台。因此,这里实现的Controller主程序也是 Go语言支持的,它的入口方法是 main文件中的main()方法。
通过 Kubebuilder工具创建的 API资源,除了创建 CRD文件外,还生成了运行Controller文件的入口方法的 main文件。CRDmain文件的产生过程还是比较简单的,感兴趣的读者可以自行阅读Kubebuilder的源码(github上)。通过 main 的模板,根据定义的CRD类型、版本等信息,渲染出 main文件的内容。它的内容大致包含 Manager的初始化、CRD的安装、Manager的启动。
下面我们通过截取部分代码片段来帮助读者理解 Manager的初始化过程(不是连续的文件)。Manager初始化是借助于ctrl.NewManager 方法实现的,而这个方法的位置指向Controller-runtime包的 manager.New方法,在New 的方法中,实际是根据传入的参数进行 Manager对象的 Scheme、Cache、Client 等模块的初始化构建。这也是在前面介绍Kubebuilder框架时,我们提到的 Client、Cache等内容。而 Manager的New方法中的Scheme变量,是借助Kubebuilder工具,根据用户 CRD生成主程序main.go 的入口函数main方法传入的,即这里的Scheme已经绑定了用户 CRD。然后,初始化 Manager对象构建出来后,通过 Manager的Cache监听 CRD,一旦 CRD在集群中创建了,Cache监听到发生了变化,就会触发Controller的协调程序 Reconcile工作,具体内容见代码清单3-7。
//Kubebuilder初始化 Manager对象
mgr,err:=ctrl.NewManager(ctrl.GetConfigOrDie(),ctrl.Options{
Scheme: scheme,MetricsBindAddress:metricsAddr,Port: 9443,
LeaderElection: enableLeaderElection,
LeaderElectionID: "{{hashFNV.Repo}}.{{.Domain}}",
})
//初始化失败,退出主程序
iferr!=nil{
setupLog.Error(err,"unabletostartmanager")os.Exit(1)
}
//controller-runtime/pkg/manager/manager.go⽂件中的New⽅法
funcNew(config*rest.Config,optionsOptions)(Manager,error){
return&controllerManager{
scheme: options.Scheme,
cache: cache,
client: writeObj,
...
}
}
//Options定义了创建⼀个 Manager对象的参数结构体
typeOptionsstruct{Scheme*runtime.Scheme
...
}