一、概述
Operator 的运行机制是作为自定义扩展资源注册到Controller Manager,通过List-Watch的方式监听对应资源的变化。controller-runtime 是 Kubernetes 社区提供可供快速搭建一套 实现了controller 功能的工具,对client-go进行了封装,用户无需自行实现Controller的功能了,只需关注Reconciler即可。
二、main函数入口
func main() {
// 1.构建controllerManager
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "1de8eaa9.demo.kubebuilder.io",
})
// 2.将reconciler添加到controllerManager中
if err = (&controllers.MyNginxReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "MyNginx")
os.Exit(1)
}
//+kubebuilder:scaffold:builder
setupLog.Info("starting manager")
// 3.启动controllerManager
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
}
2.1 SetupWithManager
SetupWithManager做了三件事情:
- 构建一个controller,并加入到controllerManager中
- 为该controller设置watch对象,也就是myappv1.MyNginxUss{}
- 为该controller设置Reconciler,也就是MemcachedReconciler
// SetupWithManager sets up the controller with the Manager.
func (r *MyNginxReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
//设置监听对象
For(&myappv1.MyNginxUss{
}).
//创建controller
Complete(r)
}
// Complete builds the Application Controller.
func (blder *Builder) Complete(r reconcile.Reconciler) error {
_, err := blder.Build(r)
return err
}
// Build builds the Application Controller and returns the Controller it created.
func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, error) {
if r == nil {
return nil, fmt.Errorf("must provide a non-nil Reconciler")
}
if blder.mgr == nil {
return nil, fmt.Errorf("must provide a non-nil Manager")
}
if blder.forInput.err != nil {
return nil, blder.forInput.err
}
// Checking the reconcile type exist or not
if blder.forInput.object == nil {
return nil, fmt.Errorf("must provide an object for reconciliation")
}
// Set the ControllerManagedBy
//创建controller
if err := blder.doController(r); err != nil {
return nil, err
}
// Set the Watch
//创建watch
if err := blder.doWatch(); err != nil {
return nil, err
}
return blder.ctrl, nil
}
先看doController():
func (blder *Builder) doController(r reconcile.Reconciler) error {
globalOpts := blder.mgr.GetControllerOptions()
ctrlOptions := blder.ctrlOptions
if ctrlOptions.Reconciler == nil {
//设置reconciler
ctrlOptions.Reconciler = r
}
//省略代码
......
// Build the controller and return.
//创建controller
blder.ctrl, err = newController(blder.getControllerName(gvk), blder.mgr, ctrlOptions)
return err
}
//newController就是调用这个方法
// New returns a new Controller registered with the Manager. The Manager will ensure that shared Caches have
// been synced before the Controller is Started.
func New(name string, mgr manager.Manager, options Options) (Controller, error) {
//创建了controller
c, err := NewUnmanaged(name, mgr, options)
if err != nil {
return nil, err
}
// Add the controller as a Manager components
//将controller加入到Manage中
return c, mgr.Add(c)