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.
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.
3 ways to create secrets from the CLI
kubectl create secret generic hidden-secrets --from-literal=username=bob --from-literal=password=67utxrtsptr
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
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
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
There are 2 main ways to reference secrets in a pod
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
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
In this tutorial, you learned how to create secrets. Please take note of the following: