Sổ tay kỹ thuật

Kubernetes ConfigMap và Secret

how-to#kubernetes#kubectl· cập nhật 2026-11-06

Dùng khi cần tạo ConfigMap/Secret, đưa vào Pod dưới dạng env hoặc file, và làm app nhận cấu hình mới khi giá trị thay đổi.

Sửa trang này
Mục lục

Tóm tắt: Tạo bằng kubectl create configmap|secret ... --dry-run=client -o yaml | kubectl apply -f - (idempotent). Đưa vào Pod qua env (env/envFrom, chỉ đọc lúc container start) hoặc volume (file, kubelet tự cập nhật sau một khoảng trễ, trừ subPath). Đổi giá trị env thì phải kubectl rollout restart. Secret chỉ là base64, cần RBAC và encryption at rest.

Luồng hoạt động

flowchart LR F["file / literal / .env"] --> C["ConfigMap / Secret"] C -->|"env, envFrom"| E["Biến môi trường (đọc 1 lần khi start)"] C -->|"volume"| V["File trong Pod (tự cập nhật, trễ)"] C -->|"volume + subPath"| S["File (KHÔNG cập nhật)"] E --> R["rollout restart để nhận giá trị mới"]

Cấu hình

Tạo bằng kubectl

# ConfigMap
kubectl create configmap api-config -n app \
  --from-literal=LOG_LEVEL=info --from-literal=APP_ENV=prod \
  --dry-run=client -o yaml | kubectl apply -f -
 
kubectl create configmap api-env -n app --from-env-file=api.env \
  --dry-run=client -o yaml | kubectl apply -f -
 
kubectl create configmap nginx-conf -n app --from-file=default.conf=./nginx/default.conf \
  --dry-run=client -o yaml | kubectl apply -f -
 
# Secret generic: đọc giá trị từ biến môi trường/file, không gõ thẳng trên dòng lệnh
kubectl create secret generic api-db -n app \
  --from-literal=username=api \
  --from-literal=password="$DB_PASSWORD" \
  --dry-run=client -o yaml | kubectl apply -f -
 
# Secret TLS (key tls.crt, tls.key) và pull secret cho registry
kubectl create secret tls app-tls -n app --cert=fullchain.pem --key=privkey.pem
kubectl create secret docker-registry regcred -n app \
  --docker-server=registry.example.com --docker-username=ci --docker-password="$REG_TOKEN"

--from-env-file không dùng chung được với --from-literal/--from-file trong cùng một lệnh (error: from-env-file cannot be combined...): tách thành hai ConfigMap hoặc gộp hết vào file .env.

Manifest

api-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: api-config
  namespace: app
data:
  LOG_LEVEL: info
  app.toml: |
    [server]
    port = 8000
---
apiVersion: v1
kind: Secret
metadata:
  name: api-db
  namespace: app
type: Opaque
stringData:                 # viết plain text, API server tự encode base64 vào data
  username: api
  password: "***"           # đừng commit giá trị thật, dùng SOPS / Sealed Secrets / External Secrets

Đưa vào Pod: env và volume

deploy-api.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: app
spec:
  selector:
    matchLabels: { app: api }
  template:
    metadata:
      labels: { app: api }
    spec:
      containers:
        - name: api
          image: registry.example.com/api:1.4.2
          envFrom:
            - configMapRef: { name: api-config }       # mọi key hợp lệ thành biến env
          env:
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef: { name: api-db, key: password }
          volumeMounts:
            - name: config
              mountPath: /etc/api                      # /etc/api/app.toml, tự cập nhật
              readOnly: true
            - name: tls
              mountPath: /etc/tls
              readOnly: true
      volumes:
        - name: config
          configMap:
            name: api-config
            items:
              - key: app.toml
                path: app.toml
        - name: tls
          secret:
            secretName: app-tls
            defaultMode: 0400
env / envFrom volume
Đổi giá trị Không cập nhật, cần restart Pod Kubelet cập nhật file sau vài chục giây đến khoảng 1-2 phút
Lộ secret Dễ lộ qua env, crash dump, log debug Ít lộ hơn, phân quyền file được
App phải làm gì Không gì Tự theo dõi file và reload (inotify, SIGHUP), hoặc restart

Làm app nhận cấu hình mới

# Cách đơn giản: restart rolling sau khi apply ConfigMap/Secret
kubectl apply -f api-config.yaml && kubectl rollout restart deploy/api -n app
kubectl rollout status deploy/api -n app
 
# Kiểm tra giá trị Pod đang thấy
kubectl exec -n app deploy/api -- env | grep LOG_LEVEL
kubectl exec -n app deploy/api -- cat /etc/api/app.toml

Tự động hoá:

  • Kustomize configMapGenerator/secretGenerator: tên có hậu tố hash nội dung, đổi nội dung là đổi tên, Deployment tự rollout.
  • Helm: annotation checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} trong Pod template.
  • Controller như Stakater Reloader theo dõi ConfigMap/Secret và tự restart workload có annotation.

Cấu hình không bao giờ đổi lúc chạy: đặt immutable: true để giảm tải watch cho API server (muốn đổi phải xoá rồi tạo lại).

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Pod CreateContainerConfigError ConfigMap/Secret hoặc key được tham chiếu không tồn tại (sai namespace) kubectl describe pod xem tên thiếu; hoặc optional: true nếu thật sự tuỳ chọn
Pod kẹt ContainerCreating, event FailedMount ... not found Volume tham chiếu ConfigMap/Secret chưa có Tạo trước, kiểm tra namespace
Đã apply ConfigMap mới mà app vẫn giá trị cũ Dùng env, hoặc app không reload file kubectl rollout restart
File mount bằng subPath không bao giờ cập nhật Hạn chế của subPath Mount cả thư mục, hoặc restart khi đổi
Key bị bỏ qua khi envFrom Tên key không phải tên biến env hợp lệ (vd app.toml) Dùng env.valueFrom đặt tên riêng, hoặc mount file
kubectl apply báo field is immutable ConfigMap/Secret có immutable: true Xoá và tạo lại, rồi restart Pod
Lỗi tạo object quá lớn ConfigMap/Secret tối đa 1 MiB Đưa file lớn vào image hoặc volume khác
Secret có giá trị sai ký tự xuống dòng echo thêm \n khi tự base64 Dùng stringData hoặc echo -n / printf

Tham khảo