ConfigMaps are a powerful tool for managing Kubernetes configuration. In this article, we’ll show you how to use them to manage your cluster’s settings. ..
A ConfigMap is a Kubernetes resource for injecting configuration into your containers. They let you maintain your stack’s settings separately from its code. Here’s how to work with ConfigMaps and supply them to your Pods.
What Are ConfigMaps For?
ConfigMaps are specifically designed to encapsulate small amounts of non-sensitive configuration data. They’re a mechanism for getting arbitrary key-value pairs into your Pods. They’re commonly used to store your database server’s IP address, the outgoing email address for your application, and other application-specific settings which you need to be configurable outside your Pods.
The ConfigMap lets you manage this data in a dedicated Kubernetes resource. Pods receive the key-value pairs as environment variables or files in a mounted volume.
What Not to Use Them For?
There are some situations where a ConfigMap should not be used.
ConfigMaps are not stored securely and their values have no encryption. They mustn’t contain any sensitive or confidential data which would constitute a security or privacy risk if leaked.
Don’t put passwords, API keys, or encryption keys into a ConfigMap – use a Kubernetes Secret instead, as these function similarly to ConfigMaps but with additional protections. Systems needing a database connection should place the hostname in a ConfigMap and credentials in a separate Secret.
Individual ConfigMaps cannot exceed 1 MB in size. Systems which need more configuration keys may be better served by an alternative approach such as injection of manually generated config files via a volume.
If you want to stick with ConfigMaps, consider splitting your configuration across multiple ConfigMap resources. This approach should avoid the 1 MB cap while letting you supply each of your Pods with the minimal set of config keys it needs.
ConfigMap values can be either UTF-8 strings or binary data encoded as a base64 string. Key names can contain alphanumeric, . (period), - (hyphen), and _ (underscore) characters. Some programming languages and frameworks may have a different convention for config variables so make sure you use a format that’s supported by both Kubernetes and your app.
Creating a ConfigMap
ConfigMaps have simple YAML manifests. Each ConfigMap needs a name in the standard Kubernetes format and a data field containing your key-value pairs:
The data field is for specifying keys with string values. You can use binaryData instead or as well as data to add base64-encoded binary values. Keys must be unique across both data and binaryData.
Apply the manifest to your cluster using kubectl or your preferred tool.
Linking ConfigMaps and Pods
A ConfigMap doesn’t do anything on its own. You’ve added some data to your cluster; now let’s link it to a Pod:
The envFrom field pulls in environment variables defined by another referenced resource. In this case, a configMapRef identifies the ConfigMap created earlier. The Pod’s containers will be started with database_host and system_email environment variables defined.
Selectively Adding Environment Variables
envFrom is useful when you want to consume every key in the ConfigMap and you’re certain there’ll be no conflicts with your Pod’s other environment variables. In more controlled situations, use a regular env section, define individual keys, and pull the value of each key from the ConfigMap:
This example shows how a Pod can be started with just the database_host key from the ConfigMap. The key is also renamed before injection so the Pod will receive it as DATABASE_HOST_IP.
Using ConfigMaps With Volumes
ConfigMaps can be mounted as files inside Pods. Kubernetes creates a volume, injects the ConfigMap’s content as a set of files, and mounts the volume to your Pod.
This Pod manifest creates a volume called app-config. The configMap field will pre-populate the volume using the data in the specified ConfigMap.
The Pod mounts the volume to /etc/config-data. Your containers can read the files within the directory to access your config values. Each ConfigMap key will have its own file within the mount point.
Updating ConfigMap Values
As a ConfigMap is a standard Kubernetes API resource, you can update values at any time by modifying your manifest and re-applying it to your cluster. How the new values reach your Pods depends on the injection mechanism you’re using.
Mounted Volumes
ConfigMaps mounted into Pods via a volume will be updated by Kubernetes. Changes to ConfigMaps are checked periodically; when a difference is detected, the files in your volume will be updated, so your Pod will receive the new data. The delay depends on the sync interval configured for the Kubelet instances on your worker nodes.
Environment Variables
Changing a Pod’s environment variables isn’t possible so ConfigMap changes won’t reach existing Pods that are referencing keys via this mechanism. You must replace your Pods to use the new data.
Newly created Pods will always receive the current ConfigMap data, irrespective of whether you’re using volumes or environment variables. If you need to force a config update, change an annotation on your Pod so Kubernetes recreates it.
Immutable ConfigMaps
ConfigMaps have an optional immutable field that prevents them from being updated. When this field is set, you can’t update the ConfigMap’s data or remove the immutable status.
This can be useful when you’re certain that config values will never change. It improves safety by removing the possibility of accidental edits. Performance can also be improved as Kubernetes no longer needs to monitor the ConfigMap to propagate any value changes into your Pods.
Summary
ConfigMaps should be your go-to for supplying non-sensitive configuration keys to your Kubernetes Pods. They’re a first-class API resource which you can consume as environment variables or mounted files in volumes.
Passwords and other credentials belong in Secrets. These function very similarly to ConfigMaps and are referenced by Pods in the same way. Substitute configMapRef with secretRef to pull a key out of a named Secret instead of a ConfigMap.