Hard-coding configuration and credentials in container images is a security and operational anti-pattern. Kubernetes provides ConfigMaps and Secrets to externalise this data so images remain portable and reusable across environments.
ConfigMaps
A ConfigMap stores non-sensitive configuration data as key-value pairs.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
config.json: |
{
"timeout": 30,
"retries": 3
}
kubectl create configmap app-config --from-literal=APP_ENV=production
kubectl create configmap app-config --from-file=config.json
Consuming ConfigMaps as Environment Variables
spec:
containers:
- name: app
image: my-app:v1
envFrom:
- configMapRef:
name: app-config # all keys become env vars
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL # single key
Consuming ConfigMaps as Volume Mounts (Files)
spec:
containers:
- name: app
volumeMounts:
- name: config
mountPath: /etc/app
volumes:
- name: config
configMap:
name: app-config
The file /etc/app/config.json will contain the value of the config.json key. Files mounted from ConfigMaps are automatically updated when the ConfigMap changes (within ~60 seconds).
Secrets
A Secret stores sensitive data such as passwords, API keys, and TLS certificates. Secret values are base64-encoded — they are not encrypted by default. Anyone with access to the cluster API or etcd can decode them.
kubectl create secret generic db-secret --from-literal=DB_PASSWORD=mysecretpassword --from-literal=DB_USER=admin
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_PASSWORD: bXlzZWNyZXRwYXNzd29yZA== # base64 encoded
DB_USER: YWRtaW4=
Secret Types
| Type | Use |
|---|---|
| Opaque | Arbitrary user data (default) |
| kubernetes.io/service-account-token | Service account credentials |
| kubernetes.io/dockerconfigjson | Private container registry credentials |
| kubernetes.io/tls | TLS certificate and key |
| kubernetes.io/basic-auth | Basic authentication |
Using Secrets
spec:
containers:
- name: app
envFrom:
- secretRef:
name: db-secret
volumeMounts:
- name: creds
mountPath: /etc/credentials
readOnly: true
volumes:
- name: creds
secret:
secretName: db-secret
External Secret Management
For production, consider using external secret managers integrated via Kubernetes operators:
- AWS Secrets Manager / SSM Parameter Store via AWS Secrets and Configuration Provider (ASCP)
- HashiCorp Vault via the Vault Agent Injector or CSI Secrets Store
- External Secrets Operator — syncs secrets from AWS, GCP, Azure, Vault into Kubernetes Secrets
Next: Namespaces and RBAC — how to organise your cluster and control who can do what.