我正在创建一个控制器,用于监视集群上的部署及其 Pod。监视的部署不是自定义资源。我已经用 kubebuilder 构建了控制器。为此,部署在命名空间“bar”中称为“foo”,我已将 SetupWithManager 函数设置为如下所示
func (r *DeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error {
namespace := "foo"
deployment:= "bar"
return ctrl.NewControllerManagedBy(mgr).
Owns(&appsv1.Deployment{}).
For(&appsv1.Deployment{}, builder.WithPredicates(predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
//fmt.Println(e)
return e.Object.GetNamespace() == namespace && e.Object.GetName() == deployment
},
UpdateFunc: func(e event.UpdateEvent) bool {
//fmt.Println(e)
return e.ObjectNew.GetNamespace() == namespace && e.ObjectNew.GetName() == deployment
},
DeleteFunc: func(e event.DeleteEvent) bool {
//fmt.Println(e)
return e.Object.GetNamespace() == namespace && e.Object.GetName() == deployment
},
GenericFunc: func(e event.GenericEvent) bool {
return e.Object.GetNamespace() == namespace && e.Object.GetName() == deployment
},
})).
Complete(r)
这会导致协调循环仅在“foo”和“bar”上发生事件时才起作用。如果我的协调循环没有更新部署对象中的任何内容,则循环将停止运行。即使控制器认为状态已“协调”,我也希望循环永远运行。现在,我通过将以下代码添加到我的协调循环中找到了解决此问题的方法。
...
if val, ok := testdeploy.Labels["foo"]; ok && val == "bar" {
testdeploy.Labels["foo"] = "blah"
} else {
testdeploy.Labels["foo"] = "bar"
}
err = r.Update(ctx, testdeploy)
if err != nil {
return ctrl.Result{}, err
}
这会导致协调循环无限循环,因为部署始终在更新。
我需要协调循环不断循环而不停止。有没有更好的方法来解决这个问题,或者这是否违背了控制器的设计?
要安排定期重新排队,请使用从协调方法返回的
RequeueAfter
对象中的 ctrl.Result
属性:
return ctrl.Result{RequeueAfter: 5 * time.Minute}, nil