在 Kubernetes 的日常維運中,ConfigMap 和 Secret 是我們管理應用程式設定與敏感資訊的核心元件。不過有個老問題一直困擾著不少人:當你修改了 ConfigMap 或 Secret 的內容後,正在跑的 Pod 並不會自動感知這些變更,你得手動重啟或用其他方式讓新設定生效。
今天想跟大家聊聊一個我自己在用的好工具 — Reloader。它是由 Stakater 開發的開源 Kubernetes Controller,能夠自動監控 ConfigMap 和 Secret 的變化,一旦偵測到更新就會觸發相關工作負載的滾動升級(Rolling Upgrade),讓你的應用程式永遠跑在最新的設定上,完全不需要人工介入。

Reloader 到底在做什麼?
簡單來說,Reloader 就像是 Kubernetes 裡的一個「設定變更守衛」。它持續盯著你指定的 ConfigMap 和 Secret,只要這些資源的內容有任何異動,它就會通知對應的 Deployment、StatefulSet、DaemonSet 等工作負載去做一次滾動升級。
它的核心運作原理是透過 SHA1 雜湊值來比對 ConfigMap/Secret 的內容是否真正發生了變化。如果雜湊值不同,才會觸發升級動作,避免不必要的重啟。

安裝方式
Reloader 提供兩種主要的安裝方式:Helm Chart 和原生 Manifest。
方式一:使用 Helm Chart(推薦)
先加入 Stakater 的 Helm repo 並更新:
helm repo add stakater https://stakater.github.io/stakater-charts
helm repo update
接著部署 Reloader,依需求選擇監控範圍:
| 指令 | 說明 |
|---|---|
helm install reloader stakater/reloader |
監控所有 Namespace 的 ConfigMap/Secret |
helm install reloader stakater/reloader --set reloader.watchGlobally=false --namespace <NS> |
僅監控特定 Namespace |
方式二:使用原生 Manifest
直接套用官方提供的 YAML:
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
預設會部署在 default Namespace,並監控所有 Namespace 的 ConfigMap 和 Secret 變更。
使用方式與 Annotation 詳解
Reloader 透過 Annotation 來決定要監控哪些資源。以下是幾種常見的使用模式:
自動模式(Auto)
在 Deployment 的 metadata 加上以下 Annotation,Reloader 就會自動掃描這個 Deployment 所使用的所有 ConfigMap 和 Secret:
kind: Deployment
metadata:
annotations:
reloader.stakater.com/auto: "true"
spec:
template:
metadata:
這是最簡單也最常用的方式。只要該 Deployment 透過環境變數或 Volume Mount 引用了某個 ConfigMap/Secret,Reloader 就會在那個資源變更時自動觸發滾動升級。
搜尋模式(Search + Match)
如果你想更精細地控制,可以用 search/match 的組合。先在 Deployment 上標記:
kind: Deployment
metadata:
annotations:
reloader.stakater.com/search: "true"
然後在需要被追蹤的 ConfigMap/Secret 上加上:
kind: ConfigMap
metadata:
annotations:
reloader.stakater.com/match: "true"
data:
key: value
要注意的是,search 和 auto 這兩個 Annotation 不能同時使用。如果設了 auto: "true",不管 ConfigMap/Secret 有沒有 match 標記都會觸發重載。
指定特定 ConfigMap
只想在某個 ConfigMap 變更時觸發滾動升級:
kind: Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload: "foo-configmap"
多個 ConfigMap 用逗號分隔:
configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap"
指定特定 Secret
同理,只在某個 Secret 變更時觸發:
kind: Deployment
metadata:
annotations:
secret.reloader.stakater.com/reload: "foo-secret"
多個 Secret 用逗號分隔:
secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret"
重新載入策略(Reload Strategy)
Reloader 支援兩種不同的重載策略:
| 策略 | 說明 | 參數 |
|---|---|---|
| env-vars(預設) | 在工作負載的容器上附加 Reloader 專屬環境變數,用來標記 ConfigMap/Secret 版本 | --reload-strategy=env-vars |
| annotations | 在 Pod Template 上附加 reloader.stakater.com/last-reloaded-from Annotation |
--reload-strategy=annotations |
annotations 策略特別適合搭配 ArgoCD 這類 GitOps 工具使用,因為它不會產生配置漂移(Configuration Drift)的誤判。
實戰演練
下面用一個簡單的範例來驗證 Reloader 的效果。
第一步:建立 ConfigMap 和 Secret
apiVersion: v1
kind: ConfigMap
metadata:
name: test-configmap
data:
test_env: "foo"
---
apiVersion: v1
data:
pass: ********
kind: Secret
metadata:
name: test-secret
第二步:建立 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
annotations:
configmap.reloader.stakater.com/reload: "test-configmap"
secret.reloader.stakater.com/reload: "test-secret"
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
env:
- name: TEST_ENV
valueFrom:
configMapKeyRef:
name: test-configmap
key: test_env
- name: TEST_PASS
valueFrom:
secretKeyRef:
name: test-secret
key: pass
這裡的兩個 Annotation 分別監控了 test-configmap 和 test-secret。
第三步:修改 ConfigMap 或 Secret
當你更新 ConfigMap 的內容後,Reloader 會自動偵測到變更,並觸發 Deployment 的滾動升級。新的 Pod 會使用更新後的環境變數值。Secret 的更新也是同樣的道理。
實用小提醒
| 項目 | 說明 |
|---|---|
| Sealed Secrets 支援 | Reloader 相容 sealed-secrets |
| Rollouts 整合 | 對 Argo Rollouts 的觸發取決於你設定的 rollout strategy |
| 自動註解條件 | auto: "true" 只有在 ConfigMap/Secret 真的被 Pod 使用(env 或 volume mount)時才會觸發 |
| 強制重載 | secret.reloader.stakater.com/reload 和 configmap.reloader.stakater.com/reload 不管有沒有使用都會觸發 |
| 忽略 Namespace | 可用 --namespaces-to-ignore 排除特定 Namespace |
| Namespace 篩選 | 可用 --namespace-selector 只監控帶有特定 Label 的 Namespace |
| 資源篩選 | 可用 --resource-label-selector 只監控帶有特定 Label 的 ConfigMap/Secret |
| JSON 日誌 | 可用 --log-format=json 啟用 JSON 格式日誌 |
結語
Reloader 是我在 Kubernetes 維運中非常推薦的一個輕量級工具。它解決了一個看似簡單但實務上很煩人的問題:ConfigMap 和 Secret 更新後 Pod 不會自動重啟。
透過簡單的 Annotation 設定,你就能讓應用程式永遠跑在最新的設定上,大幅減少人工介入的需求。不論是搭配 Helm 還是原生 Manifest 部署都很方便,再加上對 ArgoCD 和 Sealed Secrets 的良好支援,幾乎可以無痛融入現有的 CI/CD 流程。
如果你也受夠了每次改完設定還要手動重啟 Pod 的日子,不妨試試 Reloader 吧!

發佈留言