Reputation: 1729
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
)
Upvotes: 103
Views: 142181
Reputation: 1111
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 -n bar | base64 -w 0)" '.data["foo"]=$foo' | kubectl apply -f -
I'm more comfortable using jq
but yq
should also do the job if you prefer yaml format.
In case you use bash variables to update the secret:
secret_key="MY_NEW_SUPER_DOPE_SECRET"
secret_value='jfajsidhashdhühaf'
kubectl get secret env-secret -o json | jq '.data["'${secret_key}'"]="'$(echo -n ${secret_value} | base64 -w 0)'"' | kubectl apply -f -
Upvotes: 58
Reputation: 51
In order to be able to edit the whole secret values (edit, add or remove values):
# export the secret data
kubectl get secret mysecret -o jsonpath='{.data}' | jq 'map_values(@base64d)' > secret.json
# then edit secret.json to your liking
# import the secret back
kubectl patch secret mysecret -p="$(jq -c '{stringData: .}' secret.json)"
# remove the temporary secret file
rm -f secret.json
If you need to edit a secret value with multi line content, it's more handy to edit the multiline file rather than the json:
# export the secret data
kubectl get secret mysecret -o jsonpath='{.data.mySecretMultilineValue}' | base64 -d >secret.txt
# then edit secret.txt to your liking
# import the secret back
kubectl patch secret mysecret -p="$(jq -cRs '{stringData:{mySecretMultilineValue: .}}' secret.txt)"
# remove the temporary secret file
rm -f secret.txt
Upvotes: 0
Reputation: 8292
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
Upvotes: 39
Reputation: 353
The easiest way from the command line:
echo "This is my secret that might go on multiple lines when encoded" | base64 -w 0 | read output;kubectl patch secret my_secret_name -p="{\"data\":{\"secret_key\": \"$output\"}}" -v=1
It will encode value This is my secret that might go on multiple lines when encoded
and update your my_secret_name
secret by adding secret_key
key and encoded values as a last key-value pair in that secret.
Upvotes: 16
Reputation: 91
use stringData
instead of data
to specify unencoded data:
kubectl patch secret my_secret_name -p="{\"stringData\":{\"secret_key\": \"my secret\"}}"
Upvotes: 7
Reputation: 3
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 -
Upvotes: 0
Reputation: 683
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.
Upvotes: 1
Reputation: 23876
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
Upvotes: -1
Reputation: 1634
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
Upvotes: 0
Reputation: 2114
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.
Upvotes: 5
Reputation: 22248
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):
Upvotes: 4
Reputation: 1775
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>
Upvotes: 2
Reputation: 309
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
Upvotes: 20
Reputation: 12620
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 :
edit
to change a docker-registry
secretI 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='[email protected]'
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 :
Upvotes: 11
Reputation: 229
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.
Upvotes: 22
Reputation: 9837
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.
Upvotes: 69