Skip to content

Commit

Permalink
Add a guide describing ownerReference usage in CAPI
Browse files Browse the repository at this point in the history
Signed-off-by: killianmuldoon <kmuldoon@vmware.com>
  • Loading branch information
killianmuldoon committed Aug 8, 2023
1 parent 99009fe commit 346698a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,4 @@
- [Code Review in Cluster API](./REVIEWING.md)
- [Version Support](./reference/versions.md)
- [Supported Labels and Annotations](./reference/labels_and_annotations.md)
- [Owner References](./reference/owner_references.md)
79 changes: 79 additions & 0 deletions docs/book/src/reference/owner_references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Owner References


Cluster API uses [Kubernetes owner references](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/) to track relationships between objects. These references are used for Kubernetes garbage collection, which is the basis of Cluster deletion in CAPI. They are also used places where the ownership hierarchy is important, for example when using `clusterctl move`.

CAPI uses owner references in an opinionated way. The following guidelines should be considered:
- objects should always be created with an ownerReference to prevent leaking objects. Initial ownerReferences can be replaced later where another object is a more appropriate owner.
- Owner references should be re-reconciled if they are lost for an object. This is required as some tools - e.g. velero - may delete owner references on objects.
- Owner references should be kept to the most recent apiVersion.
- This ensures garbage collection still works after an old apiVersion is no longer served.
- Owner references should not be added unless required.
- Multiple ownerReferences on a single object should be exceptional.




## OwnerReference relationships in Cluster API

The below tables map out the a reference for ownership relationships for the objects in a Cluster API cluster.
Note: Providers may implement their own ownership relationships which may or may not map directly to the below tables.

## Kubernetes core types

| type | Owner | Note |
|-----------|---------------------|--------------------------|
| Secret | KubeadmControlPlane | For cluster certificates |
| Secret | KubeadmConfig | For bootstrap secrets |
| Secret | ClusterResourceSet | When created by CRS |
| ConfigMap | ClusterResourceSet | |

## Core types

| type | Owner | Note |
|---------------------|-------------------|----------------------------|
| ExtensionConfig | None | |
| ClusterClass | None | |
| Cluster | None | |
| MachineDeployments | Cluster | |
| MachineSet | MachineDeployment | |
| Machine | MachineSet | When created by MachineSet |
| Machine | ControlPlane | When created by KCP |
| MachineHealthChecks | Cluster | |



## Experimental types
| type | Owner | Note |
|----------------------------|--------------------|------|
| ClusterResourcesSet | None | |
| ClusterResourcesSetBinding | ClusterResourceSet | |
| MachinePool | Cluster | |


## KubeadmControlPlane types
| type | Owner | Note |
|-----------------------------|--------------|------|
| KubeadmControlPlane | Cluster | |
| KubeadmControlPlaneTemplate | ClusterClass | |


## Kubeadm bootstrap types
| type | Owner | Note |
|-----------------------|--------------|---------------------------------|
| KubeadmConfig | Machine | When created by MachineSet |
| KubeadmConfig | MachinePool | When created by MachinePool |
| KubeadmConfigTemplate | Cluster | When referenced in Machine spec |
| KubeadmConfigTemplate | ClusterClass | When referenced in ClusterClass |

## Infrastructure provider types
| type | Owner | Note |
|-------------------------------|--------------|---------------------------------------------|
| InfrastructureMachine | Machine | |
| InfrastructureMachineTemplate | Cluster | When created by cluster topology controller |
| InfrastructureMachineTemplate | ClusterClass | When referenced in a ClusterClass |
| InfrastructureCluster | Cluster | |
| InfrastructureClusterTemplate | ClusterClass | |
| InfrastructureMachinePool | MachinePool | |


