Kubernetes ConfigMaps and Secrets
Complete guide to Kubernetes ConfigMaps and Secrets for configuration management including environment variables, volume mounts, and best practices.
# Kubernetes ConfigMaps and Secrets
Introduction
ConfigMaps and Secrets are Kubernetes objects for storing configuration data separately from container images. ConfigMaps store non-sensitive configuration data, while Secrets store sensitive data like passwords, tokens, and keys. Both can be consumed by pods as environment variables or volume mounts.
Learning Objectives
By the end of this tutorial, you will be able to:
- Create and manage ConfigMaps
- Create and manage Secrets
- Inject configuration as environment variables
- Mount configuration as files
- Update configuration without redeploying
- Follow security best practices for Secrets
Technical Background
ConfigMap vs Secret
| Aspect | ConfigMap | Secret | |--------|-----------|--------| | Data type | Non-sensitive | Sensitive | | Encoding | Plain text | Base64 | | Use case | Configuration, feature flags | Passwords, tokens, keys | | Size limit | 1 MiB | 1 MiB |
Consumption Methods
| Method | Description | Use Case | |--------|-------------|----------| | Environment variables | Inject as env vars | Simple configuration | | Volume mounts | Mount as files | Complex config files | | Image pull secrets | For private registries | Container image authentication |
Prerequisites
- Running Kubernetes cluster
- kubectl configured
Hardware and Software Requirements
| Component | Requirement | |-----------|-------------| | Kubernetes Cluster | v1.25+ | | kubectl | v1.25+ |
Step-by-Step Implementation
Phase 1: Create ConfigMaps
#### From Literal Values
kubectl create configmap app-config \
--from-literal=DB_HOST=db-service \
--from-literal=DB_PORT=5432 \
--from-literal=LOG_LEVEL=info#### From File
kubectl create configmap app-config --from-file=config.yaml#### From Directory
kubectl create configmap app-config --from-file=config-directory/#### YAML Definition
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
DB_HOST: "db-service"
DB_PORT: "5432"
LOG_LEVEL: "info"
FEATURE_FLAGS: |
new_checkout: "true"
dark_mode: "false"
binaryData:
config.bin: <base64-encoded-binary>Phase 2: Create Secrets
#### From Literal Values
kubectl create secret generic db-secret \
--from-literal=DB_PASSWORD=supersecret \
--from-literal=API_KEY=sk-1234567890#### From File
kubectl create secret generic tls-cert \
--from-file=tls.crt=./cert.crt \
--from-file=tls.key=./cert.key#### YAML Definition
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: production
type: Opaque
stringData:
DB_PASSWORD: supersecret
API_KEY: sk-1234567890
data:
# Base64 encoded values
ENCODED_VALUE: c2VjcmV0LXZhbHVlPhase 3: Use ConfigMap as Environment Variables
#### All ConfigMap Keys as Env Vars
# configmap-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-env-pod
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- configMapRef:
name: app-config#### Specific ConfigMap Key as Env Var
# configmap-env-specific.yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-env-pod
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DB_HOST
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: DB_PORTPhase 4: Use Secret as Environment Variables
# secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
- name: API_KEY
valueFrom:
secretKeyRef:
name: db-secret
key: API_KEYPhase 5: Mount ConfigMap as Volume
# configmap-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-volume-pod
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: config-volume
mountPath: /etc/app/config
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: DB_HOST
path: db-host
- key: DB_PORT
path: db-portPhase 6: Mount Secret as Volume
# secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secretPhase 7: Image Pull Secrets
# image-pull-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: regcred
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-docker-config>
---
apiVersion: v1
kind: Pod
metadata:
name: private-image-pod
spec:
containers:
- name: app
image: myregistry.com/myapp:latest
imagePullSecrets:
- name: regcredExpected Output
- ConfigMaps storing configuration data
- Secrets storing sensitive data
- Pods consuming configuration as env vars and volumes
- Image pull secrets for private registries
Verification Procedures
| Check | Command | Expected Result | |-------|---------|-----------------| | ConfigMap | `kubectl get configmap app-config` | ConfigMap listed | | Secret | `kubectl get secret db-secret` | Secret listed | | Env vars | `kubectl exec <pod> -- env` | Variables present | | Volume mount | `kubectl exec <pod> -- ls /etc/app/config` | Files present |
Troubleshooting Scenarios
| Issue | Diagnosis | Resolution | |-------|-----------|------------| | ConfigMap not found | Wrong namespace | Check namespace; use correct name | | Secret not decoded | Base64 encoding issue | Verify encoding; use stringData | | Volume mount empty | Wrong key path | Check items mapping | | Env var not set | Wrong key reference | Verify configMapKeyRef/secretKeyRef |
Best Practices
- **Use ConfigMaps for non-sensitive data:** Don't store passwords in ConfigMaps
- **Use Secrets for sensitive data:** Encrypt at rest with etcd encryption
- **Mount as read-only:** Mount Secrets as readOnly
- **Use specific keys:** Don't mount entire ConfigMap when only needed keys
- **Version configuration:** Store ConfigMaps and Secrets in version control
- **Update strategy:** Changes to ConfigMaps/Secrets don't auto-update running pods
Security Considerations
- **Etcd encryption:** Enable encryption at rest for Secrets
- **RBAC:** Restrict access to Secrets
- **Audit logging:** Log Secret access
- **Rotation:** Rotate secrets regularly
- **External secret managers:** Consider HashiCorp Vault, AWS Secrets Manager
Conclusion
ConfigMaps and Secrets provide a clean separation of configuration from container images. By using them properly, you can manage configuration and sensitive data securely while keeping your container images portable across environments.
References
- Kubernetes ConfigMaps: https://kubernetes.io/docs/concepts/configuration/configmap/
- Kubernetes Secrets: https://kubernetes.io/docs/concepts/configuration/secret/
- Kubernetes Configuration: https://kubernetes.io/docs/concepts/configuration/
- Etcd Encryption: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/