跳转至

使用 reloader 监控 configmap/secret 并重启对应 pod

在传统的 Kubernetes 设置中,更新SecretConfigMap不会自动重启或重新部署工作负载。这可能会导致生产环境中运行过时的配置,尤其是在处理凭证、功能开关或环境配置等动态值时。手动滚动更新延迟并繁琐。调研使用 reloader 自动化监控。

1. reloader 介绍和场景

https://github.com/stakater/Reloader

1. 核心功能与价值

Reloader 是一个 Kubernetes 控制器,用于监控 ConfigMap 和 Secret 的变化,并自动触发关联 Pod 的滚动更新。其核心价值在于:

  1. 无感知配置更新
  2. 当 ConfigMap/Secret 变更时,自动重启关联的 Pod,无需手动干预
  3. 支持滚动更新策略,确保服务零停机
  4. 多触发方式支持
  5. 基于注解(Annotation)的细粒度控制
  6. 支持 Deployment、StatefulSet、DaemonSet 等多种工作负载类型
  7. 性能优化
  8. 低资源消耗(内存占用 < 10MB)
  9. 基于 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. 自动重新加载(默认):全屋总开关

检测在引用的 SecretsConfigMaps 更改时自动重启工作负载并实现滚动升级

  • 开关位置:装在所有房间门口(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. 终极总结:场景选择的黄金法则

  1. 当配置变更影响全局服务时(如数据库密码、JWT 密钥):选自动重新加载,确保所有服务同步更新。
  2. 当配置变更仅影响单个服务的特定功能时(如路由规则、限流阈值):选命名资源重新加载,精准触发重启。
  3. 当需要跨团队 / 租户隔离配置影响时(如多租户共享集群):选定向重新加载,通过双向标记避免误触。

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. 创建服务

image-20250523113745787

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
过程图
image-20250523114314611

🔔 重新加载时发出警报

每当触发工作负载的滚动升级(例如,等)时, 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"