ConfigMaps
A ConfigMap stores non-secret configuration as key/value or whole files. Mount as files, project as env vars, or read via the API. Decouples config from images.
Create, consume as env / file, immutable
EXAMPLE
# 1) Create from key/value pairs (imperative)
kubectl create configmap app-config \
--from-literal=LOG_LEVEL=info \
--from-literal=FEATURE_FLAGS=a,b,c \
--from-literal=API_URL=https://api.example.com
# 2) Create from a file
kubectl create configmap nginx-conf --from-file=nginx.conf
kubectl create configmap nginx-conf --from-file=nginx.conf=./conf/nginx.conf
# Multiple files
kubectl create configmap site-files --from-file=./public
# 3) YAML — declarative
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: info
FEATURE_FLAGS: 'a,b,c'
API_URL: https://api.example.com
application.yml: |
spring:
datasource:
url: jdbc:postgresql://db.svc:5432/app
jpa:
hibernate:
ddl-auto: validate
logging:
level:
root: INFO
# 4) Consume as ENV vars in a Pod
apiVersion: apps/v1
kind: Deployment
metadata: { name: web }
spec:
selector: { matchLabels: { app: web } }
template:
metadata: { labels: { app: web } }
spec:
containers:
- name: web
image: myapp:1.0
envFrom:
- configMapRef: { name: app-config } # all keys → env vars
env:
- name: SPECIFIC_VAR
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
# 5) Consume as a FILE (volume mount)
spec:
containers:
- name: app
image: nginx:1.27
volumeMounts:
- name: conf
mountPath: /etc/nginx/conf.d
volumes:
- name: conf
configMap:
name: nginx-conf
items:
- key: nginx.conf
path: default.conf
defaultMode: 0644
# 6) subPath — mount a single file without obscuring the directory
volumeMounts:
- name: conf
mountPath: /etc/app/application.yml
subPath: application.yml
# (Note: subPath mounts DON'T auto-reload on ConfigMap changes — limitation.)
# 7) Inspect
kubectl get configmap app-config -o yaml
kubectl describe configmap app-config
# 8) Update
kubectl edit configmap app-config # interactive
kubectl apply -f app-config.yaml # declarative (preferred)
# Pods consuming as env vars DON'T see updates until restart.
# Pods consuming via volume mount get updates within ~1 minute (kubelet polls).
# For env-var consumers, use a rollout to pick up changes:
kubectl rollout restart deployment/web
# 9) Immutable ConfigMaps — flag a CM as read-only (perf + safety)
apiVersion: v1
kind: ConfigMap
metadata: { name: app-config }
immutable: true
data: { … }
# Reduces API server / kubelet load; prevents accidental edits.
# Update by creating a NEW ConfigMap (with a version suffix) and changing the Deployment.
# 10) ConfigMap vs Secret
# ConfigMap — non-sensitive config (URLs, feature flags, settings)
# Secret — credentials, tokens, keys — base64-encoded; can be encrypted at rest in etcd
# Don't put passwords in ConfigMaps.
# 11) Cross-namespace — ConfigMaps are namespaced
# Same name in different namespaces = different CMs. Use Kustomize / Helm / external-secrets.
# 12) Common patterns
# a) Layered config — base ConfigMap + env-specific overlay (Kustomize)
# b) Version-pinned configs — `app-config-v3` referenced by Deployment v3
# Updating config triggers a Deployment update (which triggers a rollout)
# c) Hot-reloadable apps — watch the mounted file with fs.watch / inotify
# 13) Things to avoid
# - Massive ConfigMaps (etcd has a 1MB key limit; ConfigMap limit is also ~1MB)
# - Storing binary blobs (images, certs) — use a different mechanism
# - Sensitive data — use Secret + SealedSecret / external-secrets
# - Forgetting to roll out after editing — env-var consumers need a restart
Why it matters
ConfigMaps mounted as files auto-update; ConfigMaps consumed as env vars don’t. For env-var configs, pair with a versioned name (app-config-v3) so changing config triggers a Deployment rollout.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
kubectl create configmap app-config --from-literal=LOG_LEVEL=info # Mount as env or volume.Try it Yourself »
Discussion
Loading…