Lesson 09
ConfigMaps & Secrets
~4 min read
In Kubernetes, configuration should be kept separate from your application code. This makes your containers portable and your config easy to change without rebuilding images. Kubernetes provides two resources for this:
- ConfigMaps — for non-sensitive configuration data (feature flags, URLs, config files)
- Secrets — for sensitive data (passwords, API keys, certificates)
Our cluster already has a web-app deployment running. Let's configure it properly.
Creating a ConfigMap
A ConfigMap holds key-value pairs that your application can consume as environment variables or files. Create one:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: "production"
APP_LOG_LEVEL: "info"
config.json: |
{
"features": {
"darkMode": true,
"notifications": true
},
"apiUrl": "https://api.example.com"
}The sandbox has this manifest stored as app-config.yaml. Apply it and verify:
kubectl apply -f app-config.yaml
kubectl get configmaps
kubectl describe configmap app-configThe describe output shows all key-value pairs stored in the ConfigMap.
Creating a Secret
Secrets work similarly but are intended for sensitive data. In a real cluster, Secret values stored in the data field must be base64-encoded. Using stringData lets you provide plaintext values that Kubernetes encodes for you. Secrets can also be encrypted at rest.
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
DB_PASSWORD: "s3cur3-p4ssw0rd"
API_KEY: "sk-abc123def456"This manifest is stored as app-secrets.yaml. Apply and verify:
kubectl apply -f app-secrets.yaml
kubectl get secrets
kubectl describe secret app-secretsNotice that describe shows byte counts rather than the actual values — Kubernetes avoids exposing secret data in command output.
Using ConfigMaps and Secrets in Pods
Now let's update our web-app deployment to use these configuration resources. There are two main approaches:
- Environment variables via
envFrom— injects all keys as env vars - Volume mounts — mounts data as files in the container filesystem
Here's a deployment that uses both:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 1
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: node:20-alpine
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-configThis updated deployment is stored as web-app-deployment.yaml. Apply it:
kubectl apply -f web-app-deployment.yamlWait a moment for the new pod to start, then verify the environment variables are set:
kubectl get pods
kubectl exec <pod-name> -- printenvYou should see APP_ENV, APP_LOG_LEVEL, DB_PASSWORD, and API_KEY in the output.
You can also read the mounted config file:
kubectl exec <pod-name> -- cat /etc/config/config.jsonKey takeaways
- ConfigMaps store non-sensitive configuration; Secrets store sensitive data
- Both can be consumed as environment variables or mounted files
envFrominjects all keys from a ConfigMap or Secret as env vars- Volume mounts make config data available as files in the container
- Separating config from code makes deployments more flexible and secure