Kubernetes ConfigMap stores non-confidential configuration data as key-value pairs, enabling you to decouple configuration from container images. This comprehensive guide covers everything you need to know about ConfigMaps in 2026, from creation to consumption and best practices.
Quick Reference: ConfigMap Commands
| Command | Description |
|---|---|
kubectl create configmap name --from-literal=key=value | Create from literal |
kubectl create configmap name --from-file=file.txt | Create from file |
kubectl create configmap name --from-env-file=.env | Create from env file |
kubectl get configmaps | List ConfigMaps |
kubectl describe configmap name | View ConfigMap details |
kubectl delete configmap name | Delete ConfigMap |
What Is a Kubernetes ConfigMap?
A ConfigMap is a Kubernetes API object that stores non-confidential configuration data in key-value pairs. It allows you to:
- Decouple configuration from container images
- Manage environment-specific settings without rebuilding images
- Share configuration across multiple pods
- Update configuration without redeploying containers
ConfigMap vs Secret
| Aspect | ConfigMap | Secret |
|---|---|---|
| Data type | Non-confidential | Confidential |
| Encoding | Plain text | Base64 encoded |
| Encryption | Not encrypted | Can be encrypted at rest |
| Use case | Config files, env vars | Passwords, API keys, TLS certs |
Creating ConfigMaps
From Literal Values
# Single key-value
kubectl create configmap app-config --from-literal=DATABASE_HOST=postgres
# Multiple key-values
kubectl create configmap app-config \
--from-literal=DATABASE_HOST=postgres \
--from-literal=DATABASE_PORT=5432 \
--from-literal=LOG_LEVEL=info
From Files
# From single file
kubectl create configmap app-config --from-file=config.properties
# From multiple files
kubectl create configmap app-config \
--from-file=config.properties \
--from-file=settings.json
# From directory (all files in directory)
kubectl create configmap app-config --from-file=./config/
# With custom key name
kubectl create configmap app-config --from-file=myconfig=config.properties
From Environment File
# .env file format: KEY=value
kubectl create configmap app-config --from-env-file=.env
From YAML Manifest
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
# Simple key-value pairs
DATABASE_HOST: "postgres.database.svc.cluster.local"
DATABASE_PORT: "5432"
LOG_LEVEL: "info"
FEATURE_FLAG_NEW_UI: "true"
# Multi-line configuration file
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
# JSON configuration
config.json: |
{
"database": {
"host": "postgres",
"port": 5432
},
"cache": {
"enabled": true,
"ttl": 3600
}
}
kubectl apply -f configmap.yaml
Consuming ConfigMaps
As Environment Variables
All Keys as Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- configMapRef:
name: app-config
Specific Keys as Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DATABASE_HOST
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: DATABASE_PORT
With Optional ConfigMap
env:
- name: FEATURE_FLAG
valueFrom:
configMapKeyRef:
name: feature-flags
key: NEW_FEATURE
optional: true # Pod starts even if ConfigMap doesn't exist
As Volume Mount
Mount All Keys as Files
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
Each key becomes a file in /etc/config/.
Mount Specific Keys
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: nginx:latest
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf # Mount single file, not directory
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: nginx.conf
path: nginx.conf
With Permissions
volumes:
- name: config-volume
configMap:
name: app-config
defaultMode: 0644 # File permissions
As Command Arguments
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: myapp:latest
command: ["/bin/app"]
args: ["--config=$(CONFIG_FILE)"]
env:
- name: CONFIG_FILE
valueFrom:
configMapKeyRef:
name: app-config
key: config_path
Updating ConfigMaps
Edit Existing ConfigMap
kubectl edit configmap app-config
Replace ConfigMap
kubectl create configmap app-config --from-file=config.properties \
--dry-run=client -o yaml | kubectl apply -f -
Patch ConfigMap
kubectl patch configmap app-config \
--type merge \
-p '{"data":{"LOG_LEVEL":"debug"}}'
Update Behavior
| Consumption Method | Auto-Update | Delay |
|---|---|---|
| Volume mount | Yes | ~1 minute (kubelet sync) |
| Environment variable | No | Requires pod restart |
| Command arguments | No | Requires pod restart |
Important: For environment variables and command arguments, pods must be restarted to get new values.
Immutable ConfigMaps
Kubernetes 1.21+ supports immutable ConfigMaps for better performance and safety.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
immutable: true # Cannot be modified after creation
data:
DATABASE_HOST: "postgres"
DATABASE_PORT: "5432"
Benefits of Immutable ConfigMaps
- Performance - Reduces API server load (no watches)
- Safety - Prevents accidental modifications
- Clarity - Forces versioned configuration
Updating Immutable ConfigMaps
Create a new ConfigMap with a new name:
# Version in name
kubectl create configmap app-config-v2 --from-file=config.properties
# Update deployment to use new ConfigMap
kubectl set env deployment/app --from=configmap/app-config-v2
ConfigMap Best Practices
1. Use Descriptive Names
# Good
kubectl create configmap api-server-config
kubectl create configmap frontend-nginx-config
# Bad
kubectl create configmap config
kubectl create configmap cm1
2. Namespace Your ConfigMaps
metadata:
name: app-config
namespace: production
3. Use Labels
metadata:
name: app-config
labels:
app: api-server
environment: production
version: v1.2.0
4. Keep ConfigMaps Small
ConfigMaps have a 1 MiB size limit. Split large configurations:
# Split into multiple ConfigMaps
kubectl create configmap app-settings --from-file=settings.json
kubectl create configmap app-features --from-file=features.json
5. Version Control ConfigMaps
Store ConfigMap manifests in Git:
k8s/
├── base/
│ └── configmap.yaml
├── overlays/
│ ├── dev/
│ │ └── configmap-patch.yaml
│ ├── staging/
│ │ └── configmap-patch.yaml
│ └── prod/
│ └── configmap-patch.yaml
6. Use ConfigMap Generators (Kustomize)
# kustomization.yaml
configMapGenerator:
- name: app-config
files:
- config.properties
literals:
- LOG_LEVEL=info
7. Provide Default Values in App
import os
DATABASE_HOST = os.getenv('DATABASE_HOST', 'localhost')
DATABASE_PORT = int(os.getenv('DATABASE_PORT', '5432'))
8. Don’t Store Secrets in ConfigMaps
# Bad - never do this
data:
DATABASE_PASSWORD: "mypassword"
# Good - use Kubernetes Secrets instead
Complete Example: Application with ConfigMap
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
namespace: production
labels:
app: api
data:
# Environment settings
LOG_LEVEL: "info"
DATABASE_HOST: "postgres.database.svc.cluster.local"
DATABASE_PORT: "5432"
DATABASE_NAME: "myapp"
CACHE_ENABLED: "true"
CACHE_TTL: "3600"
# Configuration file
app.yaml: |
server:
port: 8080
timeout: 30s
features:
newUI: true
analytics: true
Deployment Using ConfigMap
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: api:v1.0.0
ports:
- containerPort: 8080
# Environment variables from ConfigMap
envFrom:
- configMapRef:
name: api-config
# Mount config file
volumeMounts:
- name: config-volume
mountPath: /app/config
readOnly: true
volumes:
- name: config-volume
configMap:
name: api-config
items:
- key: app.yaml
path: app.yaml
Environment-Specific ConfigMaps
Using Kustomize
base/configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
overlays/production/configmap-patch.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "warn"
DATABASE_HOST: "prod-postgres.database.svc.cluster.local"
overlays/production/kustomization.yaml:
resources:
- ../../base
patchesStrategicMerge:
- configmap-patch.yaml
Troubleshooting
ConfigMap Not Found
# Check ConfigMap exists
kubectl get configmap app-config -n production
# Check pod namespace matches
kubectl get pod app-xyz -o jsonpath='{.metadata.namespace}'
Environment Variables Not Updating
Restart pods after ConfigMap changes:
kubectl rollout restart deployment/api
Volume Mount Issues
# Check mount in pod
kubectl exec app-xyz -- ls -la /etc/config
# Check ConfigMap content
kubectl get configmap app-config -o yaml
ConfigMap Too Large
Split into multiple ConfigMaps or use external configuration storage.
Conclusion
Kubernetes ConfigMaps are essential for managing application configuration in 2026. Key takeaways:
- Use ConfigMaps for non-confidential configuration data
- Consume via environment variables, volume mounts, or command arguments
- Volume mounts auto-update; env vars require pod restart
- Use immutable ConfigMaps for stability and performance
- Version control and namespace your ConfigMaps
- Never store secrets in ConfigMaps
Master ConfigMaps to build flexible, maintainable Kubernetes applications.
Related Resources
- Kubernetes Secrets 2026
- Kubectl Create Namespace 2026
- Kubernetes Security Best Practices 2026
- Kubernetes Consulting Services
Need help with Kubernetes configuration? Book a free 30-minute consultation with our experts.