Creating Secrets (like creating ConfigMaps) is a vital part of Managing OpenShift workloads and is an exam objectives of the EX280 exam. Knowing how they work and how to configure them (from the command-line) will give you a better understanding of Secrets.
Secrets, how do they work
Secrets provide information (like config files or credentials) to workloads in your cluster. You can use a secret to provide a username and password to your pod or to add a SSL certificate to it.
No data on the node
When exposing secrets using volumes the data is stored in a tmpfs filesystem. This means that the data in de secret is not directly exposed to the node that the pod’s are running on1.
This provides a bit more security than that of ConfigMaps.
Secret types
There are 3 secret types available for you to us. Don’ worry, they are quite easy to keep apart:
- docker-registry secrets are used by the internal docker registry of your container platform
- tls secrets are used to provide tls certificates, keys or other supporting files to a pod
- generic secrets are used to store everything from an API key to a config file
I will be discussing generic secrets in this post.
Encoding vs Encryption
An important factor to know when working with secrets are that they are not encrypted. The “secret” part of secrets is that they are not readable without decoding them. By default secrets are encodes in a base64 encoding.
When you create a secret with, for example, a password key=value pair; the value will be encoded in base64.
We can simulate this in bash:
$ echo 'encoded_password' | base64
ZW5jb2RlZF9wYXNzd29yZAo=
$ echo 'ZW5jb2RlZF9wYXNzd29yZAo=' | base64 -d
encoded_password
In this case the key=value pair would be rendered in our secret like this (because only the value is encoded, and not the key):
password=ZW5jb2RlZF9wYXNzd29yZAo=
When we create a secret from yaml we need to encode it first. But when we create a secret with oc create the cluster takes care of this encoding for us. If you would use oc edit to live edit a secret, don’t forget to encode the string you are replacing.
Creating a secret
Creating a secret can be done by creating a yaml file and applying it to the cluster or by using the oc create secret command.
Creating a secret from yaml
Creating a secret form a yaml definition is quite easy when you know the layout. You always get an example from the official documentation or use oc explain secrets
The following is a yaml secret with our own value filled in:
# our-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: project-of-secrets
type: Opaque
data:
password: ZW5jb2RlZF9wYXNzd29yZAo=
If we wanted to create a secret from this we would do so with:
$ oc apply -f our-secret.yaml
Creating a secret from the cli
If your in a hurry (or don’t want to create yaml files for all your secrets). You can create a secret without a definition file.
As a demo you can setup a special testing namespace. As you can see in my yaml example I called this one project-of-secrets:
$ oc new-project project-of-secrets
From Literal
You could create a secret from the command-line with the following command:
$ oc create secret generic \
SECRET_NAME \
--from-literal KEY1=VALUE1 \
--from-literal KEY2=VALUE2
As an example:
$ oc create secret generic test-secret-literal \
--from-literal password=encoded_secret
secret/test-secret-literal created
From File
If you want your secret to be filled with an entire file:
$ oc create secret generic \
SECRET_NAME \
--from-file KEY1=/PATH/TO/FILE1
As an example:
$ echo "Our verry secret file" > secret-file.txt
$ oc create secret generic test-secret-file --from-file secret-file.txt
secret/test-secret-file created
Adding a secret to a pod
Secrets can be supplied to a pod much like ConfigMaps. For more info on those, I wrote an entire blog regarding the creation and usage of them.
Just like ConfigMaps we can provide secret data to pods as ENV variables or as a volume. We will use the secret/test-secret-literal and our demoapp as an example, you can create a demo app with:
$ oc new-app --name demoapp --docker-image bitnami/nginx
--> Creating resources ...
imagestream.image.openshift.io "demoapp" created
deployment.apps "demoapp" created
service "demoapp" created
Secret as ENV Variable
We use the oc set env command to set a secret as ENV Vars for our pod:
$ oc set env deployment/demoapp \
--from secret/test-secret-literal
deployment.extensions/demoapp updated
We can now see the secret in action when we enter the pod:
$ oc get pods
NAME READY STATUS RESTARTS AGE
demoapp-557f47dccb-2gzvp 1/1 Running 0 41s
$ oc rsh demoapp-557f47dccb-2gzvp bash
(pod) $ env | grep -i password
PASSWORD=encoded_secret
Using a prefix
You can also prefix your secrets in the pod using the --prefix option. This will add a prefix like mysql_ or our_prefix_ to all the key’s that are being added. Tis can be quite handy for example when you want to use the mysql app because that app expects all values to be prefixed.
As an example, we will create a secret from-literal and then add it with a prefix:
$ oc create secret generic prefix-example \
--from-literal key=a_value
secret/prefix-example created
And then we add it with the --prefix option:
$ oc set env deployment/demoapp \
--from secret/prefix-example \
--prefix our_prefix_ \
deployment.extensions/demoapp updated
Now, when we enter the pod and echo the ENV variables we will see the key being prefixed:
$ oc get pods -o name
pod/demoapp-6c9b77c-dw4c2
$ oc rsh pod/demoapp-6c9b77c-dw4c2 bash
(pod) $ env | grep -i 'key'
our_prefix_KEY=a_value
Secret as file
Warning: Mounting a volume on path that already exists on a pod will make all files in that directory inaccessible
To create a volume that will hold the secret we use the oc set volume command:
$ oc set volume \
deployment/demoapp \
--add \
--type secret \
--mount-path /etc/secret \
--secret-name test-secret-literal
info: Generated volume name: volume-zjmsq
deployment.extensions/demoapp volume updated
We can see the mounted secret action from the pod in actions as well:
$ rsh demoapp-557f47dccb-2gzvp bash
(pod) $ cat /etc/secret/password
encoded_secret
As you can see a file is created with the name of the key containing the value of the value from our secret.
Closing thoughts
Secrets might not be as secret as you would hope but they provide a fundamental way of exposing sensitive data to our pods on OpenShift and you will certainly encounter them on a daily basis if you manage any kind of Container Cluster.
See more of my EX280 and OpenShift related posts here
-
https://docs.openshift.com/container-platform/4.9/nodes/pods/nodes-pods-secrets.html#nodes-pods-secrets-about_nodes-pods-secrets ↩
Found this useful? Consider sponsoring me or buying me a cup of coffee at KoFi or get notified when I share new things