1. Introduction

Kubernetes is a way to manage and orchestrate containers on multiple nodes. Like platforms such as Docker, we can use central repositories with ready-made pods and other resources for Kubernetes. Further, to organize this information and structure the deployment of whole application environments, Helm was developed.

In this tutorial, we explore repositories and ways to delete all releases in Helm. First, we go over what a Helm repository is and how to add and update the charts from one. After that, we understand how Helm charts relate to releases. Next, we see ways to list current releases. Finally, we go through methods for deleting all releases.

We tested the code in this tutorial on Debian 12 (Bookworm) with GNU Bash 5.2.15. Unless otherwise specified, it should work in most POSIX-compliant environments.

2. Helm Repository

Similar to the repositories of native Linux distribution package managers, a Helm repository is a local or remote directory with a specific organization and file structure.

It commonly provides at least three components:

  • signature
  • packages
  • package index

If we want to work with a particular package from a given [repo]sitory, we first add the latter to Helm via the helm command-line tool:

$ helm repo add <REPO_NAME> <REPO_URL> <FLAGS>

For the examples below, we use two Helm repositories:

$ helm repo add gabe565 https://charts.gabe565.com
"gabe565" has been added to your repositories
$ helm repo add banzaicloud-stable https://kubernetes-charts.banzaicloud.com
"banzaicloud-stable" has been added to your repositories

Next, we update the local repository cache for all repositories:

$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "gabe565" chart repository
...Successfully got an update from the "banzaicloud-stable" chart repository
Update Complete. ⎈Happy Helming!⎈

Now, we should be able to install charts from the new gabe565 and banzaicloud-stable repositories.

3. Helm Releases

Just like a Dockerfile can be at the base of an actual Docker container instance, Helm charts are the blueprints for Kubernetes instances also called releases. In other words, a release is a Helm chart instance, usually describing an application environment.

Just like regular instances, releases can be associated with a namespace. So, let’s create some namespaces:

$ kubectl create namespace entertainment
namespace/entertainment created
$ kubectl create namespace development
namespace/development created
$ kubectl create namespace storage
namespace/storage created

Now, we can install a release from a repository chart:

$ helm install ascii-movie gabe565/ascii-movie --namespace entertainment
NAME: ascii-movie
LAST DEPLOYED: Sun Feb 25 15:02:00 2024
NAMESPACE: entertainment
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
           You can watch the status of by running 'kubectl get svc -w ascii-movie'
  export SERVICE_IP=$(kubectl get svc --namespace default ascii-movie -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  echo http://$SERVICE_IP:23

At this point, we have one deployed release in the entertainment namespace.

Let’s perform a few more deployments:

$ helm install nodex banzaicloud-stable/nodejs --namespace development
NAME: nodex
LAST DEPLOYED: Sun Feb 25 15:06:56 2024
NAMESPACE: development
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app=nodejs,release=nodex" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80
$ helm install snap banzaicloud-stable/thanos --namespace storage
NAME: snap
LAST DEPLOYED: Sun Feb 25 15:06:57 2024
NAMESPACE: storage
STATUS: deployed
REVISION: 1
TEST SUITE: None

Thus, we should have several releases in different namespaces.

4. List Helm Releases

Now, to list all releases, we can again employ helm:

$ helm list --all --all-namespaces
NAME          NAMESPACE       REVISION   UPDATED                                   STATUS     CHART                APP VERSION
ascii-movie   entertainment   1          2024-02-25 15:02:00.392981879 -0500 EST   deployed   ascii-movie-0.13.2   1.7.2
nodex         development     1          2024-02-25 15:06:56.1120554 -0500 EST     deployed   nodejs-0.1.1
snap          storage         1          2024-02-25 15:06:57.964318927 -0500 EST   deployed   thanos-0.4.9         0.28.1

Since Helm 3 and above use the NAMESPACE architecture of Kubernetes, we include –all-namespaces in addition to –all to drop any potential filter.

Before version 3, Helm did not require specifying a namespace as part of many commands. If no namespace was passed, all namespaces were considered:

$ helm list --all

Further, as long as we have the namespace and release name, we can check their current status:

$ helm status ascii-movie --namespace entertainment
NAME: ascii-movie
LAST DEPLOYED: Sun Feb 25 15:02:00 2024
NAMESPACE: entertainment
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
           You can watch the status of by running 'kubectl get svc -w ascii-movie'
  export SERVICE_IP=$(kubectl get svc --namespace entertainment ascii-movie -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  echo http://$SERVICE_IP:23

Now, let’s understand how to remove all releases, regardless of state.

5. Delete Helm Releases

While deleting Helm releases is fairly simple, it’s important to note that a Helm release might not be ephemeral. The idea behind charts is that they can configure persistent storage and other resources, associated with the release.

So, care should be taken when deleting releases, especially all of them at once.

5.1. Using delete

The delete (del, uninstall, un) subcommand of helm removes releases by name:

$ helm delete <RELEASE_NAME>

Before version 3, this command would cause Helm to remove any release that matches RELEASE_NAME, regardless of the namespace. In addition, to completely remove a release along with all records and charts, older versions of Helm require the –purge flag. Thus, we can combine these concepts with release listing to create a fairly simple command that deletes all releases in Helm versions before 3:

$ helm delete $(helm list --all --short) --purge

In this case, we add the –short flag to only get a list of names instead of all data about a release.

Yet, due to the namespace specification constraint of Helm releases after version 3, the commands above only delete releases if they reside in the default namespace.

Further, to avoid accidental data loss, the delete subcommand doesn’t support the –all-namespaces flag. So, if we want to delete a release outside of the default namespace, we should explicitly indicate the namespace that the release resides in:

$ helm delete <RELEASE_NAME> --namespace <RELEASE_NAMESPACE>

Still, we can work around this by processing the original output in full, parsing the namespace of each release:

$ helm list --all --all-namespaces | awk 'NR > 1 { print  "--namespace "$2, $1}'

In particular, we leverage awk:

  • NR > 1 skips the first line by ensuring the line number is above 1
  • print “–namespace “$2, $1 outputs –namespace followed by two fields for each line after the first
  • $2 is the second whitespace-separated column of the list output, i.e., NAMESPACE
  • $1 is the first whitespace-separated column of the list output, i.e., NAME

Let’s check the example output in our case:

$ helm list --all --all-namespaces | awk 'NR > 1 { print  "--namespace "$2, $1}'
--namespace entertainment ascii-movie
--namespace development nodex
--namespace storage snap

At this point, we have the release name and namespace combinations ready. So, let’s pipe them to the xargs command, so it can append them to helm delete:

$ helm list --all --all-namespaces | awk 'NR > 1 { print "--namespace "$2, $1}' | xargs --max-lines=1 helm delete

Above is the complete command for deleting all Helm releases, which should be fairly universal. Specifically, we pass 1 line per helm delete call.

5.2. Using Plugins

Helm enables the use of plugins for different functions.

To install a plugin, we use the plugin subcommand and the install operation:

$ helm plugin install <URL>

One plugin that provides delete-all for releases is helm-delete-all:

$ helm plugin install https://github.com/BarelElbaz/helm-delete-all
Installed plugin: delete-all

After installing the plugin, we should be able to use the delete-all subcommand to remove all instances:

$ helm delete-all

Notably, if plugins aren’t maintained, Helm might stop supporting them due to internal changes. Hence, it’s usually a good idea to understand the Helm commands involved in at least basic operation.

6. Summary

In this article, we talked about Helm repositories and releases, as well as ways to deploy and delete all Helm releases.

In conclusion, Helm is a versatile way to deploy and uninstall many application environments in Kubernetes.