Edit Kubernetes Secrets
Janne Kemppainen |Has your API key changed? Maybe you need to update a TLS certificate? There are many reasons why you’d want to edit secrets in Kubernetes. Luckily, this is relatively simple.
Secrets are normal objects inside Kubernetes, just like pods or ingresses. The secret data is stored as a base64
encoded string, so it’s not really plaintext, but it’s not encrypted either! Therefore you need to be careful of which access rights you give to the cluster so that you don’t leak sensitive information.
That base64 encoding adds some complexities when you need to change secret values.
For the rest of this post I will assume that you’ve already properly configured kubectl
with access to a cluster.
How can you find a Kubernetes secret?
Before you can edit a secret you need to be able to locate it!
Each secret lives inside a namespace, and they are only accessible to services within the same namespace. Therefore the first thing you need to do is to see what namespaces you have inside the cluster:
$ kubectl get namespaces
NAME STATUS AGE
default Active 14d
kube-node-lease Active 14d
kube-public Active 14d
kube-system Active 14d
my-app Active 2d
This gives you a complete list of all namespaces. Now you can list the secrets for your chosen namespace:
$ kubectl get secrets -n my-app
NAME TYPE DATA AGE
db-credentials Opaque 1 9h
default-token-z59b4 kubernetes.io/service-account-token 3 9h
If you need to check the current secret value you can query the YAML manifest:
$ kubectl get secret db-password -n my-app -o yaml
apiVersion: v1
data:
password: bXktcGFzc3dvcmQ=
kind: Secret
metadata:
creationTimestamp: "2021-10-14T19:56:47Z"
name: db-credentials
namespace: my-app
resourceVersion: "329851"
uid: af03fbbf-aa56-45ea-a1dc-24c118645749
type: Opaque
The -n
flag is a shorthand for --namespace
, and is -o
for --output
which sets the output format. As the data is base64 encoded you’ll have to decode the value to make sense of it.
$ echo "bXktcGFzc3dvcmQ=" | base64 --decode
my-password
There are also online services that can decode and encode base64 strings, but I wouldn’t use them to convert sensitive information.
Edit a secret with kubectl edit secret
Now we can continue to actually editing the secret. Since the secret value needs to be stored as a base64 string you’ll have to convert it to the proper format. One way to do this is to use the Linux/macOS command line again:
$ echo -n "my-new-password" | base64
bXktbmV3LXBhc3N3b3Jk
We need to use the -n
argument to suppress the newline character from the end of the echo
output that is piped to the base64
executable. If you omit the -n
flag the secret will end with a \n
character which can cause issues in your app! Copy the encoded value, then edit the secret with kubectl
:
$ kubectl edit secret db-credentials -n my-app
The current secret manifest opens in your default text editor. Replace the secret data with the new value, then save and exit the editor and you’re done!
If your secret data is something that works well within a YAML file, such as a password, then it’s also possible to let Kubernetes handle the base64 conversion. Use the same command as before to open the editor, but this time add a new stringData
field to the YAML file containing all the secret values that you want to change.
stringData:
password: my-new-password
Kubernetes merges the stringData
field to the data
field automatically and performs the needed conversions. You don’t have to remove existing keys from the data
field since stringData
takes precedence when the same keys are defined in both fields.
You can verify that the value was updated after saving and closing the editor. If you close without changes the edit is going to be cancelled.
Delete and recreate a secret
The other easy option to update a secret is to delete the old secret and create a new one with the same name. The --ignore-not-found
setting can be used when you’re not sure if the secret already exists or not. If you attempt to delete a non-existing secret without that option the command will fail.
$ kubectl delete secret db-credentials -n my-app --ignore-not-found=true
$ kubectl create secret generic db-credentials -n my-app --from-literal=password="my-password"
This option works really well when you want to fetch the secret data from a file:
$ kubectl create secret generic db-credentials -n my-app --from-file=password=db-password.txt
Note that with these options you don’t need to worry about encoding the secret value.
There is also a specific command for creating TLS certificate secrets that use the kubernetes.io/tls
type:
$ kubectl create secret tls app-cert -n my-app --cert=cert.pem --key=cert.key
You can find all available flags for these commands and more from the kubectl reference.
Remember that you can verify the secret with this command:
$ kubectl get secret db-credentials -n my-app -o yaml
Add more data to a secret
If you want to add more data to the secret you will have to follow one of the previous steps. There is no way to append to a secret with a direct kubectl
command. So for example if we need to include the database username we could delete the secret and create it again. This time I’m using environment variables to define the values.
$ export DB_USER="dbuser"
$ export DB_PASSWORD="my-new-password"
$ kubectl delete secret db-credentials -n my-app --ignore-not-found=true
$ kubectl create secret generic db-credentials -n my-app --from-literal=password=$DB_PASSWORD --from-literal=username=$DB_USER
Naturally, you could use the kubectl edit secret
command as well.
Can you change the secret type in Kubernetes?
Once you have created a secret in the cluster you cannot change its type. Your only option is to delete and recreate the secret with the correct type. Alternatively, you could roll the change by creating a new secret with a different name and then pointing any resources to use it.
For example, if you want to change an Opaque
secret to the kubernetes.io/tls
type you’ll have to recreate it.
Final thoughts
So as you can see, editing secret values is not exactly difficult, but the base64 encoding can add some complexities to the process.
If you want to see more content like this then let me known on Twitter. I hope to see you on the next article!
Previous post
What ChatOps Solutions Should You Use Today?Next post
Cancel a Git Commit