Helm delete all releases - kubernetes-helm

I'm trying find a way to delete all deployed releases in Helm.
It appears that Helm does not support deleting all releases, with --all or otherwise.
Would there be another way to delete all Helm releases in one command?

To delete all Helm releases in Linux(in Helm v2.X) with a single command, you can use some good old bash. Just pipe the output of helm ls --short to xargs, and run helm delete for each release returned.
helm ls --all --short | xargs -L1 helm delete
Adding --purge will delete the charts as well, as per #Yeasin Ar Rahman's comment.
helm ls --all --short | xargs -L1 helm delete --purge
On Windows, you can delete all releases with this command, again, with --purge deleting the charts as well.
helm del $(helm ls --all --short) --purge
Update: As per #lucidyan comment, the --purge arg is not available in Helm v3.

For helm 3 you have to provide namespaces so there is an awk step before xargs :
helm ls -a --all-namespaces | awk 'NR > 1 { print "-n "$2, $1}' | xargs -L1 helm delete
This results in commands like:
helm delete -n my-namespace my-release

This worked for me in a powershell cmd window:
helm del $(helm ls --all --short) --purge

helm delete $(helm ls --short)
Description:
helm ls --short gives a list of releases ids.
helm delete id1 id2 id3 deletes releases with ids: id1, id2, id3.
So combining them we get:
helm delete $(helm ls --short)

I regularly delete all releases in Helm too, so I thought it'd be useful to make a Helm plugin for it.
Install:
helm plugin install https://github.com/tedmiston/helm-delete-all-plugin --version 0.0.3
(You may be able to omit the --version x part on newer versions of Helm.)
Usage:
helm delete-all
https://github.com/tedmiston/helm-delete-all-plugin

If you use xargs in the alpine container then you will get the following error;
xargs: unrecognized option: L
So, you can use the following command to delete all releases in a specific namespace for the helm v3.
helm uninstall -n <namespace> $(helm ls --short -n <namespace>)

There is a really good plugin for delete all helm releases from all namespaces (The previous plugin in this post doesn't work for me) .
Install:
helm plugin install https://github.com/BarelElbaz/helm-delete-all
usage:
helm delete-all
you can provide more flags such as --deletePersistent for delete PVCs
or skipping a specific namespace by --except-namespace

To delete all releases in a particular namespace
helm ls --short -n <<namespace>> | xargs -L1 helm uninstall -n <<namespace>>

Related

How do I know which repository the installed Chart belongs to

I have many helm repositories in my kubernetes,
And I installed a lot of charts,
So How do I know which repository the installed Chart belongs to?
For example:
$> helm repo list
NAME URL
lucy-dev https://harbor.mydomain.net/chartrepo/lucy-dev
lucy-prod https://harbor.mydomain.net/chartrepo/lucy-prod
$> helm ls -n msgbox-lucy -o yaml
- app_version: "1.0"
chart: msgbox-lucy-8.27.3
name: msgbox-lucy
namespace: msgbox-lucy
revision: "48"
status: deployed
updated: 2022-04-19 08:11:16.761059067 +0000 UTC
I can't use helm show because:
$> helm show all msgbox-lucy -n msgbox-lucy --debug
show.go:195: [debug] Original chart version: ""
Error: non-absolute URLs should be in form of repo_name/path_to_chart, got: msgbox-lucy
...
I don't believe you're guaranteed to get the info you're looking for, however we can try.
Find the latest Helm secret for your Helm release.
kubectl get secret -n msgbox-lucy
Yours might look something like this:
sh.helm.release.v1.msgbox-lucy.v5
and run this command to view the chart's metadata:
SECRET_NAME="sh.helm.release.v1.msgbox-lucy.v5"
kubectl get secret $SECRET_NAME -o json | jq .data.release \
| tr -d '"' | base64 -d | base64 -d | gzip -d \
| jq '.chart.metadata'
The metadata should hopefully show you 2 things you're looking for. The chart name will be under the name field. The chart repository URL might be under sources.
I say "might" because the chart developer should have added it there, but they might not have.
Then you can match the URL to your repo alias.
If it's not included in the metadata, you're probably out of luck for now.
There is an open Github issue about exactly this feature you're wanting:
https://github.com/helm/helm/issues/4256
And an open PR that adds that feature:
https://github.com/helm/helm/pull/10369
And an open PR to add a HIP (Helm Improvement Proposal) for adding that feature:
https://github.com/helm/community/pull/224
You can run helm search repo <keyword>
This will search for the keyword msgbox-lucy in all your available repos and list results.
helm search repo msgbox-lucy
Official Doc : https://helm.sh/docs/helm/helm_search_repo/

Restrict helm to update or install if there are no changes/modification to your charts

Is there a way to restrict helm to install or update if there are no new changes or modifications detected in your charts?
One way of doing this - take helm template on old and new chart and do a diff. Then proceed with updates only if there are changes.
Essentially,
values_diff=$(diff work-values/values.yaml work-values/values-prev.yaml | wc -l)
Where values.yaml and values-prev.yaml are outputs of helm template command on latest and previous charts.
Then you do
if [ $values_diff -gt 0 ]
then
....
And your update logic goes where dots are.
See full working sample here (note it has few extra things that you may omit) - https://github.com/relizaio/reliza-hub-integrations/blob/master/Helm-cd-with-Reliza/helm_configmap.yaml, which is part of my bigger tutorial here - https://worklifenotes.com/2021/05/22/helm-cd-with-reliza-hub-tutorial/
I found a different way to do it. Wrote a small python script to list down files changed in the last 2 commits and then filtered out the apps which were modified.
This is a great plugin for helm.
helm plugin install https://github.com/databus23/helm-diff
helm diff upgrade -n mynamespace myapp foo/myapp -f custom-values.yaml
You could use it like so
#!/bin/bash
lines=$(helm diff upgrade -n mynamespace myapp foo/myapp -f custom-values.yaml)
if [[ $(echo $lines | wc -l) > 0 ]]; then
echo "$lines" | grep "^+\|^-"
echo "Helm changes detected."
echo "Running upgrade in 5."; sleep 5 helm upgrade --install -n mynamespace myapp foo/myapp -f custom-values.yaml
fi
You can use terraform helm provider as well.
https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release

How to delete helm release older than 1 month

I know I can list all helm release using helm ls --tiller-namespace <tiller-namespace>
What command I can use for deleting helm release old than 1 month ?
You could use the below shell script, that takes all the list of releases and it's last deployed in seconds using the helm ls and jq utility command; which then loops through the releases list and does some subtraction on the number of days it has been deployed and then deletes the releases which are older than a month. By month, I've just given 30 days.
#!/bin/bash
#Store the release names alone for a specific tiller.
helm_releases=(`helm ls --short --tiller-namespace "kube-system"`)
#Store current date
CURRENT_TIME_SECONDS=`date '+%s'`
for RELEASE in ${helm_releases[#]};
do
LAST_DEPLOYED_SECONDS=`helm status $RELEASE --tiller-namespace "kube-system" --output=json | jq -r '.info.last_deployed.seconds'`
SEC_DIFF=`expr $CURRENT_TIME_SECONDS - $LAST_DEPLOYED_SECONDS`
DAY_DIFF=`expr $SEC_DIFF / 86400`
if [ "$DAY_DIFF" -gt 30 ]; then
echo "$RELEASE is older than a month. Proceeding to delete it."
helm delete --purge --no-hooks $RELEASE
fi
done
You can still define your own logic on top of this by calculating the seconds differences for a month.
Please note that I've explicitly mentioned the --tiller-namespace. You can use that if you're releases are deployed in a namespace which uses tiller other than kube-system.

diff between whats active on cluster versus kustomize

kustomize's docs provides a nice one-liner that compares two different overlays...
diff \
<(kustomize build $OVERLAYS/staging) \
<(kustomize build $OVERLAYS/production)
is there a way to do the same but against what is running within a specific kubernetes namespace and that of a defined overlay on disk?
more specifically, knowing what an kubectl apply -k . would do without actually doing it? using --dry-run just says spits out a list of the objects rather than a real diff.
kustomize build ./ | kubectl diff -f -
In Kustomize version 4.x.x
If you're looking for a way to do this visually, I highly recommend trying the Compare & Sync feature from Monokle:
In the picture above you can see an example where I'm comparing the output of the cluster-install kustomization to the objects in my minikube cluster.
You can easily determine which resources are missing in your cluster and which ones are different.
On top of that, you're not limited to only comparing kustomizations to clusters. You can also compare two clusters, two kustomizations, helm charts, etc.
I'm not sure if this is what you are looking for, but in Kubernetes you have kubectl diff.
It's nicely explained on APIServer dry-run and kubectl diff.
You can use option -k, --kustomize which does:
Process the kustomization directory. This flag can't be used together with -f or -R.
Or maybe something similar to one-liner to set context for specific namespace:
$ kubectl config set-context staging --user=cluster-admin --namespace=staging
$ kubectl config set-context prod --user=cluster-admin --namespace=prod
Once you have context setup you could use them maybe in a following way:
kubectl config use-context staging; cat patched_k8s.yaml | kubectl config use-context prod; kubectl diff -f -
This is just an example which I did not tested.
Try this kustomize command, currently in alpha:
KUSTOMIZE_ENABLE_ALPHA_COMMANDS=true kustomize resources diff -k your/kustomize/overlay
via https://kubernetes.slack.com/archives/C9A5ALABG/p1582738327027200?thread_ts=1582695987.023600&cid=C9A5ALABG
I have a small function on my shell config to do this:
kdiff() {
overlay="${1}"
kustomize build ${overlay} \
| kubectl diff -f - ${#:2} \
| sed '/kubectl.kubernetes.io\/last-applied-configuration/,+1 d' \
| sed -r "s/(^\+[^\+].*|^\+$)/$(printf '\e[0;32m')\1$(printf '\e[0m')/g" \
| sed -r "s/(^\-[^\-].*|^\-$)/$(printf '\e[0;31m')\1$(printf '\e[0m')/g"
}
It drops the last-applied-configuration annotation and adds some color.

helm install in kuberneres - Error: This command needs 2 arguments: release name, chart path

Trying to install Che in Kubernertes:
from: https://www.eclipse.org/che/docs/che-6/kubernetes-single-user.html
Deploying Che:
helm upgrade --install my-che-installation --namespace my-che-namespace -f ./
Error:
Error: This command needs 2 arguments: release name, chart path
I think the problem is the -f - that is normally used for a values file but it is pointing to a whole dir and not a values file. If you take that out and run helm upgrade --install my-che-installation --namespace my-che-namespace ./ from the suggested path then you get a different error because the dependencies are not built. If you then run helm dep build . and try again then it works.
When I see this error the first thing that comes to my mind (and I ran into this many times) are typos in the command.
For example when I use --set to pass inline values and I leave a whitespace in the assignment:
#Error: This command needs 2 arguments
helm upgrade --install -f <VALUES_FILE_PATH> --set SomeToken= $Token ..
#OK
helm upgrade --install -f <VALUES_FILE_PATH> --set SomeToken=$Token ..
I would also check if the -f flag was passed in the right location.