Kubernetes

How to Create Kubernetes Secrets

Damian Igbe, Phd
Feb. 26, 2022, 7:07 p.m.

Subscribe to Newsletter

Be first to know about new blogs, training offers, and company news.

This is a tutorial on how to create Kubernetes secrets. It is a continuation from how to create Kubernetes ConfigMaps.

Sensitive information such as passwords, tokens,  keys, ssh certificates  can be maintained centrally by Kubernetes Secrets and used by containers, APIs, endpoints,  databases, servers. Secrets are encoded in base64. Kubernetes ConfigMaps are used for non-sensitive data, while secrets are used for sensitive data. Once the secrets are created, they can be referenced in pods either through environmental variables or mounted as volumes. For details, refer to kubernetes documentation.

Creating Kubernetes Secrets

Secrets can either be created directly from the kubecetl CLI  or by first defining a manifest file with the details and then used to create the ConfigMaps.

Creating Secrets from the CLI

3 ways to create secrets from the CLI

Method 1: Use from-literal CLI argument

kubectl create secret generic hidden-secrets --from-literal=username=bob --from-literal=password=67utxrtsptr

Method 2:  Use from-file by putting content in file(s)

Another way of creating secrets from the CLI is to first create a file with the required contents. For example, we can put the username and password in files and then use the files in kubectl command. Here the name of the files signifies the keynames username and password respectively.

$ printf "bob\n" >> username

$ printf  "67utxrtsptr\n" >> password

$ kubectl create secret generic hidden-secret  --from-file=username --from-file=password
secret "hidden-secret" created

$ kubectl get secret

NAME                  TYPE                                  DATA      AGE

default-token-jkkj2   kubernetes.io/service-account-token   3         4d

hidden-secrets       Opaque                                 2         1m

hidden-secret         Opaque                                2         10s

Method 3: Use ssh-keygen utility

First generate the key pairs and then use them in kubectl command

$ ssh-keygen -t rsa -b 4096 -C “coolguy@cte.com”

$ kubectl create secret generic hideen-ssh-secret --from-file=ssh-privatekey=../.ssh/id_rsa --from-file=ssh-publickey=../.ssh/id_rsa.pub

Creating Secrets from Manifest file

To create a manifest file, you first need to convert the username and password to base64

$ echo -n 'bob' | base64
Ym9i

$ echo -n '67utxrtsptr' | base64
Njd1dHhydHNwdHI=

Now the manifest file

apiVersion: v1
kind: Secret
metadata:
  name: hidesecrets
type: Opaque
data:
  username: Ym9i
  password: Njd1dHhydHNwdHI=

With the manifest file we can do

$ kubectl create -f hidesecrets.yaml

Referencing Kubernetes Secrets  in Pods/Containers

There are  2 main ways to reference secrets  in a pod

1. Using secretKeyRef to reference environmental variables

env:
        - name: rdsusername
          valueFrom:
            secretKeyRef:
              name: hidesecrets
              key: username

After the pod is created, the environmental  variable rdsusername becomes available inside the pods and can then be referenced.

For example,  it is a common example to provide database connection details for applications to use. Let’s illustrate by using the hidesecrets secret (name: hidesecrets) created above in a Redis pod declaration below.

apiVersion: v1
kind: Pod
metadata:
  name: redis-with-secrets
spec:
  containers:
    - name: myredis
      image: redis:latest
      env:
        - name: rdsusername
          valueFrom:
            secretKeyRef:
              name: hidesecrets
              key: username
        - name: rdspassword
          valueFrom:
            secretKeyRef:
              name: hidesecrets
              key: password

kubectl create -f podsec.yaml
pod "myredis" created
$ kubectl exec myredis env | grep rdsusername
rdsusername=bob

$ kubectl exec myredis env | grep rdspassword
rdspassword=67utxrtsptr

 

2. Referencing Kubernetes secrets through mounted Volumes

The following will need to be added to each container declaration in the manifest file

volumeMounts:
    - name: secretvol
      mountPath: "/etc/volume"
      readOnly: true
  volumes:
  - name: secretvol
    secret:
      secretName: hidesecrets

Let’s use  Kubernetes deployment  to illustrate mounting secrets in pods/containers. The secrets will be mounted on each of the 3 pod replicas.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deploysecretvol
spec:
  replicas: 3
  template:
    metadata:
      labels:
        name: Cmdeploy
    spec:
      containers:
      - name: containersec1
        image: redis:latest
        volumeMounts:
         - name: secvol
           mountPath: "/etc/vol"
           readOnly: true
      volumes:
       - name: secvol
         secret:
           secretName: hidesecrets

 

Let’s use one of the pods to get the variables that we defined. The actual username and password can be seen when the variables are accessed inside the pods, as below.

$kubectl exec deploy2-520019706-c3xp3 ls /etc/vol 
password 
username 
$ kubectl exec deploy2-520019706-c3xp3 cat /etc/vol/password 
67utxrtsptr 
$ kubectl exec deploy2-520019706-c3xp3 cat /etc/vol/username 
bob

Note that when you look inside the secret, it doesn’t expose the secrets itself, else it won’t be secret :). Below, you can see that the username and password are presented in base64  format.

$ kubectl get secret hidesecrets -o yaml

apiVersion: v1
data:
  password: Njd1dHhydHNwdHI=
  username: Ym9i
kind: Secret
metadata:
  creationTimestamp: 2017-09-30T18:04:10Z
  name: hidesecrets
  namespace: default
  resourceVersion: "66687"
  selfLink: /api/v1/namespaces/default/secrets/hidesecrets
  uid: c252c466-a609-11e7-837a-080027fe81f7
type: Opaque

Conclusion

In this tutorial, you learned how to create secrets. Please take note of the following:

  • Secrets must be created before being referenced in a Pod specification (unless you mark the ConfigMap as “optional”).  Otherwise:
    •  The Pod won’t start if a referenced secret   doesn’t exist.
    • The Pod won’t start if the referenced key doesn’t exist in the secret
  • Secrets reside in a specific namespace. A Secret can only be referenced by pods residing in the same namespace.
  • You can have more than one file in a secret object, and you can use more than one secret in a pod spec file
  • There are system secrets and user created secrets. Systems secrets are created and managed by the Kubernetes system. When you do kubectl get secrets, it will list both the system and the user secrets in the current namespace.

Zero-to-Hero Program: We Train and Mentor you to land your first Tech role