Reputation: 147
I am creating a controller that will watch a dpeloyment and its pods on a cluster. The watched deployment is not a custom resource. I have built out the controller with kubebuilder. For the purpose of this, the deployment is called "foo" in the namespace "bar" I have set up the SetupWithManager function to look like this
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)
This causes the reconcile loop to only work when events occur on "foo" and "bar". If my reconcile loop doesn't update anything within the deployment object, the loop stops running. I want the loop to run forever even if the controller considers the state to be "reconciled". Right now I've found a way around this problem by adding the following code to my reconcile loop.
...
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
}
This causes the reconcile loop to loop infinitely because the deployment is always updating.
I need the reconcile loop to constantly loop without stopping. Is there a better way to get around this issue or does this go against the design of what a controller should be?
Upvotes: 0
Views: 533
Reputation: 777
To schedule periodic re-queuing, use the RequeueAfter
attribute within the ctrl.Result
object that you're returning from your reconcile method:
return ctrl.Result{RequeueAfter: 5 * time.Minute}, nil
It will requeue the request after the specified delay. This approach is appropriate for actions that depend on external conditions that may change over time.
Upvotes: 0