【问题标题】:How to prevent repeated reconcile calls如何防止重复的协调调用
【发布时间】:2023-04-07 05:03:01
【问题描述】:

我正在开发一个 Kubernetes 控制器。此控制器的所需状态在 CRD-A 中捕获,然后它创建部署和状态集以实现实际状态。目前我正在使用服务器端应用来创建/更新这些部署和状态集。

控制器在 CRD-A 以及部署、statefulset 上建立监视。这是为了确保如果部署/状态集发生更改,则通知 reconcile() 并采取措施修复它。目前 reconcile() 总是调用服务器端 apply 来创建/更新,这会导致另一个监视事件(每个服务器端应用资源版本更改)导致重复/无限调用 reconcile()

我一直在考虑的一种方法是在部署/状态集上利用“生成”,即控制器将维护 (k8s 对象 -> 生成) 的内存映射并在 reconcile() 上比较此映射中的值索引的告密者缓存中存在的内容;你觉得这种方法有什么顾虑吗?是否有更好的替代方法来防止重复/无限 reconcile() 调用?

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    如果没有要应用的更改,一个想法可能是不应用对象。 这给您带来了如何检测对象是否已经是最新的问题,但很难判断这在您的情况下是否可行。

    【讨论】:

      【解决方案2】:

      理想情况下,如果您在服务器端应用中提供的对象未更改,则该对象的生成和资源版本都不应更改。

      但有时情况并非如此,请参阅这个 github 问题:https://github.com/kubernetes/kubernetes/issues/95460

      幸运的是,生成始终保持不变,所以是的,您可以利用此字段来避免协调死循环,方法是向控制器添加 GenerationChangedPredicate 过滤器,如果生成不更改,它将跳过协调,并且它通常与LabelChangedPredicate 结合使用,当对象的标签没有改变时过滤事件。

      以下是使用这两个谓词设置控制器的方法:

      ctrl.NewControllerManagedBy(mgr).
          For(&Object{}).
          Owns(&appsv1.StatefulSet{}).
          Owns(&appsv1.Deployment{}).
          // together with Server Side Apply
          // this predicates prevents meaningless reconcilations from being triggered
          WithEventFilter(predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{})).
          Complete(r)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-13
        • 2021-09-13
        • 2017-08-31
        • 2015-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多