Our applications often need to deal with sensitive information such as credentials or private keys. In a Kubernetes-based system, we can handle such sensitive information using Secrets.

In this post, I will explain how you can create a new Kubernetes Secret and use it in an application pod.

1 – What are Kubernetes Secrets?

Kubernetes Secrets are basically objects that can store sensitive data such as database credentials with encryption, private keys and so on.

Secrets in Kubernetes follow the principle of least privilege.

They act as separate objects. Application pods can query them to provide credentials to the application for access to external resources. Pods can only access the secrets if they are part of a mounted volume or at the time when the kubelet is pulling the image for the Pod.

2 – Kubernetes Secrets vs Config Maps

On face value Kubernetes Secrets look quite similar to Config Maps.

For example, both are basically key-value pairs. Also, both are used for managing configuration data in Kubernetes.

However, they serve distinct purposes and have some crucial differences with each other.

  • Secrets store sensitive data such as passwords, API tokens and certificates. They are encoded in base64 to enhance security.
  • On the other hand, Kubernetes Config Maps are for non-sensitive configuration data such as environment variables, application settings or custom configurations. They are plain text and don’t offer the same level of protection as Secrets.

In a nutshell, you need to use Secret or Config Map depending on the requirement of your application.

3 – Creating a New Kubernetes Secret

Let’s imagine that you want to create a Secret to store some credentials (user id and password).

As a first step, you need to convert them into base64 encoding as follows:

$ echo -n 'my-user' | base64
bXktdXNlcg==
$ echo -n 'password' | base64
cGFzc3dvcmQ=

With the base64 encodings ready, you can create a Kubernetes Secret YAML file as follows:

apiVersion: v1
kind: Secret
metadata:
  name: demo-secret
data:
  username: bXktdXNlcg==
  password: cGFzc3dvcmQ=

You can now apply the secret file with the below command.

$ kubectl apply -f secret.yaml

You can get the details about the secret by executing the below command.

$ kubectl get secret demo-secret
NAME          TYPE     DATA   AGE
demo-secret   Opaque   2      5m

In fact, you can view even more details about the secret by using the below command.

$ kubectl describe secret demo-secret
Name:         demo-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
username:  7 bytes
password:  8 bytes

By default, the Type of secret is Opaque.

The term “Opaque” implies that Kubernetes doesn’t have specific knowledge or handling of the data within the type of Secret.

Opaque Secrets are typically used for storing data that are not intended to be processed by Kubernetes itself. Instead, they are meant for holding generic, user-defined or application-specific data.

You can also create the Secret by skipping the base64 encoding step.

In this approach, you can directly use the kubectl create secret command as follows:

$ kubectl create secret generic test-secret --from-literal='username=my-user' --from-literal='password=password'

4 – Using a Secret in a Kubernetes Pod Through Volume

Here’s a sample YAML file for using the Secret within the Kubernetes Pod using a volume.

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      volumeMounts:
        - name: demo-secret
          mountPath: /etc/secret-volume
          readOnly: true
  volumes:
    - name: secret-volume
      secret:
        secretName: demo-secret

You can create the Pod by simply applying the YAML file.

$ kubectl apply -f test-pod.yaml

Once the pod starts, you can open an interactive terminal and see the volume directory. If you list the contents, you should see two files – one for each secret i.e. username and password.

$ kubectl exec -i -t test-pod -- /bin/bash
$ ls /etc/secret-volume
username
password

5 – Using a Secret in a Pod Through Environment Variables

You can also consume the data in Secrets as environment variables in your pod.

See the below YAML:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: test-container
    image: nginx
    env:
    - name: SECRET_USERNAME
      valueFrom:
        secretKeyRef:
          name: demo-secret
          key: username

However, if a container already consumes a Secret in an environment variable, a Secret update will not be seen by the container unless it is restarted. 

Conclusion

With this, we have looked at the various aspects of Kubernetes Secrets.

We learnt how to create a Secret and use it in a Kubernetes Pod using two different approaches:

  • Through volume
  • Through environment variables

If you have any queries or comments, please feel free to mention them in the comments section below.

Categories: BlogKubernetes

Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *