ConfigMaps
ConfigMaps decouple configuration from container images, making applications portable across environments. They store non-sensitive configuration data as key-value pairs, which can be injected into pods as environment variables, command-line arguments, or files mounted as volumes. This allows you to change configuration without rebuilding container images.
What Are ConfigMaps?
A ConfigMap is a Kubernetes object that stores configuration data in key-value pairs. Instead of hardcoding configuration in container images or command-line arguments, you store it in a ConfigMap and reference it in your pod specifications.
Why Use ConfigMaps?
ConfigMaps provide several benefits:
✅ Separate config from code - Change configuration without rebuilding images
✅ Environment-specific configs - Different ConfigMaps for dev, staging, prod
✅ Reusable configuration - Share ConfigMaps across multiple pods
✅ Version control - ConfigMaps can be versioned and managed like code
✅ Dynamic updates - Update ConfigMaps without recreating pods (with volume mounts)
✅ Portability - Same image works in different environments
ConfigMap vs Secrets
ConfigMaps are for non-sensitive data, Secrets are for sensitive data:
Use ConfigMaps for:
- Application configuration files
- Environment variables
- Command-line arguments
- Non-sensitive settings
Use Secrets for:
- Passwords, tokens, keys
- TLS certificates
- Any sensitive data
Creating ConfigMaps
There are several ways to create ConfigMaps:
1. From Literal Values
kubectl create configmap my-config \
--from-literal=key1=value1 \
--from-literal=key2=value2 \
--from-literal=database-url=mysql://localhost:3306/mydb
2. From Files
# From a single file
kubectl create configmap my-config --from-file=config.properties
# From multiple files
kubectl create configmap my-config \
--from-file=config.properties \
--from-file=logging.properties
# From a directory
kubectl create configmap my-config --from-file=./config/
3. From YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
key1: value1
key2: value2
config.properties: |
database.host=localhost
database.port=3306
logging.level=INFO
Using ConfigMaps in Pods
ConfigMaps can be used in three ways:
1. As Environment Variables
Inject all or specific keys as environment variables:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app:latest
envFrom:
- configMapRef:
name: my-config
# Or specify individual keys
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: my-config
key: database-url
2. As Command Arguments
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app:latest
command: ["/bin/sh"]
args:
- -c
- echo $(DATABASE_URL)
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: my-config
key: database-url
3. As Volume Mounts
Mount ConfigMap data as files in the container:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-config
ConfigMap Volume Mounts
When mounted as a volume, ConfigMap keys become filenames, and values become file contents:
Mounting Specific Keys
Mount only specific keys from a ConfigMap:
volumes:
- name: config-volume
configMap:
name: my-config
items:
- key: config.properties
path: app.properties
- key: key1
path: settings/key1
Setting File Permissions
volumes:
- name: config-volume
configMap:
name: my-config
defaultMode: 0644 # File permissions
ConfigMap Updates and Reloading
Environment Variables
When ConfigMaps are used as environment variables, pods must be restarted to pick up changes. Environment variables are injected at pod startup and don’t update automatically.
Volume Mounts
When ConfigMaps are mounted as volumes, they update automatically, but:
- Updates may take up to the
kubeletsync period (default: 1 minute) - Applications may need to watch for file changes or periodically reload
- Some applications detect file changes automatically (e.g., nginx reloads when config changes)
ConfigMap Lifecycle
Common Use Cases
1. Application Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8080
logging.level=INFO
feature.flag.enabled=true
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: config
mountPath: /etc/app
volumes:
- name: config
configMap:
name: app-config
2. Environment-Specific Configuration
# Development
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: dev
data:
environment: development
api.url: http://api-dev.example.com
log.level: DEBUG
# Production
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: prod
data:
environment: production
api.url: https://api.example.com
log.level: INFO
3. Nginx Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend:8080;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
volumes:
- name: config
configMap:
name: nginx-config
4. Multiple ConfigMaps
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app:latest
envFrom:
- configMapRef:
name: app-config
- configMapRef:
name: db-config
volumeMounts:
- name: app-config
mountPath: /etc/app
- name: log-config
mountPath: /etc/logging
volumes:
- name: app-config
configMap:
name: app-config
- name: log-config
configMap:
name: log-config
Best Practices
Use ConfigMaps for non-sensitive data - Use Secrets for sensitive information
Keep ConfigMaps small - ConfigMaps have a 1 MiB size limit
Use meaningful names - Clear, descriptive ConfigMap names
Version your ConfigMaps - Include version in name or use labels
metadata:
name: app-config-v1
labels:
version: "1"
Use namespaces - Organize ConfigMaps with namespaces
Document ConfigMap structure - Use annotations to document keys
metadata:
annotations:
description: "Application configuration for production environment"
- Handle missing ConfigMaps - Use
optional: trueif ConfigMap might not exist
envFrom:
- configMapRef:
name: optional-config
optional: true
Use volume mounts for files - Better for configuration files than env vars
Test ConfigMap updates - Verify applications handle updates correctly
Avoid hardcoded defaults in images - Use ConfigMaps for all configuration
Use immutable ConfigMaps - For configuration that never changes (Kubernetes 1.19+)
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
immutable: true
data:
# ...
Immutable ConfigMaps improve performance and prevent accidental updates.
Common Operations
Create ConfigMap
# From literal
kubectl create configmap my-config --from-literal=key=value
# From file
kubectl create configmap my-config --from-file=config.properties
# From YAML
kubectl create -f configmap.yaml
View ConfigMap
# List ConfigMaps
kubectl get configmaps
kubectl get cm
# View ConfigMap data
kubectl get configmap my-config -o yaml
# View specific key
kubectl get configmap my-config -o jsonpath='{.data.key}'
Update ConfigMap
# Edit ConfigMap
kubectl edit configmap my-config
# Update from file
kubectl create configmap my-config --from-file=config.properties --dry-run=client -o yaml | kubectl apply -f -
# Patch ConfigMap
kubectl patch configmap my-config -p '{"data":{"key":"new-value"}}'
Delete ConfigMap
kubectl delete configmap my-config
Troubleshooting
ConfigMap Not Found
# Verify ConfigMap exists
kubectl get configmap my-config
# Check namespace
kubectl get configmap my-config -n <namespace>
# Check pod references
kubectl describe pod my-pod | grep -A 10 "Environment\|Mounts"
Values Not Updating
# Check if using volume mount (auto-updates) or env var (requires restart)
kubectl get pod my-pod -o yaml | grep -A 5 "volumeMounts\|env"
# For env vars, restart the pod
kubectl rollout restart deployment my-deployment
# For volume mounts, check kubelet sync
kubectl describe pod my-pod | grep "Events"
ConfigMap Too Large
# Check ConfigMap size
kubectl get configmap my-config -o yaml | wc -c
# ConfigMaps have 1 MiB limit
# Consider splitting into multiple ConfigMaps
See Also
- Secrets - For sensitive configuration data
- Deployments - Using ConfigMaps with Deployments
- Volumes - Understanding volume mounts