到目前為止,我們已經完成了 Pod → Service → Ingress 的完整流量路徑。不過,回到實際的應用程式部署,還有另一個重要問題:
應用程式除了接收流量,還需要各種「設定」
想像以下幾種情境:
這些問題其實都指向同一件事:設定與應用程式耦合在一起了
Kubernetes 提供了 ConfigMap 來解決這個問題——將設定從 Container Image 中抽離,並透過環境變數或檔案的方式提供給 Pod 使用。
今天會學:
1. 為什麼設定不該寫死?
2. ConfigMap 是什麼? — 如何建立與使用 ConfigMap
3. 三種使用方式 — 匯入全部環境變數、引用單一 Key、掛載為檔案
4. ConfigMap 更新後,Pod 會自動取得新設定嗎?
以下操作皆在 master 節點 執行。
| 問題 | 寫死在 Image | 使用 ConfigMap |
|---|---|---|
| 換環境(dev → prod) | ❌ 修改程式或設定 → 重新 build → 重新 push | ✅ 更換對應環境的 ConfigMap |
| 修改設定值 | ❌ 通常需要重新建置與部署 Image | ✅ 修改 ConfigMap,再依使用方式更新或重啟 Pod |
| 多個服務共用設定 | ❌ 每個 Image 都需要各自保存一份設定 | ✅ 多個 Pod / Workload 可共用同一份 ConfigMap |
| 設定與 Image 分離 | ❌ 設定會跟著 Image 一起打包 | ✅ 設定可獨立於 Image 管理 |
12-Factor App 與設定管理
The Twelve-Factor App 的第三項原則是 Config — 將設定存放於環境中。像資料庫位址、API Endpoint、執行環境等會隨部署環境改變的設定,應與程式碼分離,並透過環境變數或外部設定提供給應用程式。
⚠️ 敏感資訊不應放在 ConfigMap 中。
密碼、API Key、Token、憑證等敏感資料,應使用 Kubernetes Secret 管理。
ConfigMap 是 Kubernetes 用來儲存非機密設定資料的資源物件,內容以 Key-Value 的形式保存。
可以將一般設定值、環境變數,甚至整份設定檔存放在 ConfigMap 中,再由 Pod 以環境變數或掛載檔案的方式讀取。
最快的方式,直接用 kubectl create configmap:
# 用 --from-literal 直接指定 key=value
kubectl create configmap app-config \
--from-literal=APP_ENV=production \
--from-literal=APP_PORT=8080 \
--from-literal=LOG_LEVEL=info
查看建立的 ConfigMap:
kubectl get configmap app-config -o yaml
會看到 data 欄位裡面就是剛才設定的 Key-Value:

當設定比較多的時候,用 YAML 檔案管理更清楚:
vim app-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
APP_PORT: "8080"
LOG_LEVEL: info
kubectl apply -f app-config.yaml
如果有一整份設定檔(例如 nginx.conf),可以直接把檔案內容存進 ConfigMap:
# 建立 NGINX 設定檔
vim my-nginx.conf
在 vim 中貼上:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /health {
return 200 'OK';
add_header Content-Type text/plain;
}
}
儲存後,再建立 ConfigMap:
# 從檔案建立 ConfigMap
kubectl create configmap nginx-config --from-file=default.conf=my-nginx.conf
查看內容:
kubectl get configmap nginx-config -o yaml
會看到整個檔案內容都被存在 data.default.conf 這個 Key 底下
--from-file=key=filename格式說明
key是 ConfigMap 中的 Key 名稱,filename則是本機設定檔的路徑。例如:
--from-file=default.conf=my-nginx.conf代表將本機的
my-nginx.conf內容存入 ConfigMap,並以default.conf作為 Key。如果省略
key=,例如--from-file=my-nginx.conf,ConfigMap 會直接使用檔名my-nginx.conf作為 Key。
ConfigMap 建立完成後,接下來要讓 Pod 能夠使用其中的設定。常見有三種方式:
把 ConfigMap 的所有 Key-Value 一次全部 注入為環境變數:
vim pod-envfrom.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-envfrom
spec:
containers:
- name: app
image: nginx
envFrom:
- configMapRef:
name: app-config
先確認 ConfigMap 內容
前面我們已經建立了
app-configConfigMap,其中包含:
APP_ENV=productionAPP_PORT=8080LOG_LEVEL=info接下來的
envFrom會把這些 Key-Value 一次匯入 Pod,作為 Container 的環境變數。
kubectl apply -f pod-envfrom.yaml
驗證環境變數有沒有注入成功:
kubectl exec pod-envfrom -- env | grep -E "APP_|LOG_"
你應該會看到:

ConfigMap 的所有 Key 都變成環境變數了!
如果你只想注入部分 Key,或是想要在 Pod 裡用不同的變數名稱:
vim pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-env
spec:
containers:
- name: app
image: nginx
env:
- name: ENVIRONMENT
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
- name: PORT
valueFrom:
configMapKeyRef:
name: app-config
key: APP_PORT
⚠️ 注意
ConfigMap 的 Key 名稱與 Pod 中的環境變數名稱可以不同。
例如 ConfigMap 裡的 Key 是
APP_ENV,在 Pod 中可以將它命名為ENVIRONMENT
kubectl apply -f pod-env.yaml
驗證:
kubectl exec pod-env -- env | grep -E "ENVIRONMENT|PORT"

當應用程式需要讀取完整設定檔時,可以將 ConfigMap 透過 Volume 掛載到 Container 中,特別適合 nginx.conf、application.yml 等檔案型設定:
vim pod-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-volume
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: nginx-config
kubectl apply -f pod-volume.yaml
驗證設定檔有沒有掛載成功:
kubectl exec pod-volume -- cat /etc/nginx/conf.d/default.conf
會看到我們之前建立的 NGINX 設定檔內容,包含 /health 路徑的設定。

測試 /health 端點:
kubectl exec pod-volume -- curl -s localhost/health
# → OK
這是一個很常見的問題,答案是:看你用哪種注入方式。
修改 ConfigMap:
kubectl edit configmap app-config
把 LOG_LEVEL 改成 debug,存檔後驗證:

kubectl exec pod-envfrom -- env | grep LOG_LEVEL

環境變數在 Pod 啟動時就固定了,改 ConfigMap 不會影響已經在跑的 Pod。你需要重啟 Pod 才能拿到新值:
kubectl delete pod pod-envfrom
kubectl apply -f pod-envfrom.yaml
kubectl exec pod-envfrom -- env | grep LOG_LEVEL

修改 nginx-config ConfigMap:
kubectl edit configmap nginx-config
把 /health 的回應改成 Healthy

等大約 30 秒到 1 分鐘,再檢查:
kubectl exec pod-volume -- cat /etc/nginx/conf.d/default.conf
會看到檔案內容已經更新了!

⚠️ 注意:檔案更新 ≠ 應用程式重新載入
雖然透過 Volume 掛載的 ConfigMap 檔案內容可以自動同步更新,但應用程式不一定會自動重新讀取設定檔。
例如 NGINX 的設定檔更新後,可能還需要:
- 執行
nginx -s reload,讓 NGINX 重新讀取設定- 使用 Sidecar Container 監控設定檔變化,並觸發 reload
- 或重新啟動 Deployment 中的 Pod,例如執行
kubectl rollout restart deployment <deployment-name>
| 方式 | 適用場景 | ConfigMap 更新後 |
|---|---|---|
envFrom |
將多個 Key-Value 一次匯入為環境變數 | ❌ 已啟動的 Pod 不會自動更新,需重新建立 Pod |
env.valueFrom |
引用指定 Key,並可自訂環境變數名稱 | ❌ 已啟動的 Pod 不會自動更新,需重新建立 Pod |
| Volume 掛載 | 將 ConfigMap 內容提供為設定檔 | ✅ 掛載內容會自動同步,但可能有延遲 |
三種方式怎麼選?
- 一般 Key-Value 設定(例如
APP_ENV=production)→ 使用環境變數,可選擇envFrom或env.valueFrom- 完整設定檔(例如
nginx.conf、redis.conf)→ 使用 Volume 掛載- 實際應用中,也可以依需求同時使用環境變數與 Volume 掛載
前面我們已經分別示範了 ConfigMap 的環境變數與 Volume 掛載方式。
最後透過同一個 Deployment,同時使用這兩種方式:
app-config 將設定注入為環境變數web-content 將 index.html 掛載到 NGINXvim web-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: web-content
data:
index.html: |
<!DOCTYPE html>
<html>
<head><title>Day 7 Demo</title></head>
<body>
<h1>Hello from ConfigMap!</h1>
<p>This page is injected via ConfigMap volume mount.</p>
<p>Environment: production</p>
</body>
</html>
建立使用這個 ConfigMap 的 Deployment:
vim web-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: app-config
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
configMap:
name: web-content
為什麼掛載到
/usr/share/nginx/html?Kubernetes 並沒有規定 ConfigMap 必須掛載到特定路徑,
mountPath可以依應用程式的需求自行指定。這個範例使用官方 NGINX Image,而
/usr/share/nginx/html是 NGINX 預設存放靜態網頁內容的目錄。因此將
web-contentConfigMap 掛載到這個路徑後,其中的index.html會出現在/usr/share/nginx/html/index.html,並成為 NGINX 提供的首頁內容。
套用並測試:
kubectl apply -f web-config.yaml
kubectl apply -f web-deploy.yaml
kubectl expose deployment web-app --port=80
驗證:
# 確認環境變數
kubectl exec deploy/web-app -- env | grep APP_ENV
# → APP_ENV=production
# 確認首頁內容
kubectl exec deploy/web-app -- curl -s localhost
# → Hello from ConfigMap!

今天我們學會了使用 ConfigMap,將設定從 Container Image 中抽離:
| 概念 | 重點 | 說明 |
|---|---|---|
| ConfigMap | 設定儲存 | 以 Key-Value 形式儲存非機密的設定資料 |
envFrom |
全部匯入 | 將 ConfigMap 中的所有 Key-Value 一次匯入為環境變數 |
env.valueFrom |
指定匯入 | 引用指定的 Key,並可自訂環境變數名稱 |
| Volume 掛載 | 檔案掛載 | 將 ConfigMap 內容掛載為檔案,內容更新後可自動同步 |
ConfigMap 解決了「一般設定」的管理問題,但有些資料並不適合放在 ConfigMap 中。
例如 資料庫密碼、API Key、Token、TLS 憑證等機密資訊,如果直接存放在 ConfigMap,並不是合適的做法。
那這些敏感資料,在 Kubernetes 中應該怎麼管理?
明天我們會接著介紹 Secret,看看 Kubernetes 如何管理機密資訊,以及它和 ConfigMap 有什麼不同!