2022-07-01

Kubernetes Secret

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:

bash
$ 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:

bash
$ 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:

bash
$ 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:

bash
$ 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:

bash
$ 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: ""
bash
$ 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:

bash
$ 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:

pod_secret_volume.yaml
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:

bash
$ 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:

bash
$ 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.

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!