stakater/Reloader

GitHub: stakater/Reloader

Kubernetes 控制器,监听 ConfigMap 和 Secret 变更并自动触发相关工作负载的滚动升级,解决配置更新后 Pod 不自动重启的问题。

Stars: 9768 | Forks: 632

Reloader

## 🔁 什么是 Reloader? Reloader 是一个 Kubernetes controller,每当引用的 `Secrets`、`ConfigMaps` 或 **可选的 CSI 挂载 secrets** 更新时,它会自动触发工作负载(如 Deployments、StatefulSets 等)的 rollouts。 在传统的 Kubernetes 设置中,更新 `Secret` 或 `ConfigMap` 并不会自动重启或重新部署您的工作负载。这可能导致生产环境中运行过时的配置,特别是在处理凭据、功能开关 或环境配置等动态值时。 Reloader 弥合了这一差距,确保您的工作负载与配置更改保持同步 —— 自动且安全。 ## 🚀 为什么选择 Reloader? - ✅ **零手动重启**:配置/secret 更改后无需手动 rollout 工作负载。 - 🔒 **设计安全**:确保您的应用始终使用最新的凭据或 token。 - 🛠️ **灵活**:适用于所有主要工作负载类型 —— Deployment、StatefulSet、Daemonset、ArgoRollout 等。 - ⚡ **快速反馈循环**:非常适合频繁更改 secrets/configs 的 CI/CD pipeline。 - 🔄 **开箱即用的集成**:只需标记您的工作负载,剩下的交给 Reloader 处理。 ## 🔧 它是如何工作的? ``` flowchart LR ExternalSecret -->|Creates| Secret SealedSecret -->|Creates| Secret Certificate -->|Creates| Secret Secret -->|Watched by| Reloader ConfigMap -->|Watched by| Reloader Reloader -->|Triggers Rollout| Deployment Reloader -->|Triggers Rollout| DeploymentConfig Reloader -->|Triggers Rollout| Daemonset Reloader -->|Triggers Rollout| Statefulset Reloader -->|Triggers Rollout| ArgoRollout Reloader -->|Triggers Job| CronJob Reloader -->|Sends Notification| Slack,Teams,Webhook ``` - 诸如 `ExternalSecret`、`SealedSecret` 或来自 `cert-manager` 的 `Certificate` 等来源可以创建或管理 Kubernetes `Secrets` —— 但它们也可以手动创建或通过 GitOps workflow 交付。 - `Secrets` 和 `ConfigMaps` 由 Reloader 监控。 - 当检测到更改时,Reloader 自动触发相关工作负载的 rollout,确保您的应用始终运行最新的配置。 ## ⚡ 快速开始 ### 1. 安装 Reloader 遵循此[安装选项](#-installation)。 ### 2. 注解您的工作负载 要为 Deployment 启用自动重新加载: ``` apiVersion: apps/v1 kind: Deployment metadata: name: my-app annotations: reloader.stakater.com/auto: "true" spec: template: metadata: labels: app: my-app spec: containers: - name: app image: your-image envFrom: - configMapRef: name: my-config - secretRef: name: my-secret ``` 这告诉 Reloader 监视此 deployment 中引用的 `ConfigMap` 和 `Secret`。当其中任何一个更新时,它将触发 rollout。 ## 🏢 企业版 Stakater 提供 Reloader 的企业级版本,包含: 1. SLA 支持支持 2. 认证镜像 3. 私有 Slack 支持 联系 [`sales@stakater.com`](mailto:sales@stakater.com) 了解有关 Reloader Enterprise 的信息。 ## 🧩 用法 Reloader 支持多种基于 annotation 的控制,让您可以**自定义 `Secrets` 或 `ConfigMaps` 更改时 Kubernetes 工作负载重新加载的时间和方式**。 当引用的 `Secret` 或 `ConfigMap` 更新时,Kubernetes 不会触发 pod 重启。Reloader 通过监控更改并自动执行 rollout 来弥补这一差距 —— 但它通过 annotation 让您完全控制,因此您可以: - 默认重新加载**所有**资源 - 将重新加载限制为仅 **Secrets** 或仅 **ConfigMaps** - 仅监视**特定资源** - 使用**通过标记选择加入**(`search` + `match`) - 排除您不想重新加载的工作负载 ### 1. 🔁 自动重新加载(默认) 当引用的 `Secrets` 或 `ConfigMaps` 更改时,使用这些 annotation 自动重启工作负载。 | Annotation | 描述 | |--------------------------------------------|----------------------------------------------------------------------| | `reloader.stakater.com/auto: "true"` | 当任何引用的 ConfigMap 或 Secret 更改时重新加载工作负载 | | `secret.reloader.stakater.com/auto: "true"`| 仅当引用的 Secret(s) 更改时重新加载 | | `configmap.reloader.stakater.com/auto: "true"`| 仅当引用的 ConfigMap(s) 更改时重新加载 | ### 2. 📛 指定资源重新加载(特定资源 Annotation) 这些 annotation 允许您手动定义哪些 ConfigMaps 或 Secrets 应触发重新加载,无论它们是否在 pod spec 中使用。 | Annotation | 描述 | |-----------------------------------------------------|--------------------------------------------------------------------------------------| | `secret.reloader.stakater.com/reload: "my-secret"` | 当特定 Secret(s) 更改时重新加载,无论它们如何被使用 | | `configmap.reloader.stakater.com/reload: "my-config"`| 当特定 ConfigMap(s) 更改时重新加载,无论它们如何被使用 | #### 使用场景 1. ✅ 这在配置共享但仅在特定情况下需要重新加载的严格范围场景中很有用。 2. ✅ 当您确切知道哪些资源重要并希望完全避免自动发现或搜索时,请使用此选项。 ### 3. 🎯 定向重新加载(Match + Search Annotation) 此模式允许细粒度的重新加载控制 —— 工作负载仅在以下情况下重启:Secret/ConfigMap 同时满足: 1. 被工作负载引用 2. 显式标注了 `match: true` | Annotation | 应用于 | 描述 | |-------------------------------------------|--------------|-----------------------------------------------------------------------------| | `reloader.stakater.com/search: "true"` | Workload | 启用搜索模式(仅在找到匹配的 secrets/configMaps 时重新加载) | | `reloader.stakater.com/match: "true"` | ConfigMap/Secret | 将 config/secret 标记为在搜索模式下符合重新加载条件 | #### 工作原理 1. 工作负载必须具有:`reloader.stakater.com/search: "true"` 2. ConfigMap 或 Secret 必须具有:`reloader.stakater.com/match: "true"` 3. 资源(ConfigMap 或 Secret)也必须在工作负载中引用(通过 env、`volumeMount` 等) #### 使用场景 1. ✅ 您希望仅在工作负载引用了显式标记为 `reloader.stakater.com/match: "true"` 的 ConfigMap 或 Secret 时才重新加载该工作负载。 2. ✅ 当您希望完全控制哪些共享或系统范围的资源触发重新加载时,请使用此选项。非常适合多租户 cluster 或共享配置。 ### ⛔ 资源级别忽略 Annotation 当您需要阻止特定 ConfigMaps 或 Secrets 触发任何重新加载时,在资源本身上使用 ignore annotation: ``` apiVersion: v1 kind: ConfigMap # or Secret metadata: name: my-config annotations: reloader.stakater.com/ignore: "true" ``` 这指示 Reloader 跳过该资源在所有工作负载中的所有重新加载逻辑。 ### 4. ⚙️ 工作负载特定的 Rollout 策略(仅限 Argo Rollouts) 注意:这仅在使用 [Argo Rollouts](https://argoproj.github.io/argo-rollouts/) 时适用。对于标准的 Kubernetes `Deployments`、`StatefulSets` 或 `DaemonSets`,它会被忽略。要使用此功能,必须在 Reloader 中启用 Argo Rollouts 支持(例如通过 --is-argo-rollouts=true)。 默认情况下,Reloader 通过更新 pod template 触发 Argo Rollout controller 执行标准 rollout。这在大多数情况下都有效,然而,由于这会修改工作负载 spec,ArgoCD 等 GitOps 工具会将此检测为“配置漂移”并将您的应用程序标记为 OutOfSync。 为避免这种情况,您可以切换到 **restart** 策略,该策略只需重启 pod 而无需更改 pod template。 ``` metadata: annotations: reloader.stakater.com/rollout-strategy: "restart" ``` | Value | 行为 | |--------------------|-----------------------------------------------------------------| | `rollout` (默认) | 更新 pod template 元数据以触发 rollout | | `restart` | 删除 pod 以重启它而不修改 template | ✅ 在以下情况下使用 `restart`: 1. 您正在使用 GitOps 并希望避免漂移 2. 您希望快速重启而不更改工作负载 spec 3. 您的平台限制了元数据更改 此设置影响 Argo Rollouts 行为,而非 Argo CD 同步设置。 ### 5. ❗ Annotation 行为规则与兼容性 - `reloader.stakater.com/auto` 和 `reloader.stakater.com/search` **不能一起使用** —— `auto` annotation 优先。 - 如果同时使用 `auto` 及其类型化版本(`secret.reloader.stakater.com/auto`、`configmap.reloader.stakater.com/auto`),**只需一个为 true** 即可触发重新加载。 - 显式设置 `reloader.stakater.com/auto: "false"` 会禁用该工作负载的重新加载。 - 如果在 controller 上启用了 `--auto-reload-all`: - 所有工作负载都被视为具有 `auto: "true"`,除非它们显式将其设置为 `"false"`。 - 缺失或无法识别的 annotation 值被视为 `"false"`。 ### 6. 🔔 重新加载时告警 Reloader 可以选择在为工作负载(例如 `Deployment`、`StatefulSet` 等)触发滚动升级时**发送告警**。 这些告警发送到配置的 **webhook endpoint**,可以是通用接收器或 Slack、Microsoft Teams 或 Google Chat 等服务。 要启用此功能,请更新 `values.yaml` 中的 `reloader.env.secret` 部分(通过 Helm 安装时): ``` reloader: deployment: env: secret: ALERT_ON_RELOAD: "true" # Enable alerting (default: false) ALERT_SINK: "slack" # Options: slack, teams, gchat or webhook (default: webhook) ALERT_WEBHOOK_URL: "" # Required if ALERT_ON_RELOAD is true ALERT_ADDITIONAL_INFO: "Triggered by Reloader in staging environment" ``` ### 7. ⏸️ 暂停 Deployment 此功能允许您在指定持续时间内暂停 deployment 的 rollout,有助于防止在多个 ConfigMaps 或 Secrets 快速连续更新时发生多次重启。 | Annotation | 应用于 | 描述 | |---------------------------------------------------------|--------------|-----------------------------------------------------------------------------| | `deployment.reloader.stakater.com/pause-period: "5m"` | Deployment | 暂停指定时间段(例如 `5m`、`1h`)的重新加载 | #### 工作原理 1. 将 `deployment.reloader.stakater.com/pause-period` annotation 添加到您的 Deployment,指定暂停持续时间(例如 `"5m"` 表示五分钟)。 2. 当受监视的 ConfigMap 或 Secret 更改时,Reloader 仍会触发重新加载事件,但如果 deployment 暂停,rollout 将在暂停期结束前无效。 3. 如果多个资源一起更新,这可以避免重复重启。 #### 使用场景 1. ✅ 您的 deployment 引用了可能同时更新的多个 ConfigMaps 或 Secrets。 2. ✅ 您希望尽量减少不必要的 rollout 并减少由连续配置更改引起的停机时间。 ### 8. 🔐 CSI Secret Provider 支持 Reloader 支持 [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/),它允许将来自外部 secret 存储(如 AWS Secrets Manager、Azure Key Vault、HashiCorp Vault)的 secret 直接挂载到 pod 中。 与 Kubernetes Secret 对象不同,CSI 挂载的 secret 并不总是触发原生的 Kubernetes 更新事件。Reloader 通过监控 CSI 状态资源并在挂载的 secret 版本更改时重启受影响的工作负载来解决此问题。 #### 工作原理 启用 secret rotation 后,Secrets Store CSI Driver 会更新一个名为:`SecretProviderClassPodStatus` 的 Kubernetes 资源 此资源反映 pod 当前挂载的 secret 版本。 Reloader 监视这些更新,并在检测到更改时触发 rollout。 #### 前提条件 - 集群中必须安装 Secrets Store CSI Driver - CSI driver 中启用了 Secret rotation。 - 在 Reloader 中启用 CSI 集成:`--enable-csi-integration=true` #### CSI 挂载 Secrets 的 Annotation | Annotation | 描述 | |------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| | `reloader.stakater.com/auto: "true"` | 全局发现:当任何挂载的 ConfigMap 或 Secret 更新时,自动发现并重新加载工作负载。 | | `secretproviderclass.reloader.stakater.com/auto: 'true'` | CSI 发现:专门监视工作负载使用的所有 SecretProviderClasses 的更新(CSI driver 集成)。 | | `secretproviderclass.reloader.stakater.com/reload: "my-secretproviderclass"` | 定向重新加载:仅当特定的命名 SecretProviderClass(es) 更新时重新加载工作负载。 | Reloader 通过监视 `SecretProviderClassPodStatus` 在**每个 secret 级别**监控更改。确保您要监视的每个 secret 都在 `SecretProviderClass` 中使用 `secretKey` 正确定义: ``` apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: vault-reloader-demo namespace: test spec: provider: vault parameters: vaultAddress: "http://vault.vault.svc:8200" vaultSkipTLSVerify: "true" roleName: "demo-role" objects: | - objectName: "password" secretPath: "secret/data/reloader-demo" secretKey: "password" ``` ***重要***:Reloader 跟踪单个 secret 的更改(由 `secretKey` 标识)。如果您的 SecretProviderClass 没有为每个对象指定 `secretKey`,Reloader 可能无法正确检测更新。 #### 注意事项与限制 Reloader 对 CSI 状态更改做出反应,而不是对外部 secret 存储的直接更新 必须在 CSI driver 中启用 secret rotation 才能检测到更新 CSI 限制(例如 `subPath` 挂载)仍然适用,可能需要重启 pod 如果 secrets 同步到 Kubernetes Secret 对象,则应用标准 Reloader 行为,可能不需要 CSI 支持 ## 🚀 安装 ### 📦 Helm 根据您的 Kubernetes 设置和偏好,可以通过多种方式安装 Reloader。以下是支持的方法: ``` helm repo add stakater https://stakater.github.io/stakater-charts helm repo update helm install reloader stakater/reloader ``` ➡️ 在 [chart README](./deployments/kubernetes/chart/reloader/README.md) 中查看完整的 Helm 配置。 ### 2. 📄 原生 Manifests 直接应用原始 Kubernetes manifests: ``` kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml ``` ### 3. 🧱 原生 Kustomize 使用内置的 Kustomize 支持: ``` kubectl apply -k https://github.com/stakater/Reloader/deployments/kubernetes ``` ### 4. 🛠️ 自定义 Kustomize 设置 您可以创建自己的 `kustomization.yaml` 并使用 Reloader 的作为基础:
`--namespace-selector='key1=value1,key2=value2'`

`--namespace-selector='key in (value1,value2)'`| 仅监视具有匹配 label 的 namespace。有关 label selector 的更多详细信息,请参阅 [LIST and WATCH filtering](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#list-and-watch-filtering) | | `--namespaces-to-ignore=ns1,ns2` | 跳过特定 namespace 不进行监视 | #### 4. 📝 Annotation 键覆盖 这些 flag 允许您重新定义工作负载或资源中使用的 annotation 键: | Flag | 覆盖 | |------|-----------| | `--auto-annotation` | 覆盖 `reloader.stakater.com/auto` | | `--secret-auto-annotation` | 覆盖 `secret.reloader.stakater.com/auto` | | `--configmap-auto-annotation` | 覆盖 `configmap.reloader.stakater.com/auto` | | `--auto-search-annotation` | 覆盖 `reloader.stakater.com/search` | | `--search-match-annotation` | 覆盖 `reloader.stakater.com/match` | | `--secret-annotation` | 覆盖 `secret.reloader.stakater.com/reload` | | `--configmap-annotation` | 覆盖 `configmap.reloader.stakater.com/reload` | | `--pause-deployment-annotation` | 覆盖 `deployment.reloader.stakater.com/pause-period` | | `--pause-deployment-time-annotation` | 覆盖 `deployment.reloader.stakater.com/paused-at` | ### 5. 🕷️ 调试 | Flag | 描述 | |--- |-------------| | `--enable-pprof` | 启用 `pprof` 进行性能分析 | | `--pprof-addr` | 启动 `pprof` server 的地址。默认为 `:6060` | ## 兼容性 Reloader 兼容 Kubernetes >= 1.19 ## 帮助 ### 文档 可以从[文档站点](https://docs.stakater.com/reloader/)查看 Reloader 文档。文档源位于 [docs](./docs/) 文件夹中。 ### 有问题? 提交 GitHub [issue](https://github.com/stakater/Reloader/issues)。 ### 在 Slack 上与我们交流 加入并在 Slack 上与我们讨论 Reloader: [![Join Slack](https://stakater.github.io/README/stakater-join-slack-btn.png)](https://slack.stakater.com/) [![Chat](https://stakater.github.io/README/stakater-chat-btn.png)](https://stakater-community.slack.com/messages/CC5S05S12) ## 贡献 ### 错误报告和功能请求 请使用 [issue tracker](https://github.com/stakater/Reloader/issues) 报告任何错误或提交功能请求。 ### 开发 1. 部署 Reloader 2. 运行 `okteto up` 激活您的开发容器 3. `make build` 4. `./Reloader` 欢迎提交 PR。通常,我们遵循“fork-and-pull” Git workflow: 1. 在 GitHub 上 **Fork** 仓库 2. **Clone** 项目到您自己的机器 3. **Commit** 更改到您自己的分支 4. **Push** 您的工作回到您的 fork 5. 提交 **Pull request**,以便我们可以审查您的更改 **注意:** 在提出 pull request 之前,请务必合并来自 "upstream" 的最新内容! ## 发布流程 *Repository GitHub releases*: 应社区在 [issue 685](https://github.com/stakater/Reloader/issues/685) 中的请求,Reloader 现在基于手动发布流程。不再在每次合并 PR 到主分支时进行发布,而是根据请求手动进行。 要进行 GitHub release: 1. Code owner 从 `master` 创建发布分支 `release-vX.Y.Z` 2. Code owner 运行 [Init Release](https://github.com/stakater/Reloader/actions/workflows/init-branch-release.yaml) workflow 以在发布分支上自动生成版本和 manifests - 将 `TARGET_BRANCH` 参数设置为发布分支,即 `release-vX.Y.Z` - 将 `TARGET_VERSION` 设置为不带 'v' 的发布版本,即 `X.Y.Z` 3. 创建一个 PR 以提升发布分支上的镜像版本,示例:[PR-798](https://github.com/stakater/Reloader/pull/798) 4. Code owner 使用标签 `vX.Y.Z` 和目标分支 `release-vX.Y.Z` 创建 GitHub release,这将触发镜像的创建 5. Code owner 从 `master` 创建另一个分支,并提升 helm chart 版本以及 Reloader 镜像版本。 - Code owner 创建带有 `release/helm-chart` 标签的 PR,示例:[PR-846](https://github.com/stakater/Reloader/pull/846) *Repository git tagging*: 推送到主分支将创建一个名为 `merge-${{ github.event.number }}` 的 merge-image 和 merge-tag,例如当 pull request 编号 800 合并时为 `merge-800`。 ## 更新日志 查看 [releases page](https://github.com/stakater/Reloader/releases) 以了解每个版本中的更改。 ## 许可证 Apache2 © [Stakater][website] ## 关于 Stakater [![Get started with Stakater](https://stakater.github.io/README/stakater-github-banner.png)](https://stakater.com/?utm_source=Reloader&utm_medium=github) `Reloader` 由 [Stakater][website] 维护。喜欢它?请在 [hello@stakater.com](hello@stakater.com) 告诉我们 请参阅[我们的其他项目](https://github.com/stakater),或通过 [hello@stakater.com](hello@stakater.com) 联系我们以获取专业服务和咨询
标签:ArgoRollouts, ConfigMap, DaemonSet, Deployment, EVTX分析, GitOps, Secrets, StatefulSet, 变更管理, 子域名突变, 容器编排, 持续部署, 控制器, 日志审计, 滚动更新, 监控, 自动化运维, 自动重启, 零停机