Keep configuration out of your images. Inject settings with ConfigMaps and sensitive values with Secrets — as environment variables or mounted files — so one image runs in every environment.
Why: baking settings into an image means rebuilding it for every environment and leaking secrets into your registry. Kubernetes keeps configuration separate: a ConfigMap holds non-sensitive settings, a Secret holds sensitive ones. The same image then runs in dev, staging, and prod — only the injected config changes.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
FEATURE_FLAGS: "search,checkout"
config.yaml: | # a whole file, as a value
cache:
ttl: 300Why: the most common way to consume config is as environment variables. envFrom pulls every key in the ConfigMap into the container's environment at once; use env + valueFrom when you want just one specific key under a chosen name.
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config # every key becomes an env var
env:
- name: LOG_LEVEL # or pull a single key explicitly
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVELWhy: apps that read a config file (not env vars) want the ConfigMap as files on disk. Mount it as a volume and each key becomes a file in the directory. Change the ConfigMap and the mounted files update automatically — no rebuild.
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: config
mountPath: /etc/app # config.yaml appears here as a file
volumes:
- name: config
configMap:
name: app-configA Secret is like a ConfigMap but for passwords, tokens, and keys. Create one from literals and Kubernetes stores the values base64-encoded. Note: base64 is encoding, NOT encryption — anyone with read access can decode it. Lock Secrets down with RBAC (a later lesson) and enable encryption-at-rest on the cluster.
Create a Secret from literal values
kubectl create secret generic db-creds \
--from-literal=username=app \
--from-literal=password='s3cr3t'Inspect it (values show base64-encoded, not plaintext)
kubectl get secret db-creds -o yamlWhy: a Secret is injected exactly like a ConfigMap — as env vars or mounted files — but using secretKeyRef / a secret volume. Prefer mounting Secrets as files over env vars when you can: env vars are easier to leak into logs and crash dumps.
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password