使用 reloader 监控 configmap/secret 并重启对应 pod ¶
在传统的 Kubernetes 设置中,更新Secret
或ConfigMap
不会自动重启或重新部署工作负载。这可能会导致生产环境中运行过时的配置,尤其是在处理凭证、功能开关或环境配置等动态值时。手动滚动更新延迟并繁琐。调研使用 reloader 自动化监控。
1. reloader 介绍和场景 ¶
1. 核心功能与价值 ¶
Reloader 是一个 Kubernetes 控制器,用于监控 ConfigMap 和 Secret 的变化,并自动触发关联 Pod 的滚动更新。其核心价值在于:
- 无感知配置更新
- 当 ConfigMap/Secret 变更时,自动重启关联的 Pod,无需手动干预
- 支持滚动更新策略,确保服务零停机
- 多触发方式支持
- 基于注解(Annotation)的细粒度控制
- 支持 Deployment、StatefulSet、DaemonSet 等多种工作负载类型
- 性能优化
- 低资源消耗(内存占用 < 10MB)
- 基于 Kubernetes API Watch 机制,实时感知配置变化
2. Reloader vs 传统配置更新方式 ¶
对比项 | 手动滚动更新 | Reloader 自动更新 |
---|---|---|
更新时效性 | 分钟级(人工操作延迟) | 秒级(自动触发) |
出错概率 | 高(可能遗漏或操作失误) | 低(自动化流程) |
服务可用性 | 可能中断(全量重启) | 零停机(滚动更新) |
配置管理复杂度 | 高(需记录更新步骤) | 低(注解驱动) |
2. reloader 安装并配置 ¶
1. 安装 Reloader ¶
helm repo add stakater https://stakater.github.io/stakater-charts
helm repo update
helm install reloader stakater/reloader
2. 用「开关模型」理解三种模式 ¶
1. 自动重新加载(默认):全屋总开关 ¶
检测在引用的 Secrets
或 ConfigMaps
更改时自动重启工作负载并实现滚动升级
-
开关位置:装在所有房间门口(Deployment 侧统一开启)。
-
触发逻辑:只要任意一个电器(ConfigMap/Secret)短路(变更),全屋断电(所有 Deployment 重启)。
-
配置代码:
kind: Deployment
metadata:
annotations:
reloader.stakater.com/auto: "true" # 开启总开关
- 实操效果:修改任意引用的 ConfigMap,执行
kubectl get deploy -w
会看到 Pod 版本号递增。
注解 | 描述 |
---|---|
reloader.stakater.com/auto: "true" |
当任何引用的 ConfigMap 或 Secret 发生更改时重新加载工作负载 |
secret.reloader.stakater.com/auto: "true" |
仅当引用的 Secret 发生变化时才重新加载 |
configmap.reloader.stakater.com/auto: "true" |
仅当引用的 ConfigMap 发生更改时才重新加载 |
配置完成后 reloader
会检测所有命名空间中其相关联的 ConfigMap
或者 Secret
的变化,并实现滚动升级。
2. 命名资源重新加载:单个电器开关 ¶
-
开关位置:装在特定电器(ConfigMap/Secret)上,需在房间(Deployment)内单独指定。
-
触发逻辑:仅当指定电器(如冰箱)短路时,对应房间断电,其他房间不受影响。
-
配置代码:
kind: Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload: "fridge-config" # 仅监听冰箱配置
#secret.reloader.stakater.com/reload: "1-secret,2-secret,3-secret" # Secret 资源
- 实操效果:修改
fridge-config
时 Deployment 重启,修改tv-config
时无反应。
3. 定向重新加载:双锁开关 ¶
-
开关位置:需要房间门锁(Deployment 的 search)和电器锁(ConfigMap 的 match)同时打开。
-
触发逻辑:只有当房间允许搜索(search: true)且电器被标记(match: true)时,短路才会触发断电。
-
配置代码:
# Deployment侧(房间门锁)
kind: Deployment
metadata:
annotations:
reloader.stakater.com/search: "true" # 允许搜索标记的配置
# ConfigMap侧(电器锁)
kind: ConfigMap
metadata:
annotations:
reloader.stakater.com/match: "true" # 标记为可触发重启
- 实操效果:若只修改未标记 match 的 ConfigMap,即使 Deployment 开启 search 也不会重启。
3. 反例警示:错误配置的后果 ¶
1. 自动重新加载误用场景 ¶
- 错误配置:在前端静态资源 ConfigMap 中使用
auto: true
。 - 后果:设计师频繁修改样式配置时,后端服务会被无意义重启,导致接口请求失败。
2. 命名资源重新加载遗漏场景 ¶
- 错误配置:Deployment 中
reload
列表遗漏关键 ConfigMap。 - 后果:数据库连接配置变更时,因未被列入 reload 列表,服务使用旧密码连接失败,且无重启修复机制。
3. 定向重新加载权限混乱场景 ¶
- 错误配置:多租户集群中,租户 A 的 Deployment 未开启 search,但 ConfigMap 标记了 match。
- 后果:租户 B 的 Deployment 若引用该 ConfigMap,变更时会误触发租户 B 的服务重启,导致跨租户影响。
4. 终极总结:场景选择的黄金法则 ¶
- 当配置变更影响全局服务时(如数据库密码、JWT 密钥):选自动重新加载,确保所有服务同步更新。
- 当配置变更仅影响单个服务的特定功能时(如路由规则、限流阈值):选命名资源重新加载,精准触发重启。
- 当需要跨团队 / 租户隔离配置影响时(如多租户共享集群):选定向重新加载,通过双向标记避免误触。
3. 创建 demo 滚动升级 ¶
1. 创建 资源文件 ¶
创建 configmap ¶
# 1-nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-index
data:
index.html: |
<html>
<body>
<h1>我是 v1 版本</h1>
</body>
</html>
创建 deployment ¶
# 2-nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx
image: docker.io/library/nginx:1.15-alpine
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /usr/share/nginx/html/
volumes:
- name: config-volume
configMap:
name: nginx-index
创建 service ¶
# 3-nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx-demo
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
创建 ingress ¶
# 4-nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8slinuxcdn1
spec:
ingressClassName: nginx
tls:
- hosts:
- test.k8s.linuxcdn.com
secretName: k8s-linuxcdn-crt-secret
rules:
- host: test.k8s.linuxcdn.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx-service
port:
number: 80
创建 PodDisruptionBudget ¶
PodDisruptionBudget
(PDB) 是 Kubernetes 中的一种资源类型,用于控制自愿性中断(Voluntary Disruption)期间的 Pod 可用性。简单来说,它限制了在集群操作(如节点维护、滚动更新)期间,应用的不可用 Pod 数量上限。
# 5-nginx-ingress.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: nginx-demo-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: nginx-demo
2. 创建服务 ¶
![]() |
3. 更改 configmap 查看是否会自动更新 ¶
修改 configmap ¶
测试 reloader 功能时,只需执行以下命令更新 ConfigMap
kubectl edit configmap nginx-index
将 index.html 内容修改为:
<html>
<body>
<h1>我是 v2 版本</h1>
</body>
</html>
保存后,reloader 会自动检测到 ConfigMap 的变化,并触发 nginx Deployment 的滚动更新。你可以通过以下命令监控 Pod 重启过程:
kubectl get pods -w -l app=nginx-demo
过程图 |
---|
![]() |
🔔 重新加载时发出警报 ¶
每当触发工作负载的滚动升级(例如,等)时, Reloader 可以选择发送警报。Deployment``StatefulSet
这些警报被发送到已配置的webhook 端点,该端点可以是通用接收器或 Slack 或 Microsoft Teams 等服务。
要启用此功能,请更新reloader.env.secret
您的部分values.yaml
(通过 Helm 安装时):
reloader:
env:
secret:
ALERT_ON_RELOAD: "true" # Enable alerting (default: false)
ALERT_SINK: "slack" # Options: slack, teams, webhook (default: webhook)
ALERT_WEBHOOK_URL: "<your-webhook-url>" # Required if ALERT_ON_RELOAD is true
ALERT_ADDITIONAL_INFO: "Triggered by Reloader in staging environment"