Finalizers: When and Why
Finalizers prevent resource deletion until cleanup runs.
When
The finalizer pattern is Kubernetes' mechanism for ensuring cleanup before resource deletion. Resources with external dependencies use finalizers to perform their cleanup; deletion is blocked until cleanup completes.
What when-to-use looks like:
- Resource has external dependencies.: Some Kubernetes resources represent external state. Cloud resources (S3 buckets, GCS buckets), DNS records, external services all are external dependencies that need cleanup.
- Cloud resources.: A custom resource representing an S3 bucket needs to delete the actual S3 bucket on Kubernetes resource deletion. The finalizer ensures the cloud resource is cleaned up before the Kubernetes resource is removed.
- DNS records.: Resources that create DNS records use finalizers. The DNS record is removed before the Kubernetes resource; the discipline prevents orphaned DNS entries.
- Cleanup before delete.: The pattern is "do cleanup first; then allow Kubernetes to delete." The finalizer is the mechanism; the controller is the cleanup actor; the order is enforced.
- Standard pattern for operators.: Custom Kubernetes operators frequently use finalizers. The discipline is part of the operator's design; the cleanup is reliable.
The when-to-use is clear. External state needs cleanup; finalizers are the mechanism.
How
The mechanism is straightforward. Add finalizer to the resource; the controller observes; the controller cleans up; the controller removes the finalizer; Kubernetes proceeds with deletion.
- Add finalizer.: The resource's metadata.finalizers includes a name. The name identifies which controller owns the cleanup; multiple controllers can have different finalizers.
- Controller removes after cleanup.: The controller observes the resource's deletionTimestamp (set when delete is requested). The controller does its cleanup; once cleanup is complete, the controller removes its finalizer from the metadata.
- Block delete until finalizer removed.: Kubernetes does not actually delete a resource while finalizers are present. The deletionTimestamp is set; the resource is in a terminating state; deletion happens only when all finalizers are gone.
- Multiple finalizers.: Resources can have multiple finalizers. Each must be removed before deletion; multiple controllers can perform cleanup independently.
- Idempotent cleanup.: The controller's cleanup must be idempotent. The controller may run multiple times before the cleanup completes; idempotent cleanup is safe.
The mechanism is well-defined. Once understood, it is straightforward to implement.
Avoid
The most common problem with finalizers is when they get stuck. The controller is not running; the cleanup cannot complete; the resource cannot be deleted; the team must intervene.
- Stuck finalizers.: If the responsible controller is not running, the finalizer is never removed. The resource stays in terminating state; new resources of the same kind may not be creatable; the team must intervene.
- If controller is broken.: A bug in the controller can prevent cleanup. The finalizer never gets removed; the resource is stuck; the team's investigation focuses on the controller.
- Resource cannot be deleted.: The stuck finalizer prevents deletion. Even kubectl delete cannot proceed; the resource persists in terminating state.
- Force-remove finalizer with --grace-period=0.: kubectl patch can remove finalizers manually. The patch removes the finalizer; Kubernetes proceeds with deletion; the discipline includes this escape hatch.
- Use force-remove cautiously.: Manually removing finalizers bypasses cleanup. The external state may not be cleaned up; orphaned cloud resources or DNS records may persist; the team's investigation includes external cleanup.
Finalizer pattern is one of those Kubernetes platform engineering disciplines that pays off when external state matters. Nova AI Ops integrates with custom resources, surfaces patterns, and supports the team's CRD-driven discipline.