samba-operator
samba-operator copied to clipboard
need to check if calls should use SetOwnerReference
Currently we use SetControllerReference all over the place, but this may not be the best choice.
Don't we need to add Owns(&corev1.ConfigMap{}), Owns(&corev1.Service{}) and Owns(&appsv1.StatefulSet) within SetupWithManager() as they are ControllerManagedBy generated objects? Then it completely makes sense to use SetControllerReference by all means.
Some excerpts from related docs:
- https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMeta
// List of objects depended by this object. If ALL objects in the list have
// been deleted, this object will be garbage collected. If this object is managed by a controller,
// then an entry in this list will point to this controller, with the controller field set to true.
// There cannot be more than one managing controller.
// +optional
// +patchMergeKey=uid
// +patchStrategy=merge
OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"`
- https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#SetControllerReference
func SetControllerReference
SetControllerReference sets owner as a Controller OwnerReference on controlled. This is used for
garbage collection of the controlled object and for reconciling the owner object on changes to
controlled (with a Watch + EnqueueRequestForOwner). Since only one OwnerReference can be a
controller, it returns an error if there is another OwnerReference with Controller flag set.
Note: SetOwnerReference doesn't have the notion of controller
And if needed, what kind of predicate should be used? (e.g., ocs-operator uses different predicates for its owned resources: https://github.com/red-hat-storage/ocs-operator/blob/main/controllers/storagecluster/storagecluster_controller.go#L124-L126)
Let's start off with some reference links related to owner references:
https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil
https://github.com/kubernetes-sigs/controller-runtime/blob/v0.12.3/pkg/controller/controllerutil/controllerutil.go#L96 https://github.com/kubernetes-sigs/controller-runtime/blob/v0.12.3/pkg/controller/controllerutil/controllerutil.go#L59
https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#OwnerReference
https://stackoverflow.com/questions/51068026/when-exactly-do-i-set-an-ownerreferences-controller-field-to-true
https://github.com/kubernetes/design-proposals-archive/blob/main/api-machinery/controller-ref.md
And here's the owns function: https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/builder#Builder.Owns
The way I understand it is that the k8s API has a mechanism for tracking resource "ownership". This is part of the resource metadata and helps decide two things: (1) when should k8s garbage collect resources and (2) disambiguate what resource is supposed to have control over another.
Each resource can have a list (slice in the Go code) of owner references. The owner references are automatically removed from a resource when the "owning" resource is removed. If the last owner is being removed the resource can be garbage collected. In the owner references exactly 1 of the references can be the "controller" (not to be confused the the code executing a "controller"). If there's some sort of resource conflict the "contoller owner" gets final say.
If resource-A triggers resource-B to be created it is reasonable to create resource-B with resource-A as the controller-owner. If you inspect the metadata of resource-A you won't see any (direct) refrences to resource-B. Only resource-B will record the resources that own it.
One additional wrinkle is the controllers (the code) often want to trigger a reconcile loop when one of the owned objects is changed, not just when the owner changes. To have the controller-runtime framework watch these objects the Owns method can be used in conjunction with setting the objects as owned.
The Owns method basically tells the controller to set a special watch for these "child" resources. The doc even says: "This is the equivalent of calling Watches(...). " [elision mine]. The options types that can follow Owns or Watches can act as filters so that certain events don't trigger the reconcile function. IIUC, you can define a predicate function so that only changes to an object's spec section trigger a reconcile but, for example, it may ignore a change to annotations.
A resource without a controller-owner can (should?) be "adopted" by another owner.
(Personally, I think the overuse of the words own & controller here are extremely confusing. IMO, in particular the Owns method could have been called something like WatchOwnedResource to be much clearer about what it does. )
Slippery touchpads suck.