16 changes: 14 additions & 2 deletions test/framework/ownerreference_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ var (

// CoreOwnerReferenceAssertion maps Cluster API core types to functions which return an error if the passed
// OwnerReferences aren't as expected.
// Note: These relationships are documented in https://github.com/kubernetes-sigs/cluster-api/tree/main/docs/book/src/reference/owner_references.md.
// That document should be updated if these references change.
var CoreOwnerReferenceAssertion = map[string]func([]metav1.OwnerReference) error{
extensionConfigKind: func(owners []metav1.OwnerReference) error {
// ExtensionConfig should have no owners.
Expand Down Expand Up @@ -161,6 +163,8 @@ var (

// ExpOwnerReferenceAssertions maps experimental types to functions which return an error if the passed OwnerReferences
// aren't as expected.
// Note: These relationships are documented in https://github.com/kubernetes-sigs/cluster-api/tree/main/docs/book/src/reference/owner_references.md.
// That document should be updated if these references change.
var ExpOwnerReferenceAssertions = map[string]func([]metav1.OwnerReference) error{
clusterResourceSetKind: func(owners []metav1.OwnerReference) error {
// ClusterResourcesSet doesn't have ownerReferences (it is a clusterctl move-hierarchy root).
Expand All @@ -184,6 +188,8 @@ var (

// KubernetesReferenceAssertions maps Kubernetes types to functions which return an error if the passed OwnerReferences
// aren't as expected.
// Note: These relationships are documented in https://github.com/kubernetes-sigs/cluster-api/tree/main/docs/book/src/reference/owner_references.md.
// That document should be updated if these references change.
var KubernetesReferenceAssertions = map[string]func([]metav1.OwnerReference) error{
secretKind: func(owners []metav1.OwnerReference) error {
// Secrets for cluster certificates must be owned by the KubeadmControlPlane. The bootstrap secret should be owned by a KubeadmControlPlane.
Expand All @@ -205,27 +211,31 @@ var (

// KubeadmControlPlaneOwnerReferenceAssertions maps Kubeadm control plane types to functions which return an error if the passed
// OwnerReferences aren't as expected.
// Note: These relationships are documented in https://github.com/kubernetes-sigs/cluster-api/tree/main/docs/book/src/reference/owner_references.md.
// That document should be updated if these references change.
var KubeadmControlPlaneOwnerReferenceAssertions = map[string]func([]metav1.OwnerReference) error{
kubeadmControlPlaneKind: func(owners []metav1.OwnerReference) error {
// The KubeadmControlPlane must be owned by a Cluster.
return hasExactOwnersByGVK(owners, []schema.GroupVersionKind{clusterGVK})
},
kubeadmControlPlaneTemplateKind: func(owners []metav1.OwnerReference) error {
// The KubeadmControlPlaneTemplate must be owned by a ClusterClass.
// The KubeadmControlPlane must be owned by a ClusterClass.
return hasExactOwnersByGVK(owners, []schema.GroupVersionKind{clusterClassGVK})
},
}

// Kind and GVK for types in the Kubeadm Bootstrap package.
var (
kubeadmConfigKind = "KubeadmConfig"
kubeadmConfigTemplateKind = "KubeadmConfigTemplate"
kubeadmConfigTemplateKind = "KubeadmConfig"

kubeadmConfigGVK = bootstrapv1.GroupVersion.WithKind(kubeadmConfigKind)
)

// KubeadmBootstrapOwnerReferenceAssertions maps KubeadmBootstrap types to functions which return an error if the passed OwnerReferences
// aren't as expected.
// Note: These relationships are documented in https://github.com/kubernetes-sigs/cluster-api/tree/main/docs/book/src/reference/owner_references.md.
// That document should be updated if these references change.
var KubeadmBootstrapOwnerReferenceAssertions = map[string]func([]metav1.OwnerReference) error{
kubeadmConfigKind: func(owners []metav1.OwnerReference) error {
// The KubeadmConfig must be owned by a Cluster or by a MachinePool.
Expand All @@ -248,6 +258,8 @@ var (

// DockerInfraOwnerReferenceAssertions maps Docker Infrastructure types to functions which return an error if the passed
// OwnerReferences aren't as expected.
// Note: These relationships are documented in https://github.com/kubernetes-sigs/cluster-api/tree/main/docs/book/src/reference/owner_references.md.
// That document should be updated if these references change.
var DockerInfraOwnerReferenceAssertions = map[string]func([]metav1.OwnerReference) error{
dockerMachineKind: func(owners []metav1.OwnerReference) error {
// The DockerMachine must be owned by a Machine.
Expand Down

0 comments on commit 346698a

Please sign in to comment.