Bài 5: ConfigMap & Secret — Tách cấu hình khỏi code
Nguyên tắc 12-Factor App
"Store config in the environment"
Không hardcode config vào image. Thay đổi DB password → rebuild image? Không đời nào!
K8s cung cấp 2 resource để làm việc này:
- ConfigMap: Dữ liệu không nhạy cảm (DB host, port, feature flags...)
- Secret: Dữ liệu nhạy cảm (password, API key, TLS certs...)
ConfigMap
Tạo ConfigMap
Cách 1: Từ file YAML
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_HOST: "postgres-svc"
DB_PORT: "5432"
LOG_LEVEL: "debug"
app.properties: | # key có thể chứa cả tên file
max.connections=100
timeout=30s
Cách 2: Từ command line
kubectl create configmap app-config \
--from-literal=DB_HOST=postgres-svc \
--from-literal=DB_PORT=5432 \
--from-file=app.properties
Dùng ConfigMap trong Pod
Cách A: Environment Variables
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config # import TOÀN BỘ key thành env vars
# Hoặc chỉ lấy vài key cụ thể:
env:
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DB_HOST
Cách B: Mount thành file
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
→ Mỗi key trong ConfigMap sẽ thành 1 file trong /etc/config/.
Ví dụ: /etc/config/DB_HOST chứa postgres-svc
Cập nhật ConfigMap
kubectl edit configmap app-config
- Mount dạng file: K8s tự update file trong Pod (có thể mất ~1 phút)
- Env vars: Không tự update → phải restart Pod
Secret
Secret giống ConfigMap nhưng được thiết kế cho dữ liệu nhạy cảm:
- Lưu dạng base64 (không phải encrypt — chỉ obfuscate!)
- Có thể cấu hình encryption at rest (quan trọng cho production)
- Giới hạn 1MB
Tạo Secret
Cách 1: Từ YAML (phải encode base64 trước)
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_USER: cG9zdGdyZXM= # echo -n "postgres" | base64
DB_PASS: c3VwZXJzZWNyZXQ= # echo -n "supersecret" | base64
Cách 2: Dùng stringData (K8s tự encode)
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData: # tiện hơn, không cần tự encode
DB_USER: postgres
DB_PASS: supersecret
Cách 3: Từ CLI
kubectl create secret generic db-secret \
--from-literal=DB_USER=postgres \
--from-literal=DB_PASS=supersecret
Dùng Secret trong Pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASS # tên key trong Secret
# hoặc mount thành file:
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secret
So sánh ConfigMap vs Secret
| ConfigMap | Secret | |
|---|---|---|
| Dữ liệu | Plain text | Base64 (có thể mã hóa at rest) |
| Dung lượng | ~1MB | ~1MB |
| Dùng làm env var | ✅ | ✅ |
| Mount làm file | ✅ | ✅ |
| Dùng làm imagePullSecrets | ❌ | ✅ |
| Dùng làm TLS | ❌ | ✅ (type: kubernetes.io/tls) |
| Auto-update khi thay đổi | Chỉ khi mount | ❌ |
Best Practices
- Không commit Secret YAML vào git — dùng Sealed Secrets, External Secrets, hoặc Vault
- Luôn set
readOnly: truekhi mount secret - Dùng
stringDatacho YAML để không phải encode thủ công - Namespace isolation: ConfigMap/Secret chỉ dùng được trong cùng namespace
Bài tập
- Tạo ConfigMap chứa cấu hình app (DB host, port, env)
- Tạo Secret chứa DB username/password
- Tạo Deployment dùng cả ConfigMap (env) và Secret (mounted file)
kubectl execvào Pod, kiểm tra env vars và file trong/etc/secrets- Sửa ConfigMap, kiểm tra xem Pod có tự update không (mount vs env)
⏭️ Bài tiếp: https://viblo.asia/p/bai-5-configmap-secret-tach-cau-hinh-khoi-code-oW4oeDGkLml — Lưu trữ dữ liệu bền vững
All rights reserved