← 返回上一頁
Kubernetes

在 Kubernetes 中使用 Reloader 自動熱載入 ConfigMap 與 Secret

本頁目錄
Stakater Reloader Kubernetes Controller Logo

在 Kubernetes 的日常維運中,ConfigMap 和 Secret 是我們管理應用程式設定與敏感資訊的核心元件。不過有個老問題一直困擾著不少人:當你修改了 ConfigMap 或 Secret 的內容後,正在跑的 Pod 並不會自動感知這些變更,你得手動重啟或用其他方式讓新設定生效。

今天想跟大家聊聊一個我自己在用的好工具 — Reloader。它是由 Stakater 開發的開源 Kubernetes Controller,能夠自動監控 ConfigMap 和 Secret 的變化,一旦偵測到更新就會觸發相關工作負載的滾動升級(Rolling Upgrade),讓你的應用程式永遠跑在最新的設定上,完全不需要人工介入。

Stakater Reloader Kubernetes Controller Logo

Reloader 到底在做什麼?

簡單來說,Reloader 就像是 Kubernetes 裡的一個「設定變更守衛」。它持續盯著你指定的 ConfigMap 和 Secret,只要這些資源的內容有任何異動,它就會通知對應的 Deployment、StatefulSet、DaemonSet 等工作負載去做一次滾動升級。

它的核心運作原理是透過 SHA1 雜湊值來比對 ConfigMap/Secret 的內容是否真正發生了變化。如果雜湊值不同,才會觸發升級動作,避免不必要的重啟。

Reloader 監控 ConfigMap 和 Secret 變更並自動觸發 Pod 滾動升級的流程圖

安裝方式

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

要注意的是,searchauto 這兩個 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-configmaptest-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/reloadconfigmap.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 吧!

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料