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/
Related
I am using an existing helm chart repo
https://github.com/kubecost/cost-analyzer-helm-chart
For deployment I am using custom helm chart, have created tgz of the repo and put it under my own charts/ directory and then i put my own certain templates which deploys some resources related to cost-analyzer.
I want to assign some custom labels to the resources which are coming from that tgz.
Is there something/someway that i can add custom labels to all the resources which are deployed using my custom helm chart including the resource which are from tgz.
There is nothing built into Helm for doing that.
You can set the additionalLabels field in their Helm chart values.yaml file (there are multiple places this needs to be done).
A potential kludge could be to pull the manifests after deploying, get the name and type of every resource, and pump that into a kubectl command to label everything, for example:
HELM_RELEASE="???"
NAMESPACE="???"
LABEL="???"
helm get manifest $HELM_RELEASE -n $NAMESPACE \
| kubectl get -n $NAMESPACE -f - \
| grep -vE '^$|^NAME' \
| cut -d' ' -f1 \
| xargs -I {} kubectl label {} $LABEL
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
I have a configMap and I want to create a backup configMap by using the last applied configuration from that.
I use the following command to get the last applied configuration:
kubectl get cm app-map -n app-space \
-o go-template \
--template='{{index .metadata "annotations" "kubectl.kubernetes.io/last-applied-configuration"}}' > backup.json
It returns something like this [the content of backup.json]:
{"kind":"ConfigMap","apiVersion":"v1","metadata":{"name":"app-map","creationTimestamp":null},"data":{"app.yml":"xxxxxxxxx","config.yml":"yyyyyyyyy"}}
Now, I want my backup configMap to have a different name. So, I want to change the .metadata.name from app-map to app-map-backup.
Is there a way I can achieve that with kubectl and -o go-template? I want to have the name changed before I write it to the backup.json file.
I know I can do that using jq but I do not have permission to install jq on the server where I am using kubectl.
you could use kubectl bulk plugin. The below command will replicate your config map
# get resource(s) and create with field(name) change
kubectl bulk configmap app-map -n app-space create name app-mapp-backup
Kubectl bulk is very powerful to use, I suggest to check samples.
You cannot do this just using kubectl. But there are other ways.
You can download statically linked jq binary from official jq website:
wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
chmod +x jq-linux64
and then you can use this binary like following:
kubectl -o go-template [...] | ./jq-linux64 ...
or you can use sed:
kubectl -o go-template [...] | sed 's/"name":"app-map"/"name":"app-map-backup"/'
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>>
How can I modify the values in a Kubernetes secret using kubectl?
I created the secret with kubernetes create secret generic, but there does not seem to be a way to modify a secret. For example, to add a new secret-value to it, or to change a secret-value in it.
I assume i can go 'low-level', and write the yaml-file and do a kubectl edit but I hope there is a simpler way.
(I'm using kubernetes 1.2.x)
The most direct (and interactive) way should be to execute kubectl edit secret <my secret>. Run kubectl get secrets if you'd like to see the list of secrets managed by Kubernetes.
In case you prefer a non-interactive update, this is one way of doing it:
kubectl get secret mysecret -o json | jq '.data["foo"]="YmFy"' | kubectl apply -f -
Note that YmFy is a base64-encoded bar string. If you want to pass the value as an argument, jq allows you to do that:
kubectl get secret mysecret -o json | jq --arg foo "$(echo bar | base64)" '.data["foo"]=$foo' | kubectl apply -f -
I'm more comfortable using jq but yq should also do the job if you prefer yaml format.
As I found myself in the need of modifying a secret, I landed up here.
Here is the most convenient way I found for editing a (one-line) secret.
This elaborates on kubectl edit secret <my secret> of Timo Reimann above.
kubectl edit secret <my secret> will (in my case) invoke vi.
Now I move the cursor to the space after the colon of the secret I want to edit.
Then I press r and [enter] which will put the base64 encoded value onto a line of its own.
Now I enter :. ! base64 -D which will decode the current line.
After making my changes to the value, I enter :. ! base64 which will encode the changed value.
Pressing k [shift]J will rejoin the secret name and its new value.
:wq will write the new secretfile and quit vi.
P.S. If the secret has a multi-line value, switch on line numbers (:set nu) and, after changing the decoded value, use A,B ! base64 where A and B are the line numbers of the first and last line of the value.
P.P.S I just learned the hard way that base64 will receive the text to encode with an appended newline :( If this is no issue for your values - fine. Otherwise my current solution is to filter this out with: .!perl -pe chomp | base64
Deriving from 'Skeeves' answer:
Base64 encode your value:
echo -n 'encode_My_Password' | base64
Open the secret in edit mode:
kubectl edit secret my-secret
The default editor will open, replace the value of an exiting key or add a new line and a new key with the encoded value.
Save and close the file. The updated value or new key-value pair has now been added to the secret.
The easiest way from the command line:
echo "This is my secret" | base64 | read output;kubectl patch secret my_secret_name -p="{\"data\":{\"secret_key\": \"$output\"}}" -v=1
It will encode value This is my secret and update your my_secret_name secret by adding secret_key key and encoded values as a last key-value pair in that secret.
I implemented a kubectl plugin just for this.
To install using krew
kubectl krew update
kubectl krew install modify-secret
To run it
kubectl modify-secret xyz -n kube-system
Demo
The Easy Way : Delete and recreate the secret
After looking at all these answers, for my needs the best solution was to delete and recreate :
kubectl delete secret generic
kubectl create secret generic # or whatever ..
If you want to do it the hard way :
Using edit to change a docker-registry secret
I came to this question looking to modify a "docker-registry" style secret.
Simply editing it using kubectl edit secret seemed fraught as I didn't know what the secret value looked like.
I had created it with a command like kubectl create secret docker-registry generic-registry-secret --docker-server=docker.server --docker-username='my-cloud-usernname' --docker-password='my-auth-token' --docker-email='my#email.com'
I could have edited it, I figured out after looking at the other various answers here how that could be done - I'm including my notes here in case they help others.
List secrets : kubectl get secrets
Details of specific secret : kubectl describe secrets/generic-registry-secret
Get value of secret : kubectl get secret generic-registry-secret -o jsonpath={.data}
Decode secret value : First get everything between "map[.dockerconfigjson:" and "]" and then do :
echo "x9ey_the_secret_encoded_value_here_X0b3=" | base64 --decode
I could then take from that the specific auth token value I was seeking, and replace it with a new one. And then run that new full entire string through a | base 64 to get the base 64 encoding, and now I could finally, confidently, change the value by using kubectl edit secret generic-registry-secret and put in the new correct value.
But a delete and recreate is the simpler option.
References :
https://kubernetes.io/docs/concepts/configuration/secret/
https://kubernetes.io/docs/tasks/configmap-secret/managing-secret-using-kubectl/
Add a new key to an existing secret.
kubectl patch secret $SECRET_NAME --type=json \
-p='[{
"op" : "add" ,
"path" : "/data/'$KEY'" ,
"value" : "'$(base64 <<< "$VALUE")'"
}]'
Update an existing key in a secret
kubectl patch secret $SECRET_NAME --type=json \
-p='[{
"op" : "replace" ,
"path" : "/data/'$KEY'" ,
"value" : "'$(base64 <<< "$VALUE")'"
}]'
I was only able to find the replace operation in documentation, with no mention of the add operation. However, it looked like it was RFC 6902 compliant, so I tested with add and it works fine. I would expect other operations defined by RFC 6902 to work as well, though I haven't tested them.
The fastest way I found:
# You need a version of micro that includes this commit https://github.com/zyedidia/micro/commit/9e8d76f2fa91463be660737d1de3bff61258c90d
kubectl get secrets my-secret -o json | jq -r .data.config | base64 -d | micro | base64 -w 0 | xclip -selection clipboard && kubectl edit secrets my-secret
And using a bash function that you can put in your profile:
function ks-edit { kubectl -n $1 get secrets $2 -o json | jq -r '.data."'$3'"' | base64 -d | micro | base64 -w 0 | xclip -selection clipboard && kubectl -n $1 edit secrets $2; }
You can call it like this:
ks-edit <namespace> <secret> <key>
Before editing secrets with kubectl...
I would highly recommend on using k9s (not only for this purpose, but also as a lightweight k8s CLI management tool).
As you can see below (ignore all white rectangles), when your cluster's context is set on terminal you just type k9s and you will hit a nice terminal where you can inspect all cluster resources.
Just type ":" and enter the resource name (secrets in this case) which will appear in the middle of screen.
Then you can choose a secret with the up and down arrows and type e to edit it (green arrow):
By far the easiest way to do this is to mantain a local .env file for each of your secrets.
e.g
MY_SECRET=something
PASSWORD=anotherthing
Just run
kubectl create secret generic <name> --from-env-file=.env
And when you need to change it - just delete it and run the above command again.
No messing with base64
Always get the copy of secrets before editing it -
kubectl get secrets <your-secret-name> -n <namespace> -o yaml > mysecret.yaml
Now you can edit run edit command to edit your secret -
kubectl edit secrets <your-secret-name> -n <namespace>
or you can make copy of your mysecret.yaml file & exit the secrets inside that & run -
kubectl apply -f mysecret.yaml
Make sure you are decoding & encoding with base64 for viewing & adding secrets respectively.
Here's my one liner:
$ kubectl get secrets/my-secret -o yaml | yq '.dataStrings = (.data | map_values(#base64d)) | del(.data)' | vipe | yq '.data = (.dataStrings | map_values(#base64)) | del(.dataStrings)' | kubectl apply -f -
In case you're wondering how to do this with k9s, I am adding here instructions on how to do this step by step:
Install krew from here https://krew.sigs.k8s.io/docs/user-guide/setup/install/ (skip this step in case you have already it)
Install modify-secret plugin:
kubectl krew install modify-secret
Run the following command or add it to ~/.zshrc or ~/.bashrc:
export XDG_CONFIG_HOME=~/
Add the following to ~/k9s/plugin.yml
plugin:
edit-secret:
shortCut: Ctrl-X
confirm: false
description: "Edit Decoded Secret"
scopes:
- secrets
command: kubectl
background: false
args:
- modify-secret
- --namespace
- $NAMESPACE
- --context
- $CONTEXT
- $NAME