advanced25 min studyLesson 355 in Engineering

Finalizers: make deletion wait for verifiable cleanup

Trace deletion timestamps and controller-owned cleanup while avoiding duplicate side effects and unsafe forced removal.

On this page

What you’ll understand

  • Explain the deletion-requested state of an object with finalizers.
  • Order finalizer registration and external provisioning safely.
  • Design repeatable cleanup and remove only the controller’s own finalizer.

Deleting an API object can require work outside the API server, such as releasing an external allocation. A finalizer records that a controller must finish its cleanup obligation before the object can disappear through the normal deletion flow. The finalizer is a key in metadata, not executable cleanup code. If its controller stops working or its dependency remains unavailable, deletion can remain pending. That is useful evidence of unfinished responsibility, not automatically a reason to erase the key.

A deletion request changes the reconciliation branch

For an object with finalizers, the API server sets deletionTimestamp on a deletion request and keeps the object until the relevant deletion conditions and finalizer removal are satisfied. The responsible controller observes the timestamp and performs cleanup instead of continuing ordinary provisioning. A successful delete request does not mean the object or external resource has already vanished. Once deletion is in progress, the API restricts changes to finalizers: existing ones can be removed, but new finalizers cannot be added to postpone an already requested deletion.

Register the controller’s finalizer before creating external resources that require it for cleanup, and check the successful persistence of that registration. Otherwise a crash or deletion between external creation and finalizer installation can orphan the external allocation. Even with the key installed first, external calls can have uncertain outcomes. Use stable identities tied to the object UID and queryable ensure/delete behavior so a retry can determine whether the intended cleanup already happened without targeting a new object incarnation. Custom finalizer keys must be qualified, such as greatitself.com/external-cleanup; short names in the example are symbolic labels.

cleanup branch⁡  ⟺  deletionTimestamp⁡≠∅\operatorname{cleanup\ branch}\iff\operatorname{deletionTimestamp}\neq\varnothing
This is a controller design predicate for entering deletion handling, not a complete API-server deletion algorithm. A timestamp requests deletion; it is not proof that cleanup succeeded or a countdown controlled by this controller.↔ Scroll wide equations horizontally.

Cleanup must tolerate partial success and retries

Suppose deletion of an external resource succeeds but the controller times out before learning that fact. A retry should treat verified absence of that particular external identity as successful cleanup, rather than fail forever because a second delete finds nothing. Conversely, a timeout alone is not proof of absence. Keep the object and finalizer while the obligation is uncertain, report a useful condition or event, and retry with a bounded rate. Separate external identity lookup errors from a positive not-found result.

Remove only the finalizer key this controller owns after its obligation is satisfied. Other finalizers may represent independent storage or policy responsibilities. Update metadata with concurrency-aware logic so competing writers’ keys are preserved. Finalizer list order is not a reliable execution dependency mechanism; avoid designs where two controllers wait on each other’s key order. If an operator deliberately removes a stuck key, the procedure must account for the external resource and accepted data-loss or leak consequences, rather than treating force removal as a harmless retry.

Fafter=Fbefore∖{fours}F_{\rm after}=F_{\rm before}\setminus\{f_{\rm ours}\}
F is the set of finalizer keys represented by the metadata list, and f_ours is this controller’s key. The desired update preserves other keys and must still use the actual API’s concurrency and finalizer validation rules.↔ Scroll wide equations horizontally.

Garbage collection and external cleanup differ

Owner references let Kubernetes garbage collection manage dependent API objects under its ownership rules. They do not automatically delete an arbitrary cloud account resource or database entry outside the API. A finalizer can bridge that external lifecycle, but only if a functioning controller implements the bridge and has the required authority. Measure deletion age and finalizer failures separately from create latency. Test deletion during provisioning, controller restarts, denied external cleanup, and names reused with a new UID; these are ordinary lifecycle interleavings, not exotic accidents.

The queue lab illustrates a backlog of cleanup obligations under a stated service rate. Reset, set λ=2 and μ=3, predict backlog max(0,4−t), then Play or Step until t=4. The fluid queue counts abstract work only; it has no finalizers, deletion timestamps, API validation, or external confirmation. A backlog reaching zero cannot prove real resources were deleted. Use the example’s explicit confirmations for correctness and the lab only to reason about capacity when deletion requests accumulate.

Preserve a second controller’s cleanup responsibility

An object has qualified finalizer keys, symbolically fA and fB, and a deletion timestamp. Controller A must release three external allocations. Two are confirmed absent, while the third cleanup request times out.

  1. A has confirmed two of its three obligations, leaving one uncertain. It retains fA and retries discovery or deletion for the third stable external identity instead of assuming the timeout means success.

  2. A later verifies that the third allocation is absent. Its confirmed count reaches three, so its own cleanup obligation is complete. It updates the finalizer set from {fA,fB} to {fB}, preserving B’s key.

  3. The object can still remain pending while fB exists or other deletion conditions apply. A has removed one key after three verified absences; it has not established that B’s unrelated cleanup happened.

The result

Successful cleanup permits removing the controller’s own key. It does not authorize deleting other finalizers or claiming the entire object lifecycle is complete.

Explore the model

Interactive lab

Interactive lab · queue

Cleanup capacity is not cleanup evidence

Reset, set λ=2 and μ=3, predict backlog max(0,4−t), then Play or Step to t=4. This fluid work model does not execute finalizers, confirm deletion, or model API-object garbage collection.

Cleanup capacity is not cleanup evidenceFluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Current readings: Fluid backlog: 4; Net rate · λ − μ: −1 /s; M/M/1 mean residence: 1 s. All parameters are adjustable with the labeled controls below.02.557.51001.534.56Elapsed time · sFluid backlogλ < μ
Fluid backlogCurrent time
Fluid backlog
4
Net rate · λ − μ
−1 /s
M/M/1 mean residence
1 s
t = 0 s

Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forA deletion backlog needs service capacity, while each cleanup obligation still needs a verifiable result.

Check your understanding

A cleanup request times out and the object still has your finalizer. What is the correct interpretation?

Try it yourself

An object has three finalizers. Your controller verifies its four external allocations are absent and removes only its own key. How many keys remain, and must the API object already be gone?

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Count responsibilities independently and distinguish removing one key from satisfying all deletion conditions.

Compare with the solution

Two finalizer keys remain. The object need not be gone because those controllers’ obligations and other deletion conditions may still be pending. Your four confirmations justify your key’s removal only; a metadata update must preserve the other keys and handle conflicts.

Take it with you

  • A finalizer records an obligation that a controller must actually implement.
  • Install cleanup responsibility before external creation and branch on deletion requests.
  • Verify repeatable cleanup, then remove only the owned key with concurrency protection.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.