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.
0 Comments