Kubernetes Manifest Deletion Intent
Kubernetes Manifest Deletion Intent defines the purpose and process of removing Kubernetes resources, ensuring clean and intentional infrastructure management.
Kubernetes Manifest Deletion Intent is the problem of how to declaratively express that an object should no longer exist, a case the manifest format itself handles awkwardly since a manifest can only describe an object's presence and desired configuration, never its absence — meaning "this should be deleted" cannot be written as a field within a manifest the way "this should have three replicas" can, and must instead be expressed through the removal of the manifest itself, an explicit imperative delete command, or specialized tooling support layered on top of the base declarative model.
Why Deletion Doesn't Fit the Manifest Format Naturally
Manifests Describe Presence, Not Absence
A manifest's entire structure is built around describing an object that should exist in some particular configuration; there is no field within the object schema that means "and this object itself should be removed," since the API's delete operation is a distinct verb entirely separate from create, update, or patch, operating on an object's identity rather than its content.
The Absence-as-Deletion Convention
The nearest thing to expressing deletion declaratively is the convention that an object's absence from a manifest set implies it should be deleted, but this is only meaningful when paired with tooling that explicitly tracks which objects belong to a given manifest set and prunes accordingly — absence alone, without that tracking, is indistinguishable from an object that was simply never managed by this manifest set to begin with.
Pruning as Explicit Deletion Intent
Opt-In Pruning Behavior
As covered under declarative apply behavior, pruning must be explicitly requested (through a flag or a GitOps controller's configuration) precisely because absence-implies-deletion is too consequential a default; when enabled, the tool deletes any live object bearing the tracking label or annotation for that manifest set but no longer present in the manifest source, converting the manifest's silence about an object into an explicit deletion action.
Risks of Misconfigured Pruning Scope
If a prune-tracking label is applied too broadly, or a manifest source is misconfigured to believe it owns objects it does not, pruning can delete resources the operator never intended to remove, which is why prune-enabled workflows generally warrant a dry-run or explicit confirmation step, treating the deletion path with more caution than ordinary apply operations.
Kustomize's Explicit Deletion Directive
The $patch: delete Marker
Kustomize supports an explicit $patch: delete marker within a patch, allowing an overlay to declare that a specific object (or a specific field within an object) present in the base should be removed entirely for that overlay's environment, giving deletion intent a genuine, explicit place within the patch-based configuration model rather than relying solely on the absence-and-prune convention.
Scoped, Reviewable Removal
Because this directive is written explicitly into a patch file, the intent to remove a specific object for a specific environment becomes a reviewable, version-controlled statement rather than an implicit consequence of an object simply not appearing somewhere, which is a meaningfully clearer expression of deletion intent than relying purely on prune-by-absence.
Imperative Deletion as the Direct Alternative
kubectl delete -f
Running kubectl delete -f against a manifest deletes the object(s) that manifest describes, using the same identity-resolution logic apply uses, but expressing deletion as an explicit, one-time imperative action rather than an implicit consequence of an ongoing declarative reconciliation; this remains a common and clear way to express deletion intent for manual or scripted operations outside a fully automated GitOps pipeline.
GitOps Deletion via Manifest Removal Plus Sync
In a GitOps workflow, the equivalent of kubectl delete -f is committing the removal of a manifest file from the source repository, relying on the GitOps controller's pruning behavior (if enabled) to translate that removal into an actual cluster deletion on its next reconciliation pass, keeping deletion intent expressed entirely through version-controlled source changes rather than direct imperative commands.
Finalizers as a Separate, Orthogonal Concern
Finalizers Govern How Deletion Proceeds, Not Whether It Is Intended
It is worth distinguishing deletion intent from finalizer-gated deletion mechanics: a manifest or delete command expresses that an object should be removed, while any finalizers present on that object govern the cleanup sequence the removal must pass through before actually disappearing — the two concerns are independent, with intent determining that deletion should happen and finalizers determining how it happens.