ConfigMaps store config data that can be used by your Pods. A ConfigMap is a Kubernetes API object that contains one or more key-value pairs.
In this article, we’ll provide a complete guide to Kubernetes ConfigMaps. You’ll learn what they are, how to create them, and the ways in which they can be used with Pods.
We will cover:
Kubernetes ConfigMap is a built-in Kubernetes API object that’s designed to store your application’s non-sensitive key-value config data. ConfigMaps allow you to keep config values separate from your code and container images. Values can be strings or Base64-encoded binary data.
Once you’ve created a ConfigMap, its content will be saved to your Kubernetes cluster. Pods can then consume the ConfigMap’s values as environment variables, command line arguments, or filesystem volumes.
ConfigMaps are intended to store relatively small amounts of simple data. The total size of a ConfigMap object must be less than 1 MiB. If you need to store more data, you should split your configuration into multiple ConfigMaps or consider using a separate database or key-value store.
It’s good practice to use a ConfigMap to supply any configurable values that your app needs at runtime. The key-value pairs within the ConfigMap can be injected directly into your Pods in several different formats. Because ConfigMaps are part of the Kubernetes API, it’s possible to alter their values without re-deploying your app’s Pods.
What is a Kubernetes ConfigMap used for?
You should reach for a ConfigMap when your app deployments need access to config values that could change independently of your code. A classic example is a system that uses a database connection—you will need to supply the hostname or IP address of the database server for your app to function correctly.
In general, a ConfigMap is the right place to deposit any user-customizable settings that your application supports. End users can create a ConfigMap before installing your app in their cluster, enabling them to configure their deployment ahead of time.
Developing your app to read config values from its environment or filesystem allows you to decouple configuration from code and easily support multiple deployment methods. When you’re working locally on your laptop, you can set environment variables straight in your shell; for Kubernetes deployments, you can reference values in a ConfigMap.
Read more: How to Set up and Manage Kubernetes Environment Variables
Kubernetes stores ConfigMaps in its etcd datastore. You shouldn’t directly edit etcd data; instead, use the Kubernetes API server and Kubectl to create and manage your ConfigMaps.
To back up ConfigMap values, follow the guidance to set up backups for etcd. These backups will contain a complete copy of your cluster’s data.
Check out other best practices for Kubernetes security.
Because ConfigMaps are regular Kubernetes API objects, you can create them using YAML Kubernetes manifests files.
They require a top-level data
field that defines the key-value config pairs to store. Keys can only contain alphanumeric characters and the .
, -
, and _
symbols.
The following ConfigMap stores three properties: database_host
, debug_mode
, and log_level
:
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-config
data:
database_host: "192.168.0.1"
debug_mode: "1"
log_level: "verbose"
Save the manifest to demo-config.yaml
, then use Kubectl to apply it to your cluster and create the ConfigMap object:
$ kubectl apply -f demo-config.yaml
configmap/demo-config created
Example 1: Using data
and binaryData
fields
When you use the data
field, your ConfigMap values must be strings. ConfigMaps also support binary data within separate binaryData
field.
Binary values need to be Base64-encoded:
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-config
binaryData:
file_template: RGVtbwo=
You can use both data
and binaryData
in a single ConfigMap, but each key can only appear once—either in data
or in binaryData
.
Example 2: Listing and inspecting ConfigMaps
You can list the ConfigMaps you’ve created by running the kubectl get
command:
$ kubectl get configmaps
NAME DATA AGE
demo-config 3 83m
To inspect the key-value pairs within a ConfigMap, use kubectl describe
:
$ kubectl describe configmap demo-config
Name: demo-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
database_host:
----
192.168.0.1
debug_mode:
----
1
log_level:
----
verbose
BinaryData
====
Events: <none>
The ConfigMap’s content is visible under the Data
and BinaryData
headings.
Getting a ConfigMap’s Content as JSON
The following command will produce a JSON object that contains the ConfigMap’s key-value pairs:
$ kubectl get configmap demo-config -o jsonpath='{.data}' | jq
{
"database_host": "192.168.0.1",
"debug_mode": "1",
"log_level": "verbose"
}
This can be a more convenient way to inspect ConfigMaps and export their content into files.
Example 3: Mounting ConfigMaps into Pods as environment variables
Once you’ve created a ConfigMap, you can consume it within your Pods. You can access all or part of a ConfigMap as environment variables, command line arguments, or mounted files.
Environment variables are familiar, easy to consume in code, and open to easy inspection. They’re a good way to supply a small number of simple values to your application.
The following Pod (demo-pod.yaml
) makes the content of the demo-config
ConfigMap available as environment variables:
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: app
command: ["/bin/sh", "-c", "printenv"]
image: busybox:latest
envFrom:
- configMapRef:
name: demo-config
The envFrom
field instructs Kubernetes to create environment variables from the sources nested within it. The configMapRef
refers to a ConfigMap by its name and selects all its key-value pairs.
Add the Pod to your cluster, then retrieve its logs to see the output from the printenv
command. This should confirm that the three key-value pairs from the ConfigMap have been set as environment variables:
$ kubectl apply -f demo-pod.yaml
pod/demo-pod created
$ kubectl logs pod/demo-pod
...
database_host=192.168.0.1
debug_mode=1
log_level=verbose
...
Sometimes a Pod won’t require access to all the values contained in a ConfigMap. For example, you could have another Pod which only utilizes the log_level
value from our demo ConfigMap.
The env.valueFrom
syntax can be used instead of envFrom
for this use case. It lets you select individual keys in a ConfigMap. Keys can also be renamed to different environment variables:
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: app
command: ["/bin/sh", "-c", "printenv"]
image: busybox:latest
env:
- name: logging_mode
valueFrom:
configMapKeyRef:
name: demo-config
key: log_level
If you add this Pod to your cluster, you’ll see that only logging_mode
is set as an environment variable. It has the value of the log_level
key from the ConfigMap.
$ kubectl logs pod/demo-pod
...
logging_mode=verbose
...
Example 4: Mounting ConfigMaps into Pods as command line arguments
ConfigMap values can be interpolated into a container’s command line arguments by first referencing the relevant ConfigMap key as an environment variable:
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: app
command: ["demo-app", "--database-host", "$(DATABASE_HOST)"]
image: demo-app:latest
env:
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: demo-config
key: database_host
This technique allows you to change the command that’s run when your containers start, based on the current content of your ConfigMap. It supports scenarios where your app expects configuration to be supplied directly to its process upon startup.
Example 5: Mounting ConfigMaps into Pods as volumes
Environment variables and command line arguments can become unwieldy when you have many different values, or values containing a large amount of data. ConfigMaps can be mounted as volumes instead, allowing your app to read its config values from files within the container’s filesystem.
To set up a volume mount, add an entry to your Pod manifest’s spec.volumes
field that uses a configMap
entry to reference your ConfigMap by name. Then, use the volumeMounts
field to mount the volume to a read-only path in the container. The following manifest mounts the content of the demo-config
ConfigMap to /etc/app-config
:
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: app
command: ["ls", "/etc/app-config"]
image: demo-app:latest
volumeMounts:
- name: config
mountPath: "/etc/app-config"
readOnly: true
volumes:
- name: config
configMap:
name: demo-config
Apply this Pod to your cluster, then check its log output:
$ kubectl apply -f demo-pod.yaml
pod/demo-pod created
$ kubectl logs pod/demo-pod
database_host
debug_mode
log_level
The logs show the output from the ls /etc/app-config
command that the container is configured to run. The command confirms there are three files within the directory, corresponding to the keys in the ConfigMap. You should configure your app to read these files when it needs to access a config value.
Example 6: Using Immutable ConfigMaps
The ConfigMaps we’ve created so far have been mutable—you can modify them at any time by adding, changing, and removing keys. In practice, many apps are configured once, then expected to stay in the same configuration throughout their lifetime.
ConfigMaps can be marked as immutable to facilitate this use case. An immutable ConfigMap cannot be edited and you’ll see an error if you try to apply changes. This enhances safety by preventing accidental modification or deletion of ConfigMap keys that your app depends on.
To create an immutable ConfigMap, set its immutable
manifest property to true
:
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-config-immutable
data:
foo: bar
immutable: true
Save the example manifest to demo-config-immutable.yaml
, then add it to your cluster:
$ kubectl apply -f demo-config-immutable.yaml
configmap/demo-config-immutable created
Now try changing the ConfigMap, such as by changing foo
from bar
to baz
:
data:
foo: baz
When you re-apply the manifest, you’ll see a Forbidden
error because the immutable ConfigMap doesn’t permit modifications:
$ kubectl apply -f demo-config-immutable.yaml
The ConfigMap "demo-config-immutable" is invalid: data: Forbidden: field is immutable when `immutable` is set
You can use Kubectl or the Kubernetes API to change mutable ConfigMaps. However, modifications won’t necessarily affect existing Pods, depending on how you’ve consumed the ConfigMap:
- ConfigMaps consumed as environment variables or command line arguments will not update. Containers must restart to receive new environment variables and command line arguments. Consequently, containers consuming ConfigMaps using these methods won’t receive new values until they’re restarted.
- ConfigMaps consumed as volumes will automatically apply updates. Pods that mount a ConfigMap as a volume will receive the new ConfigMap’s values, but the change won’t be instantaneous. The Kubelet worker process running on your cluster’s Nodes periodically checks for ConfigMap changes and updates the content of the files mounted into your Pods.
Immutable ConfigMaps are never updated–it’s impossible for them to change. As a result, immutable ConfigMaps provide a performance advantage because worker Nodes can skip calling the API server to check for updates.
ConfigMaps are only suitable for values that aren’t sensitive or confidential. Data isn’t encrypted so it could be retrieved by anyone who gains access to your cluster’s etcd datastore.
ConfigMap vs Secrets
Kubernetes Secrets are an alternative to ConfigMaps that can be used to save confidential values with encryption support. Most real-world applications will therefore use a combination of ConfigMaps and Secrets when deploying to Kubernetes.
Values such as passwords, API keys, tokens, and certificates should be stored in a Kubernetes Secret instead. Secrets function similarly to ConfigMaps but are encrypted at rest, ensuring that your sensitive values are protected.
In summary, non-sensitive values such as DATABASE_HOST
should be added to ConfigMaps; valuable ones like DATABASE_PASSWORD
belong in a Secret.
Kubernetes ConfigMaps are Kubernetes resources that store arbitrary key-value data required by your application. Once you’ve created a ConfigMap, you can mount its values into your Pods as environment variables or volumes.
ConfigMaps are stored in plain-text so you should not use them for sensitive values including passwords and API keys. Kubernetes Secrets are an alternative to ConfigMaps that can be used to save confidential values with encryption support. Most real-world applications will therefore use a combination of ConfigMaps and Secrets when deploying to Kubernetes.
If you need any assistance with managing your Kubernetes projects, take a look at Spacelift. It brings with it a GitOps flow, so your Kubernetes Deployments are synced with your Kubernetes Stacks, and pull requests show you a preview of what they’re planning to change. It also has an extensive selection of policies, which lets you automate compliance checks and build complex multi-stack workflows. You can check it for free by creating a trial account.
Manage Kubernetes Easier and Faster
Spacelift allows you to automate, audit, secure, and continuously deliver your infrastructure. It helps overcome common state management issues and adds several must-have features for infrastructure management.