使用reloader实现CM热更新后自动重启POD

1.背景

在云原生环境中,配置管理通常通过ConfigMap和Secret对象来实现。尽管这些资源对象可以直接更新,但在更新ConfigMap或Secret时,挂载到Pod中的数据处理存在以下情况:

  • 环境变量挂载:通过Env方式挂载的环境变量在更新后不会自动同步。
  • 文件挂载:通过文件方式挂载的数据会同步更新,但可能存在秒级延时。

大多数情况下,当ConfigMap或Secret中的配置信息更新后,期望Pod内的应用能够及时读取到最新的值。通常的做法是手动触发Pod的滚动更新,以重新加载环境变量或文件内容。然而,当涉及到大量Pod时,这种手动操作变得繁琐且低效。
为了解决这一问题,社区开发了开源工具Reloader。Reloader能够在ConfigMap或Secret更新时,自动触发相关Pod的滚动更新。这一机制确保Pod能够及时应用新的配置,而无需手动干预,从而简化了运维操作,提高了效率。

2.Reloader简介

项目:https://github.com/stakater/Reloader
Reloader是一个开源的Kubernetes工具,专门用于监控ConfigMap和Secret的变化,并对相关的Pod及其关联的DeploymentConfigs、Deployments、Daemonsets、Statefulsets和Rollouts进行滚动升级。

2.1 原理

当Reloader检测到ConfigMap或Secret发生变化时,它会计算配置的SHA1哈希值(SHA1因其效率高且冲突少而被选择)。随后,Reloader会获取所有与此ConfigMap或Secret相关的Deployments、Daemonsets、Statefulsets和Rollouts,并检查这些资源的annotations中是否包含Reloader相关的注解。
这些注解通常指定一个特殊的环境变量。当Reloader找到这个环境变量时,它会获取其值,并将其与新的SHA1哈希值进行比较。如果哈希值不匹配,Reloader会更新这个环境变量的值。
如果环境变量不存在,Reloader会从ConfigMap中创建一个新的环境变量,赋予最新的哈希值,并更新相应的Deployment、Daemonset或Statefulset。
Kubernetes会检测到这个环境变量的变化,进而触发关联Pod的滚动升级。这样,即使在配置更新时,服务仍然可以继续运行,确保配置变更的无感知性。

3.Reloader部署

注:默认部署在default名称空间下

kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

4.使用方法

如果某deployment需要随着configmap的更新而自动重启pods
只需要添加注解reloader.stakater.com/auto: "true"即可:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  annotations:
    reloader.stakater.com/auto: "true" #添加注解
spec:
  replicas: 1

修改CM配置测试

[root@master01 nginx]# kubectl  apply  -f nginx-cm.yaml 
Warning: resource configmaps/nginx-default-cm is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
configmap/nginx-default-cm configured

查看pod可以看见已经触发 Pod 滚动更新

[root@master01 nginx]# kubectl get  pods

image.png

也可以指定对应的ConfigMap或Secret 的变动触发 Pod 滚动更新
在Deployment 的metadata.annotations中添加configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap",指定这些 ConfigMap 才会触发 Pod 的更新。多个 ConfigMap 使用逗号分隔

kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap"
spec:
  template: 
    metadata:

在Deployment 的metadata.annotations中添加secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret",指定这些 Secret 才会触发 Pod 的更新。多个 Secret 使用逗号分隔

kind: Deployment
metadata:
  annotations:
    secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret"
spec:
  template: 
    metadata:
posted @ 2024-07-24 14:40  &UnstopPable  阅读(18)  评论(0编辑  收藏  举报