After you try to delete a namespace in a Kubernetes cluster, the namespace may be stuck in the terminating state for a long time. This topic describes how to delete a namespace in the terminating state.

Problem description

After you try to delete a namespace in a Kubernetes cluster, the namespace may be stuck in the terminating state for a long time.
$ kubectl delete ns <namespacename>
Error from server (Conflict): Operation cannot be fulfilled on namespaces "<namespacename>": The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system. 

$ kubectl describe ns <namespacename>
Name: <namespacename> 
Labels: <none> 
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"<namespacename>","namespace":""}} 

Status: Terminating 

Cause

Residual resources exist in the namespace that you want to delete from the cluster.

Solution

To delete a namespace in the terminating state, you can delete the finalizers field in the namespace configuration.

This method can clear a namespace that is stuck in the terminating state. However, resources that belong to the namespace cannot be automatically deleted and thus left in the cluster. You must manually delete the residual resources. After the residual resources are deleted, you can perform the following steps to clear the array of the finalizers field and delete the finalizers field. Then, Kubernetes deletes the namespace in the terminating state.

  1. Open a shell terminal. Run the following command to create a reverse proxy for your Kubernetes cluster:
    kubectl proxy
    A command output similar to the following one appears:
    Starting to serve on 127.0.0.1:8001
  2. Open a new shell terminal. Define environment variables to connect to the Kubernetes cluster. Then, run the curl command to check the connectivity and authorization.
    export TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
    curl http://localhost:8001/api/v1/namespaces --header "Authorization: Bearer $TOKEN" --insecure
  3. Query the configuration of a namespace, for example, istio-system.
    kubectl get namespace istio-system -o json > istio-system.json
  4. Clear the array of the finalizers field and save the configuration.
        "spec": {
            "finalizers": [
            ]
        },
  5. Run the following command to delete the finalizers field of the istio-system namespace:
    curl -X PUT --data-binary @istio-system.json http://localhost:8001/api/v1/namespaces/istio-system/finalize -H "Content-Type: application/json" --header "Authorization: Bearer $TOKEN" --insecure