ConfigMaps in Kubernetes
Basic Kubernetes API objects, ConfigMaps, store non-confidential key-value pairs. Application code and container images are intended to be separated from database URLs, hostnames, and feature identifiers. Because of this split, containerized apps are assured to be reusable and portable in development, staging, and production without recreating images for minor changes.
Motivation and Core Concepts
Hard-coding configuration into a container image is seen as an anti-pattern in contemporary cloud-native systems. You would need different images for each environment if configuration was built into the image, which would result in a large operational overhead. By enabling you to create a single, hardened container image that is consistent across all deployments, ConfigMaps address this issue. Kubernetes injects the required environment-specific settings into the Pod during execution.
This strategy is consistent with the “config” aspect of the 12-aspect App methodology, which promotes the rigorous separation of configuration from code. By simply changing the ConfigMap, a developer can utilize localhost for a database host while local debugging while the same code in production refers to a Kubernetes Service.
You can also read What is the DNS in Kubernetes? & It’s Core Architecture
Technical Constraints and Structure
The “brain” of Kubernetes is the cluster’s etcd datastore, where ConfigMaps are kept as API objects. They are subject to a tight 1 MiB size limit per item because they live in etcd. Larger configuration sets must be stored via a dedicated file service or divided into several ConfigMaps.
Two main fields are used to store data in a ConfigMap:
- data: Specifically made for UTF-8 strings.
- binaryData: Designed for base64-encoded strings that represent binary data.
ConfigMaps lack secrecy and encryption. Because they store data in plaintext, they are unsuitable for passwords, API keys, and certificates. Certain use situations require Kubernetes Secrets.
Creating ConfigMaps
ConfigMaps can be generated declaratively using YAML manifests or imperatively using the command line.
Imperative Creation
You can use the kubectl create configmap command to generate objects from literals, files, or entire directories.
- From Literal Values:
kubectl create configmap app-settings --from-literal=ui_color=blue --from-literal=log_level=infoThis creates a ConfigMap where each--from-literalargument becomes a separate entry in thedatasection. - From a File:
kubectl create configmap game-config --from-file=game.propertiesThe filename becomes the key, and the file contents become the value.
Declarative Creation (YAML Manifest)
This is the preferred method for production as it can be version-controlled.
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-config
namespace: default
data:
database_host: "prod-db.example.com"
debug_mode: "false"
app.properties: |
max.connections=100
cache.size=512mb
binaryData:
header_icon: iVBORw0KGgoAAAANSUhEUgAA...
In this example, app.properties uses the pipe character (|) to store a multi-line configuration file as a single value.
You can also read What is Kubernetes Cloud Controller Manager?
Consuming ConfigMap Data in Pods
Once created, Pods can consume ConfigMap data in four main ways:
Environment Variables
You can inject specific keys or all keys from a ConfigMap as environment variables.
- Using
envFrom(Inject all keys):
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: demo-config
The envFrom field automatically creates environment variables for every key in the referenced ConfigMap.
- Using
valueFrom(Inject specific keys):
env:
- name: DB_URL
valueFrom:
configMapKeyRef:
name: demo-config
key: database_host
This allows you to map a specific ConfigMap key to a custom environment variable name.
Command-Line Arguments
You can use the $(VAR_NAME) substitution syntax to pass ConfigMap data as startup arguments.
spec:
containers:
- name: test-container
image: busybox
command: ["/bin/echo"]
args: ["The database host is $(DB_URL)"]
env:
- name: DB_URL
valueFrom:
configMapKeyRef:
name: demo-config
key: database_host
Volume Mounts (Filesystem)
This is the most flexible method for larger files or applications that expect configuration at specific file paths.
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: test-container
image: busybox
command: ["ls", "/etc/config"]
volumeMounts:
- name: config-vol
mountPath: /etc/config
readOnly: true
volumes:
- name: config-vol
configMap:
name: demo-config
In this setup, each key in the ConfigMap appears as a file inside /etc/config. For example, a file named /etc/config/database_host would be created containing the value “prod-db.example.com”.
You can also read What is a Kubernetes Controller Manager?
Updates and Lifecycle Management
The way environment variables and volumes handle updates is a crucial difference:
- Mounted Volumes: The kubelet automatically updates the projected files in the Pod’s volume during its periodic sync (usually within a minute) when a ConfigMap is modified. However, in order to “hot-reload” the updated settings without restarting, the program itself needs to be built to detect file changes.
- Environment Variables: These don’t change. A restart is needed to apply ConfigMap changes to a running container.
- SubPath Warning: Containers using ConfigMap as
subPathvolume mounts will not receive automatic updates.
Immutable ConfigMaps
Starting from Kubernetes v1.19, you can set the immutable field to true.
apiVersion: v1
kind: ConfigMap
metadata:
name: immutable-config
immutable: true
data:
stable_setting: "true"
Benefits of Immutability:
- Security: Security prevents intentional or accidental modifications that can disrupt.
- Performance: The
kube-apiserveris less stressed because the system stops “watching” for changes to that item.
After making data immutable, you must remove and recreate the ConfigMap to update it.
Best Practices and Restrictions
- Namespace Scoping: ConfigMaps are located within a certain namespace. Pods can only reference ConfigMaps in their namespace.
- Pre-creation: Before mentioning a ConfigMap in a Pod spec, you must create it to prevent the Pod from starting. You might perhaps say the reference is optional.
- Static Pods: Kubelet cannot use static pod ConfigMaps.
- Naming Conventions: Avoid team disagreements by using clear, consistent nomenclature (e.g.,
<app>-<env>-config). - Fallbacks: Design applications with default settings to avoid failures without a ConfigMap key.
- GitOps: To keep an audit trail and make rollbacks easier, save ConfigMap manifests under version control (like Git).
You can also read How to Get Started Kubernetes? Explained Briefly
