我正在开发一个k8s自定义资源,作为业务逻辑的一部分,当集群中的外部作业改变了自己的状态时,需要协调它的状态。
这些作业不是由自定义资源本身创建的,而是由外部为第三方服务创建的,但是我需要协调CRO的状态,例如当任何这些外部作业完成时。
在阅读了一堆文档之后,我想到了为控制器设置一个监视器,像下面的例子一样观察Jobs
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)
}
不,我有我的调和循环触发的工作和我的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
}
如何在调和对象类型中检查?所以我可以检索完整的对象数据调用r。
根据设计,触发协调的事件不会传递给协调器,因此您被迫定义状态并对其进行操作。这种方法被称为基于层次的方法,而不是基于边缘的方法。
在你的例子中,你有两个你试图跟踪的资源。我建议:
- 如果这些资源是相关的,使用ownerReferences或标签。这样,您可以获得给定作业的所有相关数据集(反之亦然),并以这种方式进行协调。
- 如果两个资源不相关,为每个资源创建单独的控制器。
如果您想阻止某些事件的协调,您可以使用谓词。从谓词函数中的事件中,您可以获得对象类型,例如e.Object.(*core.Pod)
。