Chuyển đến nội dung chính

第6課: ConfigMaps 與 Secrets

ConfigMap 和 Secret 的建立方式(imperative/declarative)。透過環境變數(envFrom/valueFrom) 和 Volume 掛載注入 Pod。自動更新行為與限制。

ConfigMaps 與 Secrets — 環境變數注入和 Volume 掛載

1. ConfigMap

# Imperative — 快速建立
kubectl create configmap app-config \
  --from-literal=DB_HOST=mysql \
  --from-literal=DB_PORT=3306

kubectl create configmap app-config --from-file=config.properties

# Declarative — YAML 檔案
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_HOST: mysql
  DB_PORT: "3306"         # 值必須是字串
  app.properties: |       # 多行資料
    server.port=8080
    logging.level=INFO

2. Secrets

# Imperative
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=s3cr3t

# Declarative(值必須 base64 編碼)
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=       # echo -n "admin" | base64
  password: czNjcjN0       # echo -n "s3cr3t" | base64

# 使用 stringData(純文字,Kubernetes 自動編碼)
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
stringData:
  username: admin
  password: s3cr3t
Secret 類型用途
Opaque(預設)任意 key-value 資料
kubernetes.io/dockerconfigjsonDocker registry 認證
kubernetes.io/tlsTLS 憑證(cert + key)
kubernetes.io/basic-authBasic 認證(username + password)

考試重點: Secret 是 base64 編碼而非加密。base64 任何人都可解碼。生產環境應啟用 Encryption at Rest 或使用 External Secrets Operator。CKAD 常考 stringData(純文字)和 data(base64)的差異。

3. 作為環境變數注入

# envFrom — 將 ConfigMap/Secret 的所有 key 注入為環境變數
env:
  envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: db-secret

# valueFrom — 逐一注入特定 key
env:
- name: DATABASE_HOST
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: DB_HOST
- name: DATABASE_PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: password

4. 作為 Volume 注入

spec:
  containers:
  - name: app
    image: myapp
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config     # 每個 key 成為一個檔案
      readOnly: true
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: config-volume
    configMap:
      name: app-config
  - name: secret-volume
    secret:
      secretName: db-secret

# Volume 掛載後的檔案結構:
# /etc/config/DB_HOST        → 檔案內容: "mysql"
# /etc/config/DB_PORT        → 檔案內容: "3306"
# /etc/secrets/username      → 檔案內容: "admin"
# /etc/secrets/password      → 檔案內容: "s3cr3t"

5. 自動更新行為

注入方式自動更新備註
環境變數(envFrom/valueFrom)不會需重啟 Pod
Volume 掛載會(有延遲)依賴 kubelet 同步間隔(預設約 60 秒)

6. 速查表

任務指令 / YAML
快速建立 ConfigMapkubectl create cm name --from-literal=k=v
快速建立 Secretkubectl create secret generic name --from-literal=k=v
所有 key 注入為環境變數envFrom: configMapRef/secretRef
掛載為檔案volumes: configMap/secret + volumeMounts
base64 編碼echo -n "text" | base64
base64 解碼echo "encoded" | base64 -d

7. 練習題

Q1: 將 ConfigMap "app-config" 的所有 key 注入為 Pod 環境變數的正確 YAML 語法是什麼?

  • A) env: - configMapRef: name: app-config
  • B) envFrom: - configMapRef: name: app-config ✓
  • C) envFrom: - configMap: name: app-config
  • D) env: - valueFrom: configMapRef: name: app-config

解析: envFrom 可一次注入 ConfigMap 或 Secret 的所有 key 為環境變數。正確的 key 是 configMapRef(ConfigMap)或 secretRef(Secret)。valueFrom 用於逐一注入特定 key。

Q2: Secret YAML 的 data 欄位中,值應以什麼格式填寫?

  • A) 純文字
  • B) base64 編碼 ✓
  • C) SHA256 雜湊
  • D) AES 加密

解析: Secret 的 data 欄位值必須為 base64 編碼。若要使用純文字,可改用 stringData 欄位。base64 是編碼而非加密——其目的是支援二進位資料的儲存,而非安全保護。

Q3: 您透過 Volume 掛載方式將 ConfigMap 注入 Pod。更新 ConfigMap 的值後,不重啟 Pod 時變更是否會生效?

  • A) 不會,一律需要重啟 Pod
  • B) 會,Volume 掛載的情況下 kubelet 會在同步間隔後自動更新 ✓
  • C) 會,即時生效
  • D) ConfigMap 一旦建立就無法修改(immutable)

解析: Volume 掛載的情況下,kubelet 會定期檢測 ConfigMap 變更並更新檔案(預設約 60 秒延遲)。但透過環境變數(envFrom/valueFrom)注入時不會自動更新,需要重啟 Pod。