Kubernetes ConfigMaps: Managing Application Configuration
Kubernetes ConfigMaps: Managing Application Configuration
What is a 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 your application code, making your containerized applications more portable and easier to manage.
Think of ConfigMaps as a way to store environment variables, configuration files, or any other configuration data that your applications need to run.
Why Use ConfigMaps?
🔄 Separation of Concerns
Keep configuration separate from application code, following the 12-Factor App methodology.
🚀 Environment Flexibility
Use the same container image across different environments (dev, staging, production) with different configurations.
🔧 Runtime Updates
Update configuration without rebuilding container images.
📦 Centralized Management
Manage all configuration data in one place within your Kubernetes cluster.
Creating ConfigMaps
Method 1: From Literal Values
kubectl create configmap app-config \
--from-literal=database_host=mysql.example.com \
--from-literal=database_port=3306 \
--from-literal=app_env=production
Method 2: From Files
# Create from a single file
kubectl create configmap nginx-config --from-file=nginx.conf
# Create from multiple files
kubectl create configmap app-configs --from-file=config/
Method 3: YAML Manifest
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
# Simple key-value pairs
database_host: "mysql.example.com"
database_port: "3306"
app_env: "production"
# Multi-line configuration file
app.properties: |
server.port=8080
server.servlet.context-path=/api
logging.level.root=INFO
spring.datasource.url=jdbc:mysql://mysql:3306/mydb
# JSON configuration
config.json: |
{
"api": {
"version": "v1",
"timeout": 30
},
"features": {
"enableCache": true,
"maxConnections": 100
}
}
Using ConfigMaps in Pods
As Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: app
image: myapp:latest
env:
# Single environment variable
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database_host
# All keys as environment variables
envFrom:
- configMapRef:
name: app-config
As Volume Mounts
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
readOnly: true
volumes:
- name: config-volume
configMap:
name: app-config
Mounting Specific Keys
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: app.properties
path: application.properties
- key: config.json
path: app-config.json
Real-World Example: Laravel Application
Let's configure a Laravel application using ConfigMaps:
1. Create ConfigMap for Laravel
apiVersion: v1
kind: ConfigMap
metadata:
name: laravel-config
data:
APP_NAME: "PCJ Application"
APP_ENV: "production"
APP_DEBUG: "false"
APP_URL: "https://pcj.example.com"
DB_CONNECTION: "mysql"
DB_HOST: "mysql-service"
DB_PORT: "3306"
DB_DATABASE: "pcj_db"
CACHE_DRIVER: "redis"
REDIS_HOST: "redis-service"
REDIS_PORT: "6379"
# Laravel configuration file
database.php: |
<?php
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
],
],
];
2. Deploy Laravel Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: laravel-app
spec:
replicas: 3
selector:
matchLabels:
app: laravel
template:
metadata:
labels:
app: laravel
spec:
containers:
- name: laravel
image: pcj/laravel:latest
ports:
- containerPort: 8000
# Environment variables from ConfigMap
envFrom:
- configMapRef:
name: laravel-config
# Mount config files
volumeMounts:
- name: config-volume
mountPath: /var/www/html/config/database.php
subPath: database.php
readOnly: true
volumes:
- name: config-volume
configMap:
name: laravel-config
Best Practices
✅ Do's
- Keep it Non-Sensitive: Only store non-confidential data (use Secrets for sensitive data)
- Use Descriptive Names: Name your ConfigMaps clearly (
app-config
,nginx-config
) - Version Your Configs: Include version info in ConfigMap names for rollbacks
- Validate Data: Ensure configuration values are valid before creating ConfigMaps
- Use Namespaces: Organize ConfigMaps by environment or application
❌ Don'ts
- Don't Store Secrets: Never put passwords, API keys, or certificates in ConfigMaps
- Don't Make Them Too Large: Keep ConfigMaps under 1MB (Kubernetes limit)
- Don't Hardcode Values: Use templating tools like Helm for dynamic values
- Don't Ignore Updates: Remember that mounted ConfigMaps update automatically, but environment variables don't
Managing ConfigMaps
View ConfigMaps
# List all ConfigMaps
kubectl get configmaps
# Describe a specific ConfigMap
kubectl describe configmap app-config
# View ConfigMap data
kubectl get configmap app-config -o yaml
Update ConfigMaps
# Edit directly
kubectl edit configmap app-config
# Replace from file
kubectl replace -f configmap.yaml
# Update specific key
kubectl patch configmap app-config -p '{"data":{"database_host":"new-mysql.example.com"}}'
Delete ConfigMaps
kubectl delete configmap app-config
ConfigMaps vs Secrets vs Environment Variables
Aspect | ConfigMaps | Secrets | Environment Variables |
---|---|---|---|
Data Type | Non-sensitive config | Sensitive data | Simple key-value pairs |
Storage | Plain text | Base64 encoded | In container spec |
Size Limit | 1MB | 1MB | No specific limit |
Updates | Dynamic (volumes) | Dynamic (volumes) | Requires pod restart |
Use Cases | App settings, config files | Passwords, certificates | Simple configuration |
Conclusion
Kubernetes ConfigMaps are essential for managing application configuration in a cloud-native way. They provide:
- Flexibility to run the same application in different environments
- Maintainability by separating config from code
- Scalability for managing configuration across multiple services
Start using ConfigMaps in your Kubernetes deployments to make your applications more portable and easier to manage!
Next Steps:
- Learn about Kubernetes Secrets for sensitive data
- Explore Helm Charts for templating ConfigMaps
- Check out GitOps workflows for configuration management