【发布时间】:2023-02-01 19:28:58
【问题描述】:
我已经通过 controller-runtime lib 为自定义资源 (CR) A 实现了一个控制器。 CR A 依赖于资源 B,因为
apiVersion: CRD.API.Version
kind: A
metadata:
name: a
spec:
bName: b
otherSpecs: ...
当 A 被协调时,我在我的控制器中的 B 实例上添加 ownerReference,这使我的控制器 Watches B 并且如果它的依赖 B 被更新,将触发 A 的协调。此外,当A被删除时,B上的相关ownerReference也会被删除:
func (r *MyReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&A{}).
Watches(&source.Kind{Type: &B{}}, &handler.EnqueueRequestForOwner{OwnerType: &A{}, IsController: false}).
Complete(r)
}
func (r *MyReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
a := &A{}
reconciler.Get(ctx, request.NamespacedName, a)
b := &B{}
reconciler.Get(ctx, NamespacedName{Name: a.Spec.bName, Namespace: a.Namespace}, b)
if !a.DeletionTimestamp.IsZero() {
clearOwnerReference(b)
reconciler.Update(ctx, b)
return ...
}
setOwnerReference(b.OwnerReference, a)
reconciler.Update(ctx, b)
// Other reconciliation logic
}
但是 Kubernetes API 服务器的动作更快:它检测到 B 是孤立的并删除 B,即 GC。
我还尝试在 B 上添加终结器。但是当我的控制器从 B 中删除 ownerReference 和 finalizers 时,它就消失了,因为它已经被标记为已删除。
B 上的任何其他配置都可以用来防止这种级联删除吗?或者处理这种依赖的任何最佳实践?
【问题讨论】:
-
我不确定我是否遵循您要执行的操作。您希望您的控制器由 A 和 B 的更新触发,而不是在删除 A 时级联删除 B?
-
提供代码 sn-ps 会很有帮助
标签: kubernetes