In this lesson, you will learn how to programmatically manage standard Kubernetes resources—like Deployments and Services—directly from your custom controller’s reconciliation loop.
Bridging the Controller to Cluster State
While CRDs define your custom resource (the "what"), the controller logic defines the "how." When your controller reconciles, it needs to ensure that the actual state of the cluster matches the desired state defined in your custom resource. To do this, you don’t just execute shell commands; you use the Kubernetes client library (typically controller-runtime) to interact with the API server.
When you want to manage a standard object like a Deployment, the pattern is always: Fetch, Compare, and Act.
Implementing Reconciliation Logic
Inside your Reconcile function, you will typically define the desired state of a child resource (e.g., a Deployment) and then use the client interface to apply it. A common strategy is to use CreateOrUpdate logic to ensure the resource exists exactly as intended:
// Define the desired Deployment
deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "my-app-deployment",
Namespace: req.Namespace,
},
}
// Ensure the deployment matches the desired state
_, err := controllerutil.CreateOrUpdate(ctx, r.Client, deployment, func() error {
deployment.Spec.Replicas = &desiredReplicas
deployment.Spec.Template.Spec.Containers = []corev1.Container{
{Name: "app", Image: "nginx:latest"},
}
// Set the controller as the owner so K8s handles garbage collection
return controllerutil.SetControllerReference(myCustomResource, deployment, r.Scheme)
})
The Role of Ownership
Notice the call to SetControllerReference. This is critical. By setting the custom resource as the "Owner" of the Deployment, you enable Kubernetes' built-in Garbage Collection. If a user deletes your Custom Resource, Kubernetes automatically knows to clean up the associated Deployment and Service without you writing extra deletion code.
By keeping your logic idempotent—meaning the reconciliation loop can run a thousand times with the same result—you transform your controller into a robust automation engine that heals itself whenever the cluster state drifts from your definitions.
Key Takeaway: Controllers manage standard Kubernetes objects by programmatically reconciling the cluster state to match the specs defined in your Custom Resources, utilizing owner references to ensure automated lifecycle management.