Developers have used Configuration as Code (CaC) and the Twelve-Factor App Methodology for years given the many benefits these practices have to offer. You can also accomplish this in Kubernetes, if you use an API resource called ConfigMap
to separate code and configuration.
Using ConfigMaps avoids Kubernetes configuration issues including:
- differing pace between app code development and changes in its configuration
- lack of proper version control for configuration, which prevents reversing changes when necessary
- accidental changes to Pod configuration
This article will explore what ConfigMaps are and how they work, and suggest different ways of creating them.
What are ConfigMaps?
In simple terms, a ConfigMap is a Kubernetes API object that allows you to store non-sensitive information. Since they are objects, ConfigMaps can be consumed by other API objects such as Pods. This makes them especially useful for storing environment variables, command-line arguments, or any configuration artifact in a file or volume.
How do they work?
Unlike other Kubernetes objects, ConfigMaps store data as key-value pairs using data
and binaryData
fields instead of spec
fields. That gives ConfigMaps the flexibility to store UTF-8 byte sequences (data
field) or binary data as base64-encoded strings (binaryData
field).
The information stored in ConfigMaps can be used in multiple ways. For example, it can be used within a container to execute command-line arguments or set environment variable values in that container. You can also add a ConfigMap file to a read-only volume and mount it inside as many Pods as required.
Although ConfigMaps are widely used to configure the settings of containers running inside Pods, their flexibility makes them useful for other tasks as well. Since ConfigMaps can be mounted as data volumes, they can be used by other parts of the system as add-ons or operators that conform to the parameters set in the corresponding ConfigMap.
You’ll need to keep the following in mind when creating a ConfigMap:
- The
ConfigMap
object should not be used to store confidential information such as user credentials or certificates, since the information is stored as plain text without encryption. - The name you assign to the
ConfigMap
object must be a valid DNS subdomain name. - Since ConfigMaps are intended to store configurations and variables, their file size is limited to 1 MB.
- In the
data
field, values can be stored in two different ways, as key-value pairs or as fragments of a configuration format (such as file-like keys). - For added security, as of Kubernetes v1.19, you can create immutable ConfigMaps by adding the
immutable
field to their definition.
Here is an example of a ConfigMap from the Kubernetes documentation:
Notice how the ConfigMap stores data both as property-like keys and file-like keys.
How to create a ConfigMap
You can create ConfigMaps from directories, regular files, files containing environment variables, or directly from the command line using literal values.
For the purposes of this guide, Docker Desktop will be used to run Kubernetes and illustrate how to create ConfigMaps. However, you can also use Katacoda, Play with Kubernetes, K3s, or minikube, among others.
The basic command to create a ConfigMap
using kubectl
CLI is as follows:
Let’s go through the components of this command.
map-name
- refers to the name of theConfigMap
data-source
- can be the path to a file or directory containing the ConfigMap(s)arguments
- specifies whether to use files or directories (--from-file
), environmental files (--from-env-file
), or literal values (--from-literal
)
Here are more details about that last component.
Creating a ConfigMap from an environmental file
Let’s start by creating a new directory to store the ConfigMaps:
Now, create an env.properties
file inside the configmaps
directory and paste the following content:
Save and close the env.properties
file and execute the following command to create the ConfigMap:
You will see the message configmap/game-demo
created. To review the ConfigMap’s contents in YAML format, you can use the command:
The output should be something similar to:
Creating a ConfigMap from a file
You can use a similar procedure to create a ConfigMap from a file. Paste the following content into the game.properties
file inside the configmaps
directory:
Then create the new ConfigMap using this command:
You can verify the content using the command:
The output should look like this:
Creating a ConfigMap from a directory
You can combine several files by using the --from-file
or --from-env-file
arguments multiple times, indicating each file’s path. However, a more efficient method is to specify a directory where all the files are located, as shown below:
kubectl create configmap game-demo-3 --from-file=configmaps
When using the command kubectl get configmap game-demo-3 -o yaml
, the result would be similar to this:
Creating a configmap from the command line
You can also create a ConfigMap from literal values. Use the --from-literal
argument as shown below:
kubectl create configmap game-demo-4 --from-literal=terrain.type=continent --from-literal=map.climate=tropical
When examining the ConfigMap using the command kubectl get configmap game-demo-4 -o yaml
, you should see something like this:
Alternative ways to create a ConfigMap
Since Kubernetes v1.14, you can also use kubectl
to manage objects using Kustomize.
Kustomize is designed to customize Kubernetes configurations. Among its features is a configMapGenerator
that generates ConfigMaps from files or literals.
For more information on Kustomize, read its official documentation here.
Why do you want to use ConfigMaps?
Here are some of the most important reasons to use ConfigMaps in your deployments:
- ConfigMaps enable you to separate the application code from its configuration.
- You won’t have to hardcode the configuration data in the Pod specification.
- As long as the application supports it, you can use ConfigMaps to update your configuration while the application is running.
- ConfigMaps allow you to create complex configurations with ease.
- Segregating the Pod definition from its configuration allows you to reuse the configuration (or part of it) in multiple Pods or objects.
- The separation of the configuration from the rest of the cluster objects allows for better version control.
- As of v1.19 you can create immutable ConfigMaps, so you can protect your deployment from accidental (or intentional) configuration changes.
Conclusion
Using ConfigMaps is not only a Kubernetes configuration best practice but a good way to facilitate and improve cluster management.
If you're looking for a better way to improve your Kubernetes cluster management, then try using Airplane. Airplane is the developer platform for building internal tools. With Airplane, you can easily transform scripts, queries, APIs, and more into powerful internal workflows and UIs.
To build your first internal workflow or UI, sign up for a free account or book a demo.