KubernetesXX · ConfigurationConfiguration
ConfigMaps — key-value configuration decoupled from container images
What you'll learn
- Describe what ConfigMaps are for and what they are not for (Secrets, large data)
- Author ConfigMaps from literals, files, and directories
- Distinguish env-var consumption from file consumption
- Reason about the 1 MiB size limit and other ConfigMap constraints
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
A ConfigMap is the standard Kubernetes object for
non-sensitive configuration: feature flags, application
settings, external service URLs, log levels. ConfigMaps
decouple configuration from container images — a single
image can run with different configs across environments
— and they are designed to be consumed by Pods in two ways,
as environment variables and as mounted files. This lesson
covers the format, the limits, and the patterns that work.
What a ConfigMap is
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
namespace: prod
data:
log_level: info
feature_flags: |
{
"checkout_v2": true,
"new_search": false
}
database_url: postgres://db.prod/data
A ConfigMap has metadata (name, namespace, labels) and a
free-form data map of string keys to string values. The
values are arbitrary UTF-8; the size limit is 1 MiB total
across all keys.
flowchart LR
A["ConfigMap<br/>web-config"] --> B[Pod spec]
B --> C[env vars]
B --> D[mounted files]
C --> E[Process env]
D --> F[Container filesystem]
Authoring a ConfigMap
From literal values:
kubectl create configmap web-config -n prod \
--from-literal=log_level=info \
--from-literal=database_url=postgres://db.prod/data
From files:
kubectl create configmap web-config -n prod \
--from-file=nginx.conf=./nginx.conf \
--from-file=app.properties=./app.properties
From a directory:
kubectl create configmap web-config -n prod \
--from-file=./config/
The keys are the file names; the values are the file contents. The same ConfigMap can mix literals and files.
From a manifest:
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
data:
log_level: info
app.conf: |
[server]
port = 8080
workers = 4
The 1 MiB limit
The total size of a ConfigMap (the keys, the values, and the metadata) is bounded at 1 MiB. Larger data goes in a PVC, an external store, or a different mechanism.
Consuming a ConfigMap as env vars
spec:
containers:
- name: web
image: web:v1
envFrom:
- configMapRef:
name: web-config
envFrom injects every key in the ConfigMap as an
environment variable. The container sees LOG_LEVEL=info,
DATABASE_URL=postgres://db.prod/data, etc.
For selective injection:
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: web-config
key: log_level
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: web-config
key: database_url
valueFrom with configMapKeyRef reads a specific key.
Consuming a ConfigMap as files
spec:
containers:
- name: web
image: web:v1
volumeMounts:
- name: config
mountPath: /etc/web
volumes:
- name: config
configMap:
name: web-config
The ConfigMap’s keys become files in the mount path. With the example above, the container sees:
/etc/web/log_level # contents: info
/etc/web/feature_flags # contents: {...}
/etc/web/database_url # contents: postgres://...
For named keys:
volumeMounts:
- name: config
mountPath: /etc/web/app.conf
subPath: app.conf
volumes:
- name: config
configMap:
name: web-config
subPath mounts a single key as a file at the specified
path. Useful when the application expects a specific
filename.
Real-time updates
flowchart TB
A[ConfigMap updated] --> B{Updated object<br/>in etcd}
B --> C{Kubelet watches<br/>ConfigMap?}
C -->|yes| D{Pod consumes as<br/>env or files?}
D -->|env vars| E["Env vars NOT updated<br/>Pod must restart"]
D -->|files| F["Files updated<br/>after kubelet sync"]
F --> G["Application must<br/>reload or SIGHUP"]
This is the most common ConfigMap confusion in production:
- Env vars from ConfigMap are immutable in the running Pod. They are read once when the container starts. A ConfigMap update does not change the running container’s env vars; the Pod must be restarted.
- Files from ConfigMap are eventually consistent. The
kubelet syncs the mount within ~60 seconds (configurable
via
syncPeriod). The application must detect the change and reload; many do not.
This asymmetry is the source of “I changed the config but nothing happened” tickets.
immutability
ConfigMaps and Secrets can be marked immutable:
immutable: true
Once set, the data cannot be changed. Any update is rejected. This is correct for configuration that should not change at runtime (e.g., the configuration baked into a release). It is wrong for configuration that is expected to roll (e.g., a feature flag toggled weekly).
Quiz
Knowledge check · 4 questions
Q1. What is the maximum size of a ConfigMap?
Q2. ConfigMaps are encrypted by default in etcd.
Q3. Your team tries to store a 10 MiB JSON schema in a ConfigMap. The API server rejects the apply. Diagnose and propose alternatives.
ConfigMap web-schema with 10 MiB JSON. The apply fails with request entity too large.
Q4. What are the two ways a Pod can consume a ConfigMap, and how does update behavior differ between them?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- ConfigMaps are for non-sensitive configuration. Secrets, certificates, and credentials belong in Secrets (with encryption at rest) or external secret managers.
- The 1 MiB limit is real. Verify the total size before
applying;
kubectl get configmap -o yaml | wc -cis a quick check. - Document the consumption pattern. A ConfigMap mounted as files is not the same as one consumed as env vars. The application must be designed for the consumption it receives.
- Test the update path. A change to the ConfigMap should produce the expected effect on the running Pod. Verify with a test cluster.
- Use immutability for release-baked configuration. A ConfigMap that should never change at runtime is immutable; the cluster cannot drift.
ConfigMaps are the right tool for non-sensitive configuration. The discipline is in the consumption pattern — env vars vs files, restart-on-update vs reload-on-update — and in choosing the right object for the data (ConfigMap vs Secret vs PVC vs object store).