Kubernetes ConfigMaps and Secrets: Configuring Applications Safely
Introduction
The same container image should run in development, staging, and production, with only configuration changing. Kubernetes provides ConfigMaps for ordinary settings and Secrets for sensitive values. This lesson shows how to create and consume both, and is honest about the limits of Secret protection.
Prerequisites
- Deployments from the previous lesson
Step-by-Step Guide
Step 1: Create a ConfigMap
A ConfigMap holds key-value pairs of non-sensitive configuration, with a size limit of 1 MiB. You can write it as YAML or create it from the command line.
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
FEATURE_X: "enabled"
# or from the command line:
# kubectl create configmap app-config --from-literal=LOG_LEVEL=infoStep 2: Use a ConfigMap in a Pod
Inject values as environment variables, either one key at a time or all keys at once, or mount them as files in a volume. Environment variables are read when the container starts, so changing a ConfigMap does not update running Pods; restart them, for example with a rollout.
containers:
- name: app
image: my-app:1.0
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
envFrom:
- configMapRef:
name: app-configStep 3: Create and use a Secret
Create a Secret from literal values or files without writing the values into YAML you might commit. Consume it as an environment variable or, preferably, as a mounted read-only file, which is less likely to leak through process listings and logs.
kubectl create secret generic db-credentials \
--from-literal=username=app \
--from-literal=password='use-a-real-password'
# in the Pod spec:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: creds
mountPath: /etc/creds
readOnly: true
volumes:
- name: creds
secret:
secretName: db-credentialsStep 4: Understand what Secrets do and do not protect
A Secret's values are only base64-encoded, which is encoding, not encryption. By default they are stored unencrypted in the cluster's data store, and anyone who can read the Secret through the API, or who can create a Pod in the namespace, can see its value. Enable encryption at rest, restrict access with RBAC, and never commit Secret manifests containing real values to Git.
Step 5: Move to stronger secret management as you grow
For production, many teams keep secrets in an external manager and sync them into the cluster with a tool built for that purpose, or use sealed or encrypted manifests that are safe to store in Git. Mark ConfigMaps and Secrets immutable when they should never change, which also reduces load on the cluster.
FAQs
- Is a Kubernetes Secret safe because it is base64-encoded?
- No. Base64 is trivially reversible. Safety comes from encryption at rest, tight access control, and not exposing the values elsewhere.
- Why didn't my Pod see the updated ConfigMap?
- Environment variables are fixed at container start. Restart the Pods, for example with kubectl rollout restart deployment/<name>, or mount the ConfigMap as a volume, where updates eventually propagate.
Summary
Use ConfigMaps for settings and Secrets for sensitive values, consuming them as environment variables or mounted files. Remember that Secrets are only encoded by default, so add encryption at rest, RBAC, and an external secret manager for serious use.
Comments
Log in or create a free account to join the discussion.