Skip to the content.

Kubernetes Secrets

Create secret

This example shows how Secrets can be used to allow Pods access to a database.

Create and enter a new lab directory

mkdir -p $HOME/labs/secrets && cd $HOME/labs/secrets

Create secret files

echo -n "admin" > ./username.txt
echo -n "1f2d1e2e67df" > ./password.txt

Now, let’s create the secret objects out of the files.

kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt

Confirm secret was created

kubectl get secrets 

Now describe the secret

kubectl describe secrets/db-user-pass 
Name:            db-user-pass
Namespace:       default
Labels:          <none>
Annotations:     <none>

Type:            Opaque

Data
====
password.txt:    12 bytes
username.txt:    5 bytes

Notice that neither get nor describe shows the contents of the file. This is to protect the secret from being exposed, or being stored in a terminal log.

Create Secret Manually

You can also create a secret object in a JSON or YAML file and create the object.

To do this each item must be base64 encoded

echo -n "admin" | base64
echo -n "1f2d1e2e67df" | base64

Now let’s write a secret object using encoded data from above.

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

Create a secret from above file

kubectl create -f ./secret.yaml

Decoding Secrets

Using kubectl and base64 we can decode our secrets

kubectl get secret mysecret -o yaml

We will get output similar to

apiVersion: v1
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
  creationTimestamp: 2016-01-22T18:41:56Z
  name: mysecret
  namespace: default
  resourceVersion: "164619"
  selfLink: /api/v1/namespaces/default/secrets/mysecret
  uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque

Now let’s decode it

echo "MWYyZDFlMmU2N2Rm" | base64 --decode

Using Secrets

Secrets can be mounted as data volumes or be exposed as environment variables to be used by a container in a pod. They can also be used by other parts of the system, without being directly exposed to the pod. For example, they can hold credentials that other parts of the system should use to interact with external systems on your behalf.

To use Secrets as files from a Pod we can use the following YAML

secret-mount.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

Inside the container that mounts a secret volume, the secret keys appear as files and the secret values are base-64 decoded and stored inside these files. This is the result of commands executed inside the container from the example above:

List secrets

kubectl exec -it mypod -- ls /etc/foo

Output username

kubectl exec -it mypod -- cat /etc/foo/username

Output password

kubectl exec -it mypod -- cat /etc/foo/password

Secrets as Environment Variables

Use the following YAML to create a Pod that uses environment variable secret

secret-env.yaml

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
  restartPolicy: Never

Now let’s confirm the secret is available in the container. Log in to the container

kubectl exec -it secret-env-pod -- bash 

Echo the environment variables

echo $SECRET_USERNAME
echo $SECRET_PASSWORD

You can also get the vault of the variables from the host machine.

kubectl exec secret-env-pod -- sh -c 'echo $SECRET_USERNAME'
kubectl exec secret-env-pod -- sh -c 'echo $SECRET_USERNAME'

Lab complete