英文:
Invoke kubernetes operator reconcile loop on external resources changes
问题
你可以通过检查 req.Kind
字段来确定对象的类型。在 Reconcile
方法中,你可以使用 req.Kind
来判断对象的类型,然后根据类型调用相应的 r.Get
方法来获取完整的对象数据。
以下是一个示例代码,展示了如何在 Reconcile
方法中检查对象类型:
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)
// Check the object kind
if req.Kind == "batchv1.Job" {
// Object is of type Job
job := &batchv1.Job{}
r.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, job)
// Process the Job object
// ...
} else if req.Kind == "datasetv1beta1.Dataset" {
// Object is of type Dataset
dataset := &datasetv1beta1.Dataset{}
r.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, dataset)
// Process the Dataset object
// ...
} else {
// Unknown object type
l.Info("Unknown object type", "Kind", req.Kind)
return ctrl.Result{}, nil
}
return ctrl.Result{}, nil
}
在上述示例中,我们通过检查 req.Kind
字段来确定对象的类型,然后根据类型调用相应的 r.Get
方法来获取完整的对象数据。你可以根据实际情况进行适当的处理和操作。
英文:
I'm working on developing a k8s custom resource that as part of the business logic needs to reconcile its state when an external Job in the cluster have changed its own state.
Those Jobs aren't created by the custom resource itself but are externally created for a third party service, however I need to reconcile the state of the CRO for example when any of those external jobs have finished.
After reading bunch of documentation, I came up with setting a watcher for the controller, to watch Jobs like the following example
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)
}
No I'm having my reconcile loop triggered for Jobs and my CRs with the corresponding name and namespace but I don't know anything about the object kind.
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
}
How can I check within Reconcile the object kind? so I can retrieve the full object data calling r.Get
答案1
得分: 2
根据设计,触发协调的事件不会传递给协调器,因此您被迫定义和处理状态。这种方法被称为“基于级别的,而不是基于边缘的”(http://venkateshabbarapu.blogspot.com/2013/03/edge-triggered-vs-level-triggered.html)。
在您的示例中,您有两个要跟踪的资源。我建议您采取以下措施之一:
- 如果这些资源相关,请使用ownerReferences或labels。这样,您可以获取给定作业(或反之)的所有相关数据集,并通过这种方式进行协调。
- 如果这两个资源不相关,请为每个资源创建一个单独的控制器。
如果您想要阻止某些事件上的协调,您可以使用谓词。通过谓词函数中的事件,您可以通过e.Object.(*core.Pod)
来获取对象类型,例如。
英文:
By design, the event that triggered reconciliation is not passed to the reconciler so that you are forced to define and act on a state instead. This approach is referred to as level-based, as opposed to edge-based.
In your example you have two resources you are trying to keep track of. I would suggest either:
- Using ownerReferences or labels if these resources are related. That way you can get all related Datasets for a given Job (or vice versa) and reconcile things that way.
- If the two resources are not related, create a separate controller for each resource.
If you want to prevent reconciliation on certain events you can make use of predicates. From the event in the predicate function you can get the object type by e.Object.(*core.Pod)
for example.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论