Edit Kubernetes SecretsJanne 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
-n flag is a shorthand for
--namespace, and is
--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 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
$ 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.
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!