Kubernetes Declarative Apply Behavior
Kubernetes Declarative Apply Behavior defines how cluster state changes are applied via manifests, ensuring consistent and predictable infrastructure management.
Kubernetes Declarative Apply Behavior is the specific set of edge-case semantics that determine what actually happens when a manifest is reapplied against an object whose live state has diverged from what was previously applied — covering field removal, fields never touched by apply, dry-run evaluation, and pruning of entire objects no longer present in a manifest set — behavior that is easy to get wrong intuitively because "apply" sounds simpler than the three-way reconciliation it actually performs. Getting these semantics right matters because a misunderstanding here commonly leads to fields silently persisting after being removed from a manifest, or unrelated fields being unexpectedly reset.
Removing a Field From a Manifest
Field Omission Does Not Always Mean Deletion
Simply deleting a line from a manifest and reapplying it does not automatically clear that field from the live object under client-side apply's three-way merge: because the merge compares last-applied configuration, the new manifest, and current live state, a field present in the last-applied configuration but absent from the new manifest is correctly recognized as intentionally removed and is cleared — but a field that was never part of any previously applied configuration (set some other way, such as by a defaulting mechanism or another controller) is left untouched, since apply has no record of ever having declared it.
Server-Side Apply's Cleaner Removal Semantics
Server-Side Apply handles this more predictably: because it tracks exactly which fields a given field manager owns, removing a field from the manifest and reapplying causes that field manager to relinquish ownership, and if no other field manager also owns it, the field is cleared; if another manager still owns it, the field is left in place with that other manager retaining responsibility for it.
Fields Never Set Through Apply
Coexistence With Other Writers
A field set by a different actor — a defaulting mechanism, a mutating webhook, or a separate controller such as the Horizontal Pod Autoscaler adjusting replica count — is not affected by an apply that never mentions that field, since neither client-side nor server-side apply attempts to reset fields it has no record of managing, which is precisely the behavior that allows autoscalers and GitOps tools to coexist on the same object without fighting.
The Risk of Accidentally Claiming a Field
If a manifest is authored to explicitly include a field that another actor is actively managing (such as hardcoding a replica count that the Horizontal Pod Autoscaler also adjusts), reapplying that manifest will overwrite the autoscaler's most recent value on every apply, which is a common source of "why does my replica count keep resetting" issues traceable directly to this apply behavior.
Dry-Run Evaluation
Client-Side Versus Server-Side Dry Run
A dry-run apply can be evaluated either purely on the client (checking manifest syntax and structure without contacting the API server) or as a server-side dry run, where the full request, including admission and validation, is processed by the API server exactly as a real request would be, except the result is never actually persisted — giving a far more accurate preview of what a real apply would produce, including any mutation from webhooks or defaulting.
Practical Use in Pipelines
Server-side dry-run apply is commonly used in CI pipelines to validate that a manifest would be accepted by a specific target cluster's admission configuration before merging a change, catching validation and policy failures earlier than they would otherwise surface, without any risk of the dry-run itself affecting live cluster state.
Pruning Objects No Longer Present
Prune as an Explicit Opt-In
By default, applying a set of manifests only creates or updates the objects present in that set; it does not delete objects that were previously applied from the same source but have since been removed from the manifest set, unless pruning is explicitly requested, since automatic deletion based on absence is judged too consequential to be the default behavior.
Tracking Which Objects Belong to a Prune Set
When pruning is enabled, the tool performing the apply needs a way to identify which live objects belong to the manifest set being reconciled, typically through a label or annotation applied consistently across the set, so that objects belonging to unrelated manifests are never mistakenly swept up in the pruning pass.