Create Kubernetes Secrets with `kubectl`
In Kubernetes, a Secret is an object that stores sensitive data for containers to use in the form of a key-value pair, such as a password, a token, or an access key.
The short answer
To create a Secret, you can use the [.inline-code]kubectl create secret generic[.inline-code] command as follows:
Where:
- [.inline-code]secret_name[.inline-code] is the name of the secret.
- [.inline-code]key[.inline-code] is the name of the key (e.g. [.inline-code]password[.inline-code]).
- [.inline-code]value[.inline-code] is the value of the key (e.g. [.inline-code]S!B\*d$zDsb=[.inline-code]).
For example:
The above command will create a general-purpose secret called [.inline-code]demo-secret[.inline-code] with two keys [.inline-code]dbPassword[.inline-code] and [.inline-code]dbUser[.inline-code].
To view the secret in [.inline-code]yaml[.inline-code] format you can use the [.inline-code]kubectl get secret[.inline-code] command as follows:
Note that these values are, by default, encoded into Base64, but you can easily retrieve a specific value and decode it using the following command:
Which is quite useful if, for example, you've installed a Helm chart that generates random passwords at installation and you need to retrieve these values in order to manually access the instance.
[#easily-recall-with-ai]Easily retrieve this command using Warp’s AI Command Search[#easily-recall-with-ai]
If you’re using Warp as your terminal, you can easily retrieve this command using the Warp AI Command Search feature:
Entering [.inline-code]k8s literal secret[.inline-code] in the AI Command Search will prompt a [.inline-code]kubectl[.inline-code] command that can then quickly be inserted into your shell by doing [.inline-code]CMD+ENTER[.inline-code].
Note that you can also recall the decode command by entering [.inline-code]k8s decode secret key[.inline-code].
[#creating-a-secret-from-a-file]Creating a Secret from a file[#creating-a-secret-from-a-file]
To create a Secret from a value contained in a regular file, you can use the [.inline-code]--from-file[.inline-code] flag as follows:
For example:
When creating a secret using a file, [.inline-code]kubectl[.inline-code] will use the filename as the default key and the file contents as the value.
To specify a different key, you can use the following syntax:
For example:
In this case, the key will be [.inline-code]private-key[.inline-code] instead of [.inline-code]secret.txt[.inline-code]
Note that you can use both the [.inline-code]--from-literal[.inline-code] and [.inline-code]--from-file[.inline-code] flags at the same time.
[#creating-a-docker-secret]Creating a Docker Secret[#creating-a-docker-secret]
Kubernetes Docker Secrets are a special kind of Secrets used by Kubernetes to authenticate with a Docker registry when pulling images for containers. This is common if you store your images in a private docker registry.
[#using-the-docker-configuration]Using the Docker configuration[#using-the-docker-configuration]
Docker usually stores your credentials or token information inside a file named [.inline-code]~/.docker/config.json[.inline-code] after logging in with the [.inline-code]docker login[.inline-code] command.
To create a Kubernetes Secret from this Docker configuration file, you can use the [.inline-code]kubectl create secret docker-registry[.inline-code] command as follows:
Where the key will be set to [.inline-code].dockerconfigjson[.inline-code] and its value to the contents of the [.inline-code]~/.docker/config.json[.inline-code] file.
Note that unlike generic Secrets, this Docker Secret will have a [.inline-code]kubernetes.io/dockerconfigjson[.inline-code] type.
[#using-the-cli]Using the command-line interface[#using-the-cli]
Alternatively, you can directly create a Docker Secret in the command using the [.inline-code]--docker-server[.inline-code], [.inline-code]--docker-username[.inline-code] and [.inline-code]--docker-password[.inline-code] flags like so:
You can then attach it to any pod spec to tell Kubernetes to use this Secret for pulling that image as follows:
[#refreshing-tokens]Refreshing pull Secrets[#refreshing-tokens]
Note that if you are using a private registry that uses a custom CLI to generate a temporary token - like AWS’s ECR for instance - you will need to put in place a mechanism for your cluster to refresh the token.
A popular way to do this is by creating a special read-only account to your registry, and then creating a Kubernetes Job to periodically recreate the secret in Kubernetes.
[#creating-a-tls-secret]Creating a TLS Secret[#creating-a-tls-secret]
TLS Secrets are used for storing TLS certificates and keys for things like securing an ingress with HTTPS.
[#creating-a-self-signed-certificate]Creating a self-signed certificate[#creating-a-self-signed-certificate]
TLS certificates and keys can either be acquired from a Certificate Authority or self-signed.
To create a self-signed certificate, you can run the following [.inline-code]openssl[.inline-code] command:
Following the prompt with really only “Common Name” being important and should be set to the domain you are trying to secure.
[#creating-tls-secrets]Creating a TLS Secret[#creating-tls-secrets]
Once your TLS certificate and key downloaded or generated, you can create a TLS Secret using the following [.inline-code]kubectl create secret tls[.inline-code] command:
Which will contain two keys: [.inline-code]tls.crt[.inline-code] and [.inline-code]tls.key[.inline-code].
You can then add the following configuration to your Ingress spec to enable TLS:
You can learn more about certificates by reading our article on how to generate your own certificate signing request.
[#creating-a-secret-from-an-env-file]Creating a Secret from an env file [#creating-a-secret-from-an-env-file]
Env files are pretty popular in development with libraries like [.inline-code]dotenv[.inline-code] that allow you to load environment variables dynamically per program. Kubernetes allows you to create a regular generic secret from this type of file automatically.
For example, if we create a new env file called [.inline-code]staging.env[.inline-code]
We can convert this file into a secret using the following command:
[#connecting-a-secret-to-a-pod]Connecting a Secret to a Pod[#connecting-a-secret-to-a-pod]
There are essentially two ways to attach a secret’s values to a pod:
- As a file mounted in a container.
- As an environment variable.
[#mounting-a-secret-as-a-file]Mounting a Secret as a file[#mounting-a-secret-as-a-file]
To mount a file into the container with the value of one of the secret’s keys, you can create a Pod file as follows:
There are two main parts here, the [.inline-code]volumes[.inline-code] key defines a new volume named [.inline-code]secret-volume[.inline-code]. The volume’s source is defined to be from a secret named [.inline-code]demo-secret[.inline-code] and we are saying take the key called [.inline-code]REDIS_HOST[.inline-code] from the secret and mount it as a file called ‘redis_host.txt’
The section above starting with [.inline-code]volumeMounts[.inline-code] takes the volume we defined and says to mount it at [.inline-code]/etc/config[.inline-code] so, in the end, we will have a file containing the value of REDIS_HOST mounted at [.inline-code]/etc/config/redis_host.txt[.inline-code]
[#mounting-a-secret-as-an-environment-variable]Mounting a Secret as an environment variable[#mounting-a-secret-as-an-environment-variable]
Attaching a secret to a container as an environment variable can be achieved using a [.inline-code]secretKeyRef[.inline-code] to reference a value from a secret when setting an environment variable.
For example, if we wanted to mount the [.inline-code]REDIS_HOST[.inline-code] key from our secret as an environment variable we can create the following pod file:
Where:
- [.inline-code]env.name[.inline-code] is how to call the environment variable inside the container.
- [.inline-code]secretKeyRef.name[.inline-code] is the name of the secret.
- [.inline-code]secretKeyRef.key[.inline-code] is the key inside the referenced secret we will attach to this environment variable.