在外部资源更改时调用 kubernetes operator reconcile 循环

Invoke kubernetes operator reconcile loop on external resources changes

我正在开发一个 k8s 自定义资源,作为业务逻辑的一部分,当集群中的外部作业改变了它自己的状态时,它需要协调它的状态。

这些作业不是由自定义资源本身创建的,而是为第三方服务在外部创建的,但是我需要协调 CRO 的状态,例如当任何这些外部作业完成时。

在阅读了一堆文档之后,我想到了为控制器设置一个观察者,像下面的例子一样观察乔布斯

func (r *DatasetReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&datasetv1beta1.Dataset{}).
        Watches(&source.Kind{Type: &batchv1.Job{}}, &handler.EnqueueRequestForObject{} /* filter by predicates, see https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.9.6/pkg/controller#Controller */).
        Complete(r)
}

不,我正在使用相应的 namenamespace 为 Jobs 和我的 CR 触发协调循环,但我没有对对象种类一无所知。

func (r *DatasetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    l := log.FromContext(ctx)
    l.Info("Enter Reconcile loop")
    l.Info("Request", "Req", req)

    //if this is triggered by my CR
    dataset := &datasetv1beta1.Dataset{}
    r.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, dataset)
    //whereas when triggered by a Job
    job := &batchv1.Job{}
    r.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, job)


    return ctrl.Result{}, nil
}

如何在 Reconcile 中检查对象种类?所以我可以检索完整的对象数据调用 r.Get

根据设计,触发协调的事件不会传递给协调器,因此您不得不定义状态并根据状态采取行动。这种方法被称为 level-based, as opposed to edge-based.

在您的示例中,您尝试跟踪两个资源。我会建议:

  1. 如果这些资源相关,则使用 ownerReferences 或标签。这样你就可以获得给定作业的所有相关数据集(反之亦然)并以这种方式协调。
  2. 如果两个资源不相关,则为每个资源创建一个单独的控制器。

如果您想防止对某些事件进行协调,您可以使用谓词。例如,从谓词函数中的事件,您可以通过 e.Object.(*core.Pod) 获取对象类型。