Finalizers

Finalizers are conditions that must be satisfied before a resource can be deleted. When a delete is ordered on a finalized resource, the resource is locked for changes until the conditions are met. Finalizers are used to signal to the control plane, or to custom controllers like Operators, to clean up for a resource before completely and finally removing it.

Create a manifest for a Deployment with a Finalizer:

cat > finalizer-test.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: finalizer-test
  namespace: myproject
  labels:
    app: finalizer-test
  finalizers:
    - finalizer.extensions/v1beta1  
spec:
  selector:
    matchLabels:
      app: finalizer-test
  replicas: 3
  template:
    metadata:
      labels:
        app: finalizer-test
    spec:
      containers:
        - name: hieveryone
          image: openshiftkatacoda/blog-django-py
          imagePullPolicy: Always
          ports:
            - name: helloworldport
              containerPort: 8080
EOF

Create the Deployment.

kubectl create -f finalizer-test.yaml

Verify the Deployment has been created.

kubectl get deployments

Verify the ReplicaSet has been created:

kubectl get replicasets

Verify the pods are running:

kubectl get pods

Attempt to delete the Deployment.

kubectl delete deployment finalizer-test

Open up another terminal by clicking the + button and selecting Open New Terminal. In the new terminal, see that the Deployment still exits and has been updated with the `deletionGracePeriodSeconds` and `deletionTimestamp` fields:

kubectl get deployment finalizer-test -o yaml | grep 'deletionGracePeriodSeconds\|deletionTimestamp'

Attempt to scale the Deployment up and down. Although status is updated, pods will not be created/deleted:

kubectl scale deploy finalizer-test --replicas=5
kubectl get deployments
kubectl get pods
kubectl scale deploy finalizer-test --replicas=1
kubectl get deployments
kubectl get pods

Update the Deployment with the Finalizer value unset.

cat > finalizer-test-remove.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: finalizer-test
  namespace: myproject
  labels:
    app: finalizer-test
  finalizers:
spec:
  selector:
    matchLabels:
      app: finalizer-test
  replicas: 3
  template:
    metadata:
      labels:
        app: finalizer-test
    spec:
      containers:
        - name: hieveryone
          image: openshiftkatacoda/blog-django-py
          imagePullPolicy: Always
          ports:
            - name: helloworldport
              containerPort: 8080
EOF

Replace the Deployment.

kubectl replace -f finalizer-test-remove.yaml

The Deployment will now be deleted.

kubectl get deployments
kubectl get pods

See the following Kubernetes source code references to Finalizer implementation:

Deployment Controller (DeletionTimestamp != nil)

SyncStatusOnly Method