<p>Seems <a href="https://book.kubebuilder.io/reference/using-finalizers.html" rel="noreferrer">easy peasy</a> to implement custom <em>finalizers</em> if I'm implementing my Kubernetes CRD: the code snippet is quite easy since the first delete request on the object sets a value for the <code>metadata.deletionTimestamp</code> field instead of deleting the object that triggers the custom controller watching the object to execute any finalizers it handles.</p>

<p>However, let's imagine I'd like to set a <em>custom finalizer</em> for a default Kubernetes resource like a Namespace, a Deployment or whatever: is that possible or not?</p>

<p>Ok, tested a little bit taking <code>Namespace</code> as an example.</p>

<pre class="lang-sh prettyprint-override"><code># k create ns my-namespace
namespace/my-namespace created

# k edit ns my-namespace
(... adding the .metadata.finalizers list)

# k get ns my-namespace -o yaml
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2019-09-08T06:50:25Z"
  finalizers:
  - prometherion/do-something
  name: my-namespace
  resourceVersion: "1131"
  selfLink: /api/v1/namespaces/my-namespace
  uid: 75b5bae8-1d5b-44c6-86bc-e632341aabfd
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

# k delete ns my-namespace
namespace "my-namespace" deleted
</code></pre>

<p>If I open another terminal, I can see the resource in <code>Terminating</code> state.</p>

<pre class="lang-sh prettyprint-override"><code># k get ns my-namespace
NAME           STATUS        AGE
my-namespace   Terminating   6m8s
</code></pre>

<p>So, actually the resource is marked to be deleted since I got a <code>deletionTimestamp</code>:</p>

<pre class="lang-sh prettyprint-override"><code>k get ns my-namespace -o jsonpath='{.metadata.deletionTimestamp}'
2019-09-08T06:58:07
</code></pre>

<p>To complete the deletion, I just need a simple <a href="https://stackoverflow.com/a/40975308/10104472">Watch</a> (using the Kubernetes Go Client) to get the change of the object (or a <a href="https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/" rel="noreferrer">Dynamic Admission Controll</a> to get the event, process my business logic in async mode (like a pre delete hook) and remove my fully-qualified Finalizer... just for sake of simplicity, I tested removing it with <code>kubectl</code> and it worked.</p>

<p>Just for information, <em>Finalizer</em> must be fully qualified since there's a <a href="https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/core/validation/validation.go#L4676-L4680" rel="noreferrer">validation</a> process, so it must be declared according to the pattern <code>prometherion/whatever_you_want</code>, taking care the first part must adhere to <code>DNS-1123</code> specification.</p>
