Learn how to manage configuration data and sensitive information in Kubernetes using ConfigMaps and Secrets. Keep your applications configurable and secure.
Table of Contents
1. Introduction
Applications often need configuration data and sensitive information:
- Configuration: Environment-specific settings, feature flags, endpoints
- Sensitive Data: Passwords, API keys, certificates, tokens
Kubernetes provides two objects for this:
- ConfigMaps: Store non-sensitive configuration data
- Secrets: Store sensitive information
Both can be mounted as volumes or exposed as environment variables in Pods.
2. ConfigMaps
A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or configuration files in a volume.
2.1 Use Cases
- Application configuration files
- Environment variables
- Command-line arguments
- Configuration data in volumes
2.2 Important Notes
- ConfigMaps are NOT encrypted - don't store secrets
- ConfigMaps are namespace-scoped
- ConfigMaps can be updated without recreating Pods
- Data size limit: 1MB per ConfigMap
3. Creating ConfigMaps
There are several ways to create ConfigMaps:
3.1 From Literal Values
kubectl create configmap app-config \
--from-literal=key1=value1 \
--from-literal=key2=value2 \
--from-literal=database_url=postgresql://localhost:5432/mydb
3.2 From Files
# From a 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=app.yaml
# From a directory
kubectl create configmap app-config --from-file=./config/
3.3 From YAML Definition
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
# Simple key-value
database_url: "postgresql://localhost:5432/mydb"
log_level: "info"
# Multi-line value
app.properties: |
server.port=8080
server.host=0.0.0.0
app.name=myapp
app.version=1.0.0
kubectl apply -f configmap.yaml
3.4 Viewing ConfigMaps
# List ConfigMaps
kubectl get configmaps
# Describe ConfigMap
kubectl describe configmap app-config
# View ConfigMap data
kubectl get configmap app-config -o yaml
4. Using ConfigMaps
ConfigMaps can be used in Pods in three ways:
4.1 As Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database_url
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log_level
4.2 All Keys as Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config
4.3 As Volume Mounts
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
This mounts all ConfigMap keys as files in /etc/config. Each key becomes a filename.
4.4 Specific Keys as Files
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: app.properties
path: application.properties
4.5 In Deployments
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config
5. Secrets
A Secret is an object that contains a small amount of sensitive data such as passwords, tokens, or keys. Kubernetes stores Secrets in base64 encoding (not encryption).
5.1 Use Cases
- Database passwords
- API keys and tokens
- TLS certificates
- Docker registry credentials
- SSH keys
5.2 Important Notes
- Secrets are base64 encoded, NOT encrypted
- Anyone with API access can read Secrets
- Use RBAC to restrict Secret access
- Consider external secret management (Vault, AWS Secrets Manager)
- Secrets are namespace-scoped
- Data size limit: 1MB per Secret
5.3 Secret Types
- Opaque: User-defined data (default)
- kubernetes.io/dockerconfigjson: Docker registry credentials
- kubernetes.io/tls: TLS certificate and key
- kubernetes.io/service-account-token: Service account token
6. Creating Secrets
6.1 From Literal Values
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=secretpassword123
6.2 From Files
# Create secret from file
echo -n 'secretpassword123' > password.txt
kubectl create secret generic db-secret --from-file=password.txt
# Create TLS secret
kubectl create secret tls tls-secret \
--cert=tls.crt \
--key=tls.key
6.3 From YAML Definition
Values must be base64 encoded:
# Encode values
echo -n 'admin' | base64
echo -n 'secretpassword123' | base64
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # base64 encoded 'admin'
password: c2VjcmV0cGFzc3dvcmQxMjM= # base64 encoded 'secretpassword123'
6.4 Docker Registry Secret
kubectl create secret docker-registry regcred \
--docker-server=docker.io \
--docker-username=myuser \
--docker-password=mypassword \
--docker-email=myuser@example.com
6.5 Viewing Secrets
# List secrets (values are hidden)
kubectl get secrets
# Describe secret
kubectl describe secret db-secret
# View secret data (base64 encoded)
kubectl get secret db-secret -o yaml
# Decode secret value
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
7. Using Secrets
Secrets can be used similarly to ConfigMaps:
7.1 As Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
7.2 All Keys as Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- secretRef:
name: db-secret
7.3 As Volume Mounts
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secret
7.4 TLS Secret in Pod
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: tls-volume
mountPath: /etc/tls
volumes:
- name: tls-volume
secret:
secretName: tls-secret
7.5 Image Pull Secrets
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
imagePullSecrets:
- name: regcred
containers:
- name: app
image: private-registry.io/myapp:1.0
8. Best Practices
8.1 Use ConfigMaps for Non-Sensitive Data
Never store passwords, keys, or tokens in ConfigMaps. Use Secrets instead.
8.2 Enable Encryption at Rest
Configure encryption at rest for etcd to encrypt Secrets stored in the cluster.
8.3 Use RBAC
Restrict access to Secrets using Role-Based Access Control. Only grant access to users and service accounts that need it.
8.4 Consider External Secret Management
For production, consider using external secret management systems like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault.
8.5 Rotate Secrets Regularly
Implement a secret rotation strategy. Update Secrets and restart Pods to pick up new values.
8.6 Use Immutable ConfigMaps/Secrets
For better performance and security, mark ConfigMaps and Secrets as immutable:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
immutable: true
data:
key: value
8.7 Don't Commit Secrets to Git
Never commit Secrets or base64-encoded values to version control. Use CI/CD pipelines to inject secrets at deployment time.
Summary: ConfigMaps store non-sensitive configuration data, while Secrets store sensitive information. Both can be used as environment variables or volume mounts. Remember that Secrets are base64 encoded, not encrypted, so use RBAC and consider external secret management for production.
0 Comments