ConfigMaps & Secrets
ConfigMaps
ConfigMaps allow us to decouple the configuration details from the container image. Using ConfigMaps, we pass configuration data as key-value pairs, which are consumed by Pods or any other system components and controllers, in the form of environment variables, sets of commands and arguments, or volumes. We can create ConfigMaps from literal values, from configuration files, from one or more files or directories.
Create a ConfigMap from Literal Values
A ConfigMap can be created with the imperative kubectl create configmap
command, and we can display its details using the kubectl get
or kubectl describe
commands.
Create the ConfigMap:
Display the ConfigMap details in YAML for my-config:
With the -o yaml
option, we are requesting the kubectl
command to produce the output in the YAML format. The object has the ConfigMap kind
, and it has the key-value pairs listed under the data
field. The name of ConfigMap
and other details are part of the metadata
field.
Create a ConfigMap from a Definition Manifest
For a declarative approach, first we need to create a definition file with the following content:
where we specify the kind
, metadata
, and data
fields, targeting the v1 endpoint of the API server.
If we name the file with the definition above as customer1-configmap.yaml
, we can then create the ConfigMap with the following command:
Create a ConfigMap from a File
First, we need to create a file permission-reset.properties
with the following configuration data stored as key-value pairs:
We can then create the ConfigMap with the following command:
Use ConfigMaps Inside Pods: As Environment Variables
Inside a Container, we can retrieve the key-value data of an entire ConfigMap or the values of specific ConfigMap keys as environment variables.
In the following example all the myapp-full-container
Container’s environment variables receive the values of the full-config-map
ConfigMap keys:
In the following example the myapp-specific-container
Container’s environment variables receive their values from specific key-value pairs from two separate ConfigMaps, config-map-1
and config-map-2
respectively:
With the configuration presented above, we will get the SPECIFIC_ENV_VAR1
environment variable set to the value of SPECIFIC_DATA
key from config-map-1
ConfigMap, and SPECIFIC_ENV_VAR2
environment variable set to the value of SPECIFIC_INFO
key from config-map-2
ConfigMap.
Use ConfigMaps Inside Pods: As Volumes
We can mount a vol-config-map
ConfigMap as a Volume inside a Pod. The configMap
Volume plugin converts the ConfigMap object into a mountable resource. For each key in the ConfigMap, a file gets created in the mount path (where the file is named with the key name) and the respective key’s value becomes the content of the file:
For more details, please explore the documentation on using ConfigMaps.
Using ConfigMaps as Volumes Demo Guide
This exercise guide was prepared for the video demonstration available in this chapter. It includes an index.html
file and a Deployment definition manifest that can be used as templates to define other similar objects as needed. The goal of the demo is to store the custom webserver index.html
file in a ConfigMap object, which is mounted by the nginx container specified by the Pod template nested in the Deployment definition manifest.
The webserver index file:
The Deployment definition manifest:
Demo: Using ConfigMaps as Volumes
Secrets
Let’s assume that we have a Wordpress blog application, in which our wordpress frontend connects to the MySQL database backend using a password. While creating the Deployment for wordpress, we can include the MySQL password in the Deployment’s YAML definition manifest, but the password would not be protected. The password would be available to anyone who has access to the definition manifest.
In this scenario, the Secret object can help by allowing us to encode in base 64the sensitive information before sharing it. We can share sensitive information like passwords, tokens, or keys in the form of key-value pairs, similar to ConfigMaps; thus, we can control how the information in a Secret is used, reducing the risk for accidental exposures. In Deployments or other resources, the Secret object is referenced, without exposing its content.
It is important to keep in mind that by default, the Secret data is stored as plain text inside etcd, therefore administrators must limit access to the API server and etcd. However, Secret data can be encrypted at rest while it is stored in etcd, but this feature needs to be enabled at the API server level by the Kubernetes cluster administrator.
Create a Secret from Literal Values
To create a Secret, we can use the imperative kubectl create secret
command:
The above command would create a secret called my-password
, which has the value of the password key set to mysqlpassword
.
After successfully creating a secret we can analyze it with the get
and describe
commands. They do not reveal the content of the Secret. The type is listed as Opaque
.
Create a Secret from a Definition Manifest
We can create a Secret manually from a YAML definition manifest. The example manifest below is named mypass.yaml
. There are two types of maps for sensitive information inside a Secret: data
and stringData
.
With data
maps, each value of a sensitive information field must be encoded using base64. If we want to have a definition manifest for our Secret, we must first create the base64 encoding of our password:
and then use it in the definition manifest:
Please note that base64 encoding does not mean encryption, and anyone can easily decode our encoded data:
Therefore, make sure you do not commit a Secret’s definition file in the source code.
With stringData
maps, there is no need to encode the value of each sensitive information field. The value of the sensitive field will be encoded when the my-password Secret is created:
Using the mypass.yaml
definition file we can now create a secret with kubectl create
command:
Create a Secret from a File
To create a Secret from a File, we can use the kubectl create secret
command.
First, we encode the sensitive data and then we write the encoded data to a text file:
Now we can create the Secret from the password.txt
file:
After successfully creating a secret we can analyze it with the get
and describe
commands. They do not reveal the content of the Secret. The type is listed as Opaque.
Use Secrets Inside Pods: As Environment Variables
Secrets are consumed by Containers in Pods as mounted data volumes, or as environment variables, and are referenced in their entirety (using the envFrom
heading) or specific key-values (using the env
heading).
Below we reference only the password
key of the my-password
Secret and assign its value to the WORDPRESS_DB_PASSWORD
environment variable:
Use Secrets Inside Pods: As Volumes
We can also mount a Secret as a Volume inside a Pod. The secret
Volume plugin converts the Secret object into a mountable resource. The following example creates a file for each my-password
Secret key (where the files are named after the names of the keys), the files containing the values of the respective Secret keys:
For more details, you can explore the documentation on managing Secrets.