What is a Secret in Kubernetes
In Kubernetes, a Secret is a resource that helps us save key-value pairs in an encoded form, particularly in Base64 format. Secrets serve as a means to manage sensitive data like passwords, tokens, or keys which applications might need during their runtime. The fact that the data stored is Base64 encoded means that, while it is not directly readable, it's not truly encrypted. Anyone with the encoded value can decode it without a decryption key, so while Secrets help avoid storing sensitive data in plaintext in your applications, they are not a standalone solution for securing sensitive information.
Differences between Secret and ConfigMap
While both Secrets and ConfigMaps allow you to decouple configuration details from your containerized application code, they are used for different types of data.
ConfigMaps are ideal for storing and sharing non-sensitive, static configuration data in the form of key-value pairs. You can use ConfigMaps to store things like configuration files, properties files, or even JSON blobs.
Secrets, on the other hand, are specifically designed for sensitive information. They offer a more secure and flexible solution than ConfigMaps when it comes to storing confidential data. Although Secrets are not encrypted by default, Kubernetes offers integration with cloud provider key management systems to store secrets encrypted at rest.
Demonstration of Kubernetes Secret
I'll demonstrate how to create and use Kubernetes Secrets.
Starting Minikube
Before we get started, ensure that Minikube is up and running on your machine. To start Minikube, use the following command:
$ minikube start
Creating a Secret
The process of creating a Secret is similar to creating a ConfigMap. Here, we'll make use of the command kubectl create secret
.
We'll use a handy command --dry-run
for a dry run, and -o yaml
to generate a manifest. See the following command:
$ kubectl create secret generic my-secret \
--from-literal=SECRET_KEY1=SECRET_VALUE1 \
--from-literal=SECRET_KEY2=SECRET_VALUE2 \
--dry-run=client -o yaml
This will produce an output that looks like this:
apiVersion: v1
data:
SECRET_KEY1: U0VDUkVUX1ZBTFVFMQ==
SECRET_KEY2: U0VDUkVUX1ZBTFVFMg==
kind: Secret
metadata:
creationTimestamp: null
name: my-secret
After confirming the manifest, we'll save it to secret.yaml
file with the command:
$ kubectl create secret generic my-secret \
--from-literal=SECRET_KEY1=SECRET_VALUE1 \
--from-literal=SECRET_KEY2=SECRET_VALUE2 \
--dry-run=client -o yaml > secret.yaml
Creating a Secret from a Manifest
We then apply the manifest using kubectl apply
to create the secret:
$ kubectl apply -f secret.yaml
secret/my-secret created
Displaying and Inspecting the Secret
After the Secret is created, you can display its information in YAML format or check its details with the following commands:
$ kubectl get secret -o yaml
apiVersion: v1
items:
- apiVersion: v1
data:
SECRET_KEY1: U0VDUkVUX1ZBTFVFMQ==
SECRET_KEY2: U0VDUkVUX1ZBTFVFMg==
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"SECRET_KEY1":"U0VDUkVUX1ZBTFVFMQ==","SECRET_KEY2":"U0VDUkVUX1ZBTFVFMg=="},"kind":"Secret","metadata":{"annotations":{},"creationTimestamp":null,"name":"my-secret","namespace":"default"}}
creationTimestamp: "2022-06-25T02:01:34Z"
name: my-secret
namespace: default
resourceVersion: "644"
uid: f46d9fae-afeb-46e5-8fbd-eff006a59993
type: Opaque
kind: List
metadata:
resourceVersion: ""
$ kubectl describe secret my-secret
Name: my-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
SECRET_KEY2: 13 bytes
SECRET_KEY1: 13 bytes
Decoding the Secret
Remember, the Secret values are Base64 encoded, not encrypted. This means that anyone with access to the encoded data can decode it and retrieve the original values:
$ echo U0VDUkVUX1ZBTFVFMQ== | base64 --decode
SECRET_VALUE1
This reveals the original value of our Secret key.
Mounting a Secret as a Volume in a Pod
Here I'll demonstrate how to mount a Kubernetes Secret as a volume in a Pod. We'll use the Secret we created in the previous chapter.
Defining References to Secret in a Pod Manifest
We begin by defining a Pod manifest where we specify how to use the Secret. Here, we'll mount the Secret as a volume in the Pod. Here's an example of a Pod manifest that includes a reference to the Secret my-secret
:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: helloworld-secret-volume
name: helloworld-secret-volume
spec:
containers:
- image: bhargavshah86/kube-test:v0.1
name: helloworld-secret-volume
ports:
- containerPort: 8080
resources: {}
volumeMounts:
# Specify the volume name
- name: my-secret-volume
# Specify the path in the container where the volume should be mounted
mountPath: /my-secret
readOnly: true
volumes:
# Specify the volume name to be created
- name: my-secret-volume
secret:
# Specify the Secret name
secretName: my-secret
status: {}
Creating the Pod
After defining the Pod manifest, we can create the Pod with the following command:
$ kubectl apply -f pod_secret_volume.yaml
Checking the Value of Secret Inside the Pod
Once the Pod is up and running, we can check the value of the Secret inside the Pod with the following command:
$ kubectl exec -it helloworld-secret-volume -- cat /my-secret/SECRET_KEY1
SECRET_VALUE1%
This should display the original value of the Secret, indicating that the Secret was successfully mounted as a volume in the Pod and can be used by the applications running inside the Pod.