hello云胜

技术与生活

0%

kubebuilder(五)operator运行逻辑

前面我们先简单介绍了operator的项目结构,现在来深入聊聊operator的运行逻辑

Controller 的架构图

img

这是kubebuilder生成的operator项目架构图

img

operator项目的启动逻辑

1.在main.go启动函数中,实例化一个Manager对象。

1
2
3
4
5
6
7
8
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "f6f7ca38.demo.com",
})

注意看ctrl.Options,默认是监听所有namespace。

1
2
3
4
5
ctrl.Options{
Scheme: scheme,
Namespace: xxnamespace,
MetricsBindAddress: metricsAddr,
}

可以监听指定的namespace。

想要监听多个namespace,可以使用MultiNamespacedCacheBuilder

1
2
3
4
5
ctrl.Options{
Scheme: scheme,
NewCache: cache.MultiNamespacedCacheBuilder([]string{"default", "demo"}),
MetricsBindAddress: metricsAddr,
}

在修改了Operator作用域后,需同时修改RBAC(config/rbac/… 路径下相关yaml文件),以授权Operator操作该namespace下的资源。

2.通过SetUpWithManager()方法,注册资源对象的controller到Manager对象中。

1
2
3
4
5
6
7
if err = (&controllers.DemoReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Demo")
os.Exit(1)
}

作用就是把我们的DemoReconciler控制器绑定到Manager上

主要的代码逻辑在SetUpWithManager()方法里

1
2
3
4
5
6
// SetupWithManager sets up the controller with the Manager.
func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&tutorialv1.Demo{}).
Complete(r)
}

ctrl.NewControllerManagedBy(mgr)返回一个controller的构造器builder,然后通过For方法进行设置,这里就是设置为我们编写的自定义资源tutorialv1.Demo,表示要监听这个资源。监听了之后,干什么呢?就是Complete()方法,你看Complete的参数就是r,这个r就是我们写的DemoReconciler。所以,SetupWithManager方法就是说监听我们的crd资源,有任何变化都去执行他的Reconcile()方法。

继续往下追,Complete()方法会调用Builder.Build()进行构造。

Builder.Build()里又包含doController()和doWatch()这两个重要方法。

doController通过资源对象的 GVK 来获取 Controller 的名称,最后通过一个 newController 函数来实例化Controller。

DoWatch就是调用controller.watch来注册EventHandler事件。

启动controllerManager,也就是启动我们编写的crd对象的controller

1
2
3
4
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}

主要的代码逻辑在mgr.Start()方法里