Terminus by Warp
Create Kubernetes Secrets with `kubectl`

Create Kubernetes Secrets with `kubectl`

 Gabriel Manricks
Gabriel Manricks
Chief Architect at ClearX

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:

 $ kubectl create secret generic <secret_name>--from-literal <key>=<value>

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:

 $ kubectl create secret generic demo-secret --from-literal dbPassword=p4ssw0rd --from-literal
dbUser=postgres

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:

 $ kubectl get secret demo-secret -o yaml
apiVersion: v1
data:
  dbPassword: cDRzc3cwcmQ=
  dbUser: cG9zdGdyZXM=
kind: Secret
metadata:
  creationTimestamp: "2023-08-24T14:44:01Z"
  name: demo-secret
  namespace: default
  resourceVersion: "1170"
  uid: 4b6953b3-081d-4fa0-870c-79cf01c3199e
type: Opaque

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:

 $ kubectl get secret demo-secret -o jsonpath='{.data.dbUser}' | base64 -d
postgres

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:

 $ kubectl create secret generic <secret_name> --from-file <file_path>

For example:

 $ echo "secret text file" > secret.txt
$ kubectl create secret generic secret-file --from-file secret.txt
secret/secret-file created

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:

 $ kubectl create secret generic <secret_name> --from-file=<key_name>=<file_path>

For example:

 $ kubectl create secret generic secret-file --from-file=private-key=secret.txt

In this case, the key will be [.inline-code]private-key[.inline-code] instead of [.inline-code]secret.txt[.inline-code]

 $ kubectl get secret secret-file -o yaml
apiVersion: v1
data:
  private-key: U2VjcmV0IHRleHQgZmlsZQo=
kind: Secret
metadata:
  creationTimestamp: "2023-08-24T15:07:23Z"
  name: secret-file
  namespace: default
  resourceVersion: "1543"
  uid: b602f00b-dbeb-492c-8eb4-52608a1bd89f
type: Opaque

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.

 $ cat ~/.docker/config.json
{
    "auths": {
        "my-registry.harbor.local": {
            "auth": "cm9ib3Q6QTlRYXlxYWxpTkVRTnAyM3NlS0tkUjg1MXFZckhHSHE="
        }
}

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:

 $ cd ~
$ kubectl create secret docker-registry harbor-secret --from-file=.dockerconfigjson=.docker/config.json

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:

 $ kubectl create secret docker-registry demo-docker \
--docker-server=my-registry.harbor.local \
--docker-username=robot \
--docker-password=A9QayqaliNEQNp23seKKdR851qYrHGHq

You can then attach it to any pod spec to tell Kubernetes to use this Secret for pulling that image as follows:

 imagePullSecrets:
- demo-docker 

[#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:

 $ openssl req -newkey rsa:2048 -nodes -keyout server.pem -x509 -days 365 -out 
server.crt

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:

 $ kubectl create secret tls demo-tls --cert=server.crt --key=server.pem

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:

 tls:
  - hosts:
      - yourdomain.com
    secretName: demo-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]

 $ echo 'REDIS_HOST=redis-main' > staging.env
$ echo 'REDIS_PORT=8783' >> staging.env
$ cat staging.env
REDIS_HOST=redis-main
REDIS_PORT=8783

We can convert this file into a secret using the following command:

 $ kubectl create secret generic demo-env --from-env-file=staging.env
secret/demo-env created

$ kubectl get secret demo-env -o yaml
apiVersion: v1
data:
  REDIS_HOST: cmVkaXMtbWFpbg==
  REDIS_PORT: ODc4Mw==
kind: Secret
metadata:
  creationTimestamp: "2023-08-24T18:57:39Z"
  name: demo-env
  namespace: default
  resourceVersion: "4026"
  uid: 226f9f0d-9a22-40d6-84bf-68a1677a3492
type: Opaque

[#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:

  1. As a file mounted in a container.
  2. 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:

 apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/config
   volumes:
   - name: secret-volume
     secret:
       secretName: demo-env
       items:
       - key: REDIS_HOST
         path: redis_host.txt

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:

 apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    env:
    - name: REDIS_HOST
      valueFrom:
        secretKeyRef:
          name: demo-env
          key: REDIS_HOST

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.

Experience the power of Warp

  • Write with an IDE-style editor
  • Easily navigate through output
  • Save commands to reuse later
  • Ask Warp AI to explain or debug
  • Customize keybindings and launch configs
  • Pick from preloaded themes or design your own
brew install --cask warp
Copied!
Join the Windows waitlist:
Success! You will receive an email from Warp when the release is available to download.
Oops! Something went wrong while submitting the form.
Join the Linux waitlist:
Success! You will receive an email from Warp when the release is available to download.
Oops! Something went wrong while submitting the form.
Join the Linux waitlist or join the Windows waitlist
Join the Windows waitlist:
Success! You will receive an email from Warp when the release is available to download.
Oops! Something went wrong while submitting the form.