Secrets & ConfigMaps – Complete Guide
Store configuration and sensitive data separately from container images.
1. ConfigMap vs Secret
| Aspect | ConfigMap | Secret |
|---|---|---|
| Data type | Non-sensitive config | Sensitive data |
| Encoding | Plain text | Base64 encoded |
| Use case | App settings, config files | Passwords, tokens, keys |
| Size limit | 1 MB | 1 MB |
2. ConfigMap
Create from Literal
bash
kubectl create configmap app-config \
--from-literal=APP_ENV=production \
--from-literal=LOG_LEVEL=infoCreate from File
bash
# Single file
kubectl create configmap nginx-config --from-file=nginx.conf
# Directory (all files)
kubectl create configmap configs --from-file=./config-dir/
# With custom key name
kubectl create configmap app-config --from-file=myconfig=config.propertiesCreate from YAML
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
config.json: |
{
"database": "mysql",
"port": 3306
}3. Secret
Types of Secrets
| Type | Use Case |
|---|---|
Opaque | Generic (default) |
kubernetes.io/tls | TLS certificates |
kubernetes.io/dockerconfigjson | Docker registry auth |
kubernetes.io/basic-auth | Basic authentication |
kubernetes.io/ssh-auth | SSH private keys |
Create Generic Secret
bash
# From literal (auto base64 encodes)
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=secret123
# From file
kubectl create secret generic tls-secret \
--from-file=tls.crt --from-file=tls.keyCreate TLS Secret
bash
kubectl create secret tls my-tls \
--cert=tls.crt \
--key=tls.keyCreate Docker Registry Secret
bash
kubectl create secret docker-registry regcred \
--docker-server=docker.io \
--docker-username=user \
--docker-password=pass \
--docker-email=email@example.comCreate from YAML (manual base64)
yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # echo -n 'admin' | base64
password: c2VjcmV0MTIz # echo -n 'secret123' | base64Using stringData (auto-encode)
yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
username: admin # Plain text, auto base64 encoded
password: secret1234. Use in Pods
As Environment Variables
All keys from ConfigMap:
yaml
spec:
containers:
- name: app
image: nginx
envFrom:
- configMapRef:
name: app-configAll keys from Secret:
yaml
spec:
containers:
- name: app
image: nginx
envFrom:
- secretRef:
name: db-secretSpecific keys:
yaml
spec:
containers:
- name: app
image: nginx
env:
- name: DATABASE_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENVAs Volume Mount
Mount entire ConfigMap:
yaml
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-configMount entire Secret:
yaml
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secretMount specific keys:
yaml
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: config.json
path: app-config.json # Mounted as /etc/config/app-config.jsonMount with permissions:
yaml
volumes:
- name: secret-volume
secret:
secretName: db-secret
defaultMode: 0400 # Read-only for ownerSubPath Mount (don't overwrite directory)
yaml
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf5. Commands Reference
ConfigMap
bash
# Create
kubectl create configmap <name> --from-literal=key=value
kubectl create configmap <name> --from-file=<file>
kubectl create configmap <name> --from-file=<dir>
# View
kubectl get configmap
kubectl describe configmap <name>
kubectl get configmap <name> -o yaml
# Edit
kubectl edit configmap <name>
# Delete
kubectl delete configmap <name>Secret
bash
# Create
kubectl create secret generic <name> --from-literal=key=value
kubectl create secret generic <name> --from-file=<file>
kubectl create secret tls <name> --cert=<cert> --key=<key>
kubectl create secret docker-registry <name> --docker-server=...
# View
kubectl get secret
kubectl describe secret <name>
kubectl get secret <name> -o yaml
# Decode secret value
kubectl get secret <name> -o jsonpath='{.data.password}' | base64 -d
# Edit
kubectl edit secret <name>6. Patching
Patch ConfigMap
bash
# Add/update key
kubectl patch configmap app-config -p '{"data":{"NEW_KEY":"new_value"}}'
# Using JSON merge patch
kubectl patch configmap app-config --type merge -p '{"data":{"APP_ENV":"staging"}}'Patch Secret
bash
# Add/update key (must be base64)
kubectl patch secret db-secret -p '{"data":{"newkey":"bmV3dmFsdWU="}}'
# Using stringData (plain text)
kubectl patch secret db-secret --type merge -p '{"stringData":{"newkey":"newvalue"}}'7. Immutable ConfigMaps and Secrets
Prevent accidental changes (K8s 1.21+):
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
immutable: true
data:
APP_ENV: productionNote: Immutable objects cannot be changed; must delete and recreate.
8. Hot Reload
| Mount Type | Update Behavior |
|---|---|
| Environment variables | NO auto-reload (Pod restart needed) |
| Volume mount | YES auto-reload (~1 min delay) |
| SubPath mount | NO auto-reload |
9. Complete Examples
Example 1: App with ConfigMap and Secret
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: debug
---
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
DB_USER: admin
DB_PASS: secret123
---
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: nginx
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-secretExample 2: Mount Config File
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
}
}
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
volumes:
- name: config
configMap:
name: nginx-config10. CKA Exam Tips
- kubectl create is fastest for creating ConfigMaps/Secrets
- stringData avoids manual base64 encoding
- envFrom loads all keys at once
- Volume mounts auto-update, env vars don't
- Decode secrets:
kubectl get secret <name> -o jsonpath='{.data.key}' | base64 -d - Check mounted data:
kubectl exec <pod> -- cat /path/to/mounted/file