How to: Delete a stubborn Kubernetes namespaces.
Tags: kubernetes, operations, howto
Published: 2019-09-25 22:41:10

---
title: How to: Delete a stubborn Kubernetes namespaces.
published: true
description: deleting a stubborn Kubernetes namespace
tags: kubernetes, operations, howto
---

[First posted on my blog.](https://blog.davidjeddy.com/)

<!-- wp:heading -->
<h2>The Situation</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Recently I was introduced to a new project. The getting started documentation was decent and I was able to get the project started up. When it came time to clear the project out of my local machines Kubernetes cluster however, the same space for to the <code>terminating</code> life cycle phase and stayed there for days. Fast forward a couple of weeks and I notice it there, still terminating. Turns out the project had a <code>finalizer</code> that was not responding back. Think of remote service call. In this case the remote service never responded. So below is a little script I put together to <code>force</code> a namespace deletion.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>The Code</h2>
<!-- /wp:heading -->

<!-- wp:code -->
<pre class="wp-block-code"><code>#!/bin/bash
k8s_delete_ns=$1
echo "Provided namesapce: ${k8s_delete_ns}..."
echo "Exporting namespace configuration..."
kubectl get namespaces -o json | grep "${k8s_delete_ns}"
kubectl get namespace ${k8s_delete_ns} -o json > temp.json
echo "Opening editor..."
wait 3
vi temp.json
echo "Sending configuration to k8s master for processing..."
curl -H "Content-Type: application/json" -X PUT --data-binary @temp.json http://127.0.0.1:8080/api/v1/namespaces/${k8s_delete_ns}/finalize
echo "Waiting for namespace deletion to process..."
wait 12
kubectl get namespaces
echo "...done."</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>So what does this do? Lets remove the shell, echo and wait statements since we know the machine does not really do anything with those.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>k8s_delete_ns=$1
kubectl get namespaces -o json | grep "${k8s_delete_ns}"
kubectl get namespace ${k8s_delete_ns} -o json > temp.json
vi temp.json
curl -H "Content-Type: application/json" -X PUT --data-binary @temp.json http://127.0.0.1:8080/api/v1/namespaces/${k8s_delete_ns}/finalize
kubectl get namespaces</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2>So what does this do exactly?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Ok, so what do we have here. Line one takes the first argument from the command invocation and assigns it to a local variable. <code>./script.sh stuck_namespace</code>. So <code>stuck_namespace</code> is the value that is assigned to <code>k8s_delete</code>. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The next two commands get's the current namespace configuration and writes it to <code>temp.json</code>. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The fourth command opens the <code>temp.json</code> configuration file using <code>vi</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With the configuration open we want to remove any items listed in the <code>finalizers</code> array. This is the real magic moment here. Removing the finalizers with allow kubectl to remove the namespace.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Speaking of the next command uses <code>curl</code> to pass the newly edited configuration to kubectl. This updates the namespace configuration with the config that does not contain finalizers.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And finally, <code>get namespaces</code> will output the existing namespace after the update. If all went as expected the list will not contain the stuck namespace.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>So there it is. There are a number of solutions out floating around the internet but the release cadence of Kubernetes renders some of then out-dated in a matter of months. So let me state this: this solution works for Kubernetes 1.13. Other than that, I hope you it helps you out  as it helped me.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>P.S.: If you would like to keep up with Kubernetes helpers I make, checkout the repo on <a href="https://github.com/davidjeddy/k8s_helper_scripts">GitHub</a>.</p>
<!-- /wp:paragraph -->