0

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

  1. Không commit Secret YAML vào git — dùng Sealed Secrets, External Secrets, hoặc Vault
  2. Luôn set readOnly: true khi mount secret
  3. Dùng stringData cho YAML để không phải encode thủ công
  4. Namespace isolation: ConfigMap/Secret chỉ dùng được trong cùng namespace

Bài tập

  1. Tạo ConfigMap chứa cấu hình app (DB host, port, env)
  2. Tạo Secret chứa DB username/password
  3. Tạo Deployment dùng cả ConfigMap (env) và Secret (mounted file)
  4. kubectl exec vào Pod, kiểm tra env vars và file trong /etc/secrets
  5. 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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí