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.
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
When you create a secret with, for example, a password
key=value pair; the value will be encoded in
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):
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
$ oc new-project project-of-secrets
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
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
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
$ 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.
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