Lesson 09
ConfigMaps & Secrets
~4 min read
Kubernetes can supply configuration separately from the application image, allowing you to use the same image with different settings. Two resources hold this data:
- ConfigMaps hold non-sensitive configuration data, such as feature flags, URLs, and config files.
- Secrets hold sensitive data, such as passwords, API keys, and 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-secretsFor Secrets, describe shows the byte count of each value. Other commands can reveal the values if your permissions allow it.
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:
envFromsupplies all keys as environment variables. - Volume mounts: data appears 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