checksum 触发滚动是什么
Deployment 只在 Pod 模板变化时才滚动更新,而 ConfigMap 与 Secret 的内容变化不属于模板变化,所以改了配置之后运行中的 Pod 不会有任何反应——以环境变量或 subPath 方式注入的配置更是连文件都不会更新,需要重启容器才生效。checksum 模式把配置内容的哈希写进 Pod 模板注解:配置一变哈希就变,模板跟着变,滚动更新被天然触发,无需人工干预。
基本信息
| 注解位置 | spec.template.metadata.annotations,必须在模板里才有效 |
|---|---|
| 常用键名 | checksum/config、checksum/secret 之类自定义键 |
| 触发原理 | 注解属于模板,模板哈希变化即触发滚动 |
| 配套字段 | 与 kubernetes.io/change-cause 注解配合可读性更好 |
| 适用对象 | ConfigMap、Secret 驱动的 Deployment、StatefulSet 等 |
| 环境要求 | 不依赖集群版本,任何支持 Deployment 的集群都可用 |
工具链原生写法
工具链原生写法
# Helm:把配置模板的渲染结果做哈希写进注解
spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
# Kustomize:configMapGenerator 生成带内容哈希后缀的名字
# 引用名随内容变化,模板随之变化,滚动更新自动触发手工脚本版
手工脚本版
HASH=$(kubectl get cm app-config -n prod -o yaml | sha256sum | cut -c1-16) # 配置内容哈希
printf '{"spec":{"template":{"metadata":{"annotations":{"checksum/config":"%s"}}}}}' \
"$HASH" > /tmp/patch.json
kubectl patch deploy web -n prod --patch-file /tmp/patch.json # 只改注解即触发滚动
kubectl rollout status deploy/web -n prod # 确认滚动完成
kubectl annotate deploy/web kubernetes.io/change-cause="配置更新 $HASH" # 补上变更说明几种做法对照
| 做法 | 原理 | 特点 |
|---|---|---|
| Helm 模板函数 | 渲染配置模板后取哈希写入注解 | 声明式,随发布自动计算 |
| Kustomize | configMapGenerator 生成带哈希后缀的名字 | 引用名变化即触发,无需额外注解 |
| 手工脚本 | 计算哈希后再 patch 注解 | 不依赖工具链,需自行保证算法一致 |
| rollout restart | 给模板加时间戳注解强制重启 | 与配置是否变化无关,属人工触发 |
典型使用场景
- 配置与镜像同批发布:流水线里改完 ConfigMap 直接滚动,不用额外人工步骤
- 避免手工重启:希望配置变更后自动生效,降低遗漏风险
- 多环境差异配置:各环境配置内容不同,哈希不同,发布互不影响
- 灰度与回滚:注解里能看出配置版本,回滚时配置与镜像一起回到对应状态
- Helm 或 Kustomize 用户:直接用工具链原生能力,不必自己维护脚本
哈希只用来判断「变了没有」,具体算法不重要,但同一条流水线里前后两侧必须一致;Helm 模板与手工脚本混用时尤其容易一边用 sha256 一边用 md5,导致该滚的时候不滚。
如果应用本身支持读取文件变更后热重载,也可以选择不用 checksum,改为以卷方式挂载并让应用监听文件变化;两种方式取舍在于是否允许运行中的实例继续用旧配置。