iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0

前幾天的 Deployment YAML 裡,環境變數是直接寫死在 env 裡面的。

這樣有個問題:設定和部署設定混在一起。開發環境、測試環境、生產環境的設定不同,但 YAML 卻是同一份,每次換環境都要手動改 YAML,很容易出錯。


ConfigMap 是什麼

ConfigMap 是 K8s 用來儲存非敏感設定資料的資源,把設定從 Pod 的定義裡分離出來,讓同一份 Deployment YAML 可以在不同環境下搭配不同的 ConfigMap 使用。

ConfigMap 的資料是明文儲存的,密碼、API Key 這類機密資訊不應該放這裡,那是 Secret 的職責。


ConfigMap YAML 拆解

apiVersion: v1
kind: ConfigMap
metadata:
  name: todo-api-config
data:
  APP_ENV: "development"
  LOG_LEVEL: "info"

結構很簡單:data 裡面放 key-value,key 是設定名稱,value 是設定值。

DATABASE_URL 含有資料庫密碼,不適合放在 ConfigMap。Day 11 會用 Secret 來處理,這裡先不放。


把 ConfigMap 注入 Pod 的兩種方式

方式一:作為環境變數注入

spec:
  containers:
    - name: api
      image: yourname/todo-app-api:v1.0.0
      envFrom:
        - configMapRef:
            name: todo-api-config   # 把整個 ConfigMap 的 key-value 全部變成環境變數

或是只取特定的 key:

env:
  - name: APP_ENV
    valueFrom:
      configMapKeyRef:
        name: todo-api-config
        key: APP_ENV

方式二:掛載成檔案

spec:
  containers:
    - name: api
      volumeMounts:
        - name: config-volume
          mountPath: /app/config    # ConfigMap 的內容會出現在這個路徑下
  volumes:
    - name: config-volume
      configMap:
        name: todo-api-config

ConfigMap 的每個 key 會變成一個獨立的檔案,value 是檔案內容。適合應用程式用設定檔而不是環境變數的情境,例如 nginx 的 nginx.conf。

大多數情況用環境變數注入就夠了,掛載成檔案適合需要完整設定檔的服務。


實際操作

今天目標:建立 ConfigMap 儲存 todo-api 的環境變數,更新 Deployment 改用 ConfigMap 注入設定,並驗證更新 ConfigMap 後重啟 Pod 能正確套用新值。

Step1: 建立 ConfigMap

  1. 在 /Todo-App/k8s 目錄下,建立 todo-api-configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
  name: todo-api-config
data:
  APP_ENV: "development"
  LOG_LEVEL: "info"
kubectl apply -f todo-api-configmap.yaml
  1. 確認建立成功:
kubectl get configmaps

https://ithelp.ithome.com.tw/upload/images/20260921/20183863gUATg6bUgL.png
3. 看 ConfigMap 的內容:

kubectl describe configmap todo-api-config

https://ithelp.ithome.com.tw/upload/images/20260921/20183863OhJTLNVGt4.png

Step2: 更新 Deployment 使用 ConfigMap

todo-api-deployment.yaml 加入 envFrom:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: todo-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: todo-api
  template:
    metadata:
      labels:
        app: todo-api
        tier: backend
    spec:
      containers:
        - name: api
          image: yourname/todo-app-api:v1.0.0
          ports:
            - containerPort: 8000
          envFrom:
            - configMapRef:
                name: todo-api-config   # 注入 APP_ENV、LOG_LEVEL
          env:
            - name: DATABASE_URL
              value: "mysql+pymysql://user:password@mysql-service:3306/tododb"  # 暫時維持寫死,Day 11 再抽出來
kubectl apply -f todo-api-deployment.yaml

Step3: 確認環境變數有正確注入

進到 Pod 裡面確認:

# 取得其中一個 Pod 名稱
kubectl get pods

# 進到 Pod 裡面
kubectl exec -it <pod-name> -- env | grep -E "APP_ENV|LOG_LEVEL"

你會看到:

https://ithelp.ithome.com.tw/upload/images/20260921/20183863dyN8GNLrk8.png

Step4: 更新 ConfigMap 的值

假設要把 LOG_LEVEL 改成 debug:

kubectl edit configmap todo-api-config

這會開啟編輯器,直接修改存檔。

注意:更新 ConfigMap 不會自動重啟 Pod。環境變數是在 Pod 啟動時注入的,ConfigMap 更新後需要手動重啟 Pod 才會生效:

kubectl rollout restart deployment/todo-api

你會看到 log_level被更改為 debug :
https://ithelp.ithome.com.tw/upload/images/20260921/20183863jbesyMi4BD.png


延伸筆記:ConfigMap 的限制和注意事項

大小限制:ConfigMap 的資料總量不能超過 1MB,適合放設定值,不適合放大型文件或二進位資料。

不會自動重啟 Pod:如上面提到的,ConfigMap 更新後 Pod 不會自動感知,需要手動重啟。如果你的服務需要即時感知設定變更,可以考慮用掛載成檔案的方式——掛載成檔案的 ConfigMap 更新後,檔案內容會在幾秒到一分鐘內自動同步,不需要重啟 Pod(但應用程式要自己實作重新讀取設定的邏輯)。

不適合放敏感資料:ConfigMap 是明文儲存,任何有 kubectl get configmap 權限的人都能看到內容。密碼、Token、憑證要用 Secret(Day 11)。


小結

今天學了 ConfigMap,把設定從 Deployment YAML 裡抽出來:

  • ConfigMap 儲存非敏感的設定資料,讓設定和部署設定分離
  • 環境變數注入:envFrom 注入整個 ConfigMap,valueFrom 取特定 key
  • 掛載成檔案:適合需要完整設定檔的服務(例如 nginx.conf)
  • 更新 ConfigMap 後需要手動重啟 Pod 才會生效
  • DATABASE_URL 含有密碼,不放在 ConfigMap,明天用 Secret 處理

明天會學 Secret,處理密碼和 API Key 這類不能明文儲存的敏感資料 !


上一篇
Day 09|Ingress
下一篇
Day 11|Secret
系列文
從零學 K8s|30 天核心概念 × 實作,新手也能真正掌握 Kubernetes 共 15 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言