- Explain why CRDs are useful only when paired with controllers.
- Describe the reconciliation loop and its governing principles.
- Describe controller architecture and the typical reconcile function shape.
- Cover status reporting with conditions and observedGeneration.
- Implement finalizers for cleanup on deletion.
- Compare common operator frameworks so you can pick the right one.

kubectl apply.




- CRD is the menu: it defines what can be requested.
- CR (the object you apply) is the order you place.
- Controller is the kitchen: it actually prepares the meal and reports progress.
- Watch / observe — get notifications for creates/updates/deletes.
- Compare — compute desired state (from
spec) vs actual state (external resources, cloud APIs, cluster objects). - Act — create/update/delete resources to close the gap.
- Report — update the CR’s
status(conditions, observedGeneration, phase).
- If the external DB does not exist, create it.
- If the
sizechanged, resize the DB. - If the CR is deleted, perform cleanup.
- Update
statusto show provisioning progress or readiness.
- Level-triggered: react to current state, not transient events. If an event is missed, the next reconcile still inspects state and corrects drift.
- Idempotency: running Reconcile multiple times should produce the same final result as running it once—always check current state first.
- Eventual consistency: the system can take multiple reconciles to converge; expect retries and backoff.

Progressing while the controller continues to reconcile and later update Ready.
Controller internals: four collaborating layers
Most operator frameworks implement this architecture for you; your job is to implement the Reconciler (the business logic).
- API server — source of truth and where desired state is stored.
- Informer — watches API server and maintains a local cache to reduce API traffic.
- Work queue — the informer enqueues resource keys; queue deduplicates events so the reconciler runs for the latest state.
- Reconciler — your implementation: read resource, compare desired vs actual, act, and return a result (requeue/no-requeue/error).



Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error).
- Always fetch the latest object from the API server or cache.
- Handle deletion via finalizers and short-circuit if the object is gone.
- Make operations idempotent — check external state before making changes.
- Use the
statussubresource to update fields likeobservedGenerationandconditions.
type, status (True/False/Unknown), reason, and message.
Common condition types:
Available/Ready— resource is ready to serve.Progressing— creation/update is in progress.Degraded— running but not operating correctly.
spec, Kubernetes increments metadata.generation. Your controller sets status.observedGeneration to the generation it last reconciled. Comparing metadata.generation and status.observedGeneration tells users whether the controller has acted on the latest change.

deletionTimestamp but keeps the object until finalizers are cleared—this is the controller’s opportunity to delete external resources (cloud instances, secrets, networks).
Typical finalizer handling:
- User runs
kubectl delete. - API server sets
deletionTimestampand retains the object. - Controller observes the timestamp, performs cleanup, and removes finalizers.
- When no finalizers remain, the API server deletes the object.
If cleanup fails (for example, cloud API outages), the object will remain in a Terminating state while finalizers persist. Implement robust retries, exponential backoff, and comprehensive logging so cleanup eventually completes and you avoid orphaned resources.

Key takeaways

- CRDs without controllers are just stored data — controllers make the desired state become real.
- Design your Reconcile to be idempotent and level-triggered: always read current state and act only when needed.
- Use
status, conditions, andobservedGenerationto transparently communicate what the controller has processed. - Implement finalizers to clean up external resources; handle errors with retries and backoff to avoid stuck Terminating objects.
- Kubernetes controllers & reconciliation concepts: https://kubernetes.io/docs/concepts/architecture/controller/
- controller-runtime (Reconcile signature and helpers): https://github.com/kubernetes-sigs/controller-runtime
- Kubebuilder book: https://book.kubebuilder.io/
- Operator SDK docs: https://sdk.operatorframework.io/
- Metacontroller: https://metacontroller.github.io/