Secrets

Secrets are similar to Config Maps but they are stored in an encoded format

Config Map

1apiVersion: v1
2kind: ConfigMap
3metadata:
4  name: app-config
5data:
6  APP_COLOR: pink
7  APP_MODE: prod

Secret

1apiVersion: v1
2kind: Secret
3metadata:
4  name: app-secret
5data:
6  APP_COLOR: pink
7  APP_MODE: prod

Creation

Imperative

Using the CLI

From Literal

1kubectl create secret generic \
2  <secret-name> --from-literal=<key>=<value>
1kubectl create secret generic \
2  <secret-name> \ 
3  --from-literal=APP_COLOR=blue \
4  --from-literal=APP_COLOR_1=pink \
5  --from-literal=APP_COLOR_2=green \

From Path

1kubectl create secret generic \
2  <secret-name> --from-path=<path-to-file>
1kubectl create secret generic \
2  <secret-name> --from-path=app_secret.properties

Declaritive

Using Yaml Syntax

Secret

Fiels Available

1apiVersion: v1
2kind:
3metadata:
4
5data:

Secret

Example

1apiVersion: v1
2kind: Secret
3metadata:
4  name: app-secret
5data:
6  APP_COLOR: cGluaw== #pink
7  APP_MODE: cHJvZA== #prod

How to base64 encode

1echo -n "value" | base64

Examples

1echo -n "pink" | base64
2echo -n "prod" | base64

To Decode (ignore %)

echo -n "value" | base64 -d

Example

echo -n "cGluaw==" | base64 -d

pink%

DEBUG

Get Secrets

kubectl get secret

kubectl get secret

NAME                     TYPE                DATA   AGE
mantisd-io-staging-tls   kubernetes.io/tls   2      7d17h
mantisd-io-tls           kubernetes.io/tls   2      7d17h

Describe Secret

kubectl describe secret <secret-name>

kubectl describe secret mantisd-io-tls

Name:         mantisd-io-tls
Namespace:    default
Labels:       <none>
Annotations:  cert-manager.io/alt-names: *.mantisd.io,mantisd.io
              cert-manager.io/certificate-name: mantisd-io
              cert-manager.io/common-name: *.mantisd.io
              cert-manager.io/ip-sans: 
              cert-manager.io/issuer-group: 
              cert-manager.io/issuer-kind: ClusterIssuer
              cert-manager.io/issuer-name: letsencrypt-production
              cert-manager.io/uri-sans: 

Type:  kubernetes.io/tls

Data
====
tls.key:  1679 bytes
tls.crt:  5599 bytes

Get Secret Yaml

kubectl get secret <secret-name> -o yaml

kubectl get secret mantisd-io-tls -o yaml

apiVersion: v1
data:
  tls.crt: asdasdasdasdasdasdasdasd
  tls.key: asdasdasdasdasdasdasdasd
kind: Secret
metadata:
  annotations:
    cert-manager.io/alt-names: '*.mantisd.io,mantisd.io'
    cert-manager.io/certificate-name: mantisd-io
    cert-manager.io/common-name: '*.mantisd.io'
    cert-manager.io/ip-sans: ""
    cert-manager.io/issuer-group: ""
    cert-manager.io/issuer-kind: ClusterIssuer
    cert-manager.io/issuer-name: letsencrypt-production
    cert-manager.io/uri-sans: ""
  creationTimestamp: "2022-10-30T02:09:48Z"
  name: mantisd-io-tls
  namespace: default
  resourceVersion: "93005"
  uid: 6520e20c-ad81-4020-ae57-fc3963a0202f
type: kubernetes.io/tls

Use Secret

Secret

1apiVersion: v1
2kind: Secret
3metadata:
4  name: app-secret
5data:
6  APP_COLOR: cGluaw== #pink
7  APP_MODE: cHJvZA== #prod

envFrom

 1
 2apiVersion: 
 3kind: Pod
 4metadata:
 5  name: simple-webapp-color
 6spec:
 7  containers:
 8    - name: simple-webapp-color
 9      image: simple-webapp-color
10      ports:
11        - containerPort: 8080
12
13      envFrom:
14        - secretRef:
15            name: app-config

env valueFrom

 1
 2apiVersion: 
 3kind: Pod
 4metadata:
 5  name: simple-webapp-color
 6spec:
 7  containers:
 8    - name: simple-webapp-color
 9      image: simple-webapp-color
10      ports:
11        - containerPort: 8080
12
13      env:
14        - name: APP_COLOR
15          valueFrom:
16            secretKeyRef:
17              name: app-secret
18              key: APP_COLOR

volume

 1
 2apiVersion: 
 3kind: Pod
 4metadata:
 5  name: simple-webapp-color
 6spec:
 7  containers:
 8    - name: simple-webapp-color
 9      image: simple-webapp-color
10      ports:
11        - containerPort: 8080
12
13      volumes:
14        - name: app-secret-volume
15          secret:
16            secretName: app-config

This will Add each secret as an individual file

Inside Container

ls /opt/app-secret-volumes

APP_COLOR APP_MODE

cat /opt/app-secret-volumes/APP_COLOR

pink

Tips

Remember that secrets encode data in base64 format. Anyone with the base64 encoded secret can easily decode it. As such the secrets can be considered as not very safe.

The concept of safety of the Secrets is a bit confusing in Kubernetes. The kubernetes documentation page and a lot of blogs out there refer to secrets as a "safer option" to store sensitive data. They are safer than storing in plain text as they reduce the risk of accidentally exposing passwords and other sensitive data. In my opinion it's not the secret itself that is safe, it is the practices around it.

Secrets are not encrypted, so it is not safer in that sense. However, some best practices around using secrets make it safer. As in best practices like:

  • Not checking-in secret object definition files to source code repositories.

  • Enabling Encryption at Rest for Secrets so they are stored encrypted in ETCD.

Also the way kubernetes handles secrets. Such as:

  • A secret is only sent to a node if a pod on that node requires it.

  • Kubelet stores the secret into a tmpfs so that the secret is not written to disk storage.

  • Once the Pod that depends on the secret is deleted, kubelet will delete its local copy of the secret data as well.

Read about the protections and risks of using secrets here

Having said that, there are other better ways of handling sensitive data like passwords in Kubernetes, such as using tools like Helm Secrets, HashiCorp Vault. I hope to make a lecture on these in the future.

  • Secrets are not Encrypted. Only Encoded
  • Do Not Check In Secret objects to SCM along with code
  • Secrets are not Encrypted in ETCD
  • Anyone who has access to to Namespace has access to all secrets in that Namespace
  • Configure RBAC to Secrets
  • Consider 3rd Party secret store Providers like Vault