把 release 打开看看 — 存在哪、保留窗口、复活
目标
亲手解开 Helm release 在 cluster 中以什么形式保存在哪里,并走完整个流程:观察保留窗口有多窄,以及如何恢复已删除的 release。
为什么重要
helm rollback 能恢复什么、不能恢复什么,都源于 storage 结构。release 是 namespace 中的一条 Secret,其中压缩保存了完整的 render manifest。因此,manifest 中写过的内容可以恢复,而发生在其外部的事情无法恢复。
同一结构还带来两个结论:release name 只需在namespace 内唯一,并且保留的 revision 数量有上限。这就是“rollback 到半年前”通常不可能的原因。事故发生时先用 helm get values 确认“当时使用了哪些值”的习惯,也需要理解该结构才能真正养成。
环境
此 Pod 通过 kwok 启动真实 kube-apiserver。Pod 不会真正运行,但 release Secret、revision 与 object 变更都是真实的,因此评分器会重新询问 helm 与 apiserver,而不是检查文件。工作目录为 /root/hs-rel,产物放在 /root/hs-rel/out 下。
步骤
- 在
/root/hs-rel创建 chart,安装到rel-a,并使用名称shop。 - 解开 revision 1 的 release Secret,保存到
/root/hs-rel/out/release-v1.json。 - 使用相同名称
shop,也安装到rel-b。 - 使用
--history-max 3upgrade 四次,观察旧 revision 消失。 - 将
helm get values与helm get manifest结果保存到/root/hs-rel/out。 - 删除
rel-b的 release,使用--keep-history保存记录。 - 通过 rollback 恢复已删除的 release。
- 在
/root/hs-rel/out/report.txt中用七行总结。
参考
- 解开 Secret 时,
base64 -d要执行两次:Kubernetes 编码一层,helm 又编码一层。 helm list默认只显示deployed。查看已删除或卡住的内容时要添加-a。- 常见错误是第 6 步遗漏
--keep-history,导致第 7 步没有可恢复内容。 - 另一个错误是在第 5 步添加
--all,这样会混入 chart 默认值,无法判断“人工传入了什么”。
创建 chart、命名并部署
在 /root/hs-rel 中通过 helm create webapp 创建 chart,安装到 namespace rel-a,并使用名称 shop。使用 --create-namespace 同时创建 namespace。
命令格式为 helm install <릴리스이름> <차트경로> -n <네임스페이스> --create-namespace。安装后用 kubectl -n rel-a get deploy 检查创建的 Deployment 名称。名称前缀来自 release name,而不是 chart 自己指定的名称。此 cluster 使用 kwok,Pod 不会真正运行,但 release 与 object 都是真实的。
解开保存 release 的 Secret
从 rel-a 的 helm release Secret 中选择 revision 1,解开内容,并将完整 release JSON 保存到 /root/hs-rel/out/release-v1.json。
使用 kubectl -n rel-a get secret -l owner=helm,name=shop 确认名称。通过 -o jsonpath='{.data.release}' 取值后,执行两次 base64 -d 再执行 gzip -d,即可得到 release JSON。Kubernetes 编码一层,helm 又编码一层。render 后 YAML 以字符串保存在 JSON 的 .manifest 字段中;本步骤要保存完整 JSON。
在另一个 namespace 再创建同名 release
把同一个 chart 也安装到 namespace rel-b,并使用名称 shop。两个 release 必须互不冲突、分别存在。
release name 不是 cluster-wide,而只需在 namespace 内唯一,因为记录保存在该 namespace 的 Secret 中。用 helm list -A 查看全部 release,并用 kubectl -n rel-b get secret -l owner=helm 确认记录生成位置。
缩小保留窗口,观察旧 revision 消失
为 rel-a 的 shop 添加 --history-max 3,连续 upgrade 四次。最后一次 upgrade 的 replicaCount 必须为 5。
以 replicaCount 2、3、4、5 依次执行 helm upgrade shop ./webapp -n rel-a --set replicaCount=<값> --history-max 3。随后并排查看 helm history shop -n rel-a 与 kubectl -n rel-a get secret -l owner=helm,name=shop。revision 编号升到 5,但只保留三项;这说明可 rollback 的窗口比想象中窄。
提取 release 实际使用的 values 与 manifest
将 helm get values 的 JSON 结果保存到 /root/hs-rel/out/values.json,将 helm get manifest 结果保存到 /root/hs-rel/out/manifest.yaml。values 文件只能包含用户传入的值。
helm get values shop -n rel-a -o json 只显示用户传入值;添加 --all 后会连 chart 默认值一起显示。事故调查首先应看前者。helm get manifest 是 release 实际应用的 YAML,其中 replicas 应与 kubectl get deploy 查询结果一致。
保留记录后删除
删除 rel-b 中的 shop,使用 --keep-history,并把 helm list -n rel-b -a 与 helm history shop -n rel-b 的输出一同保存到 /root/hs-rel/out/uninstalled.txt。
执行 helm uninstall shop -n rel-b --keep-history。若直接 helm uninstall,release Secret 也会消失,无法恢复。删除后 helm list -n rel-b 不显示任何内容,添加 -a 后会看到 uninstalled 状态。请亲眼确认 helm list 默认隐藏已删除 release。
恢复已删除的 release
将 rel-b 的 shop rollback 到 revision 1 以恢复。恢复后,uninstalled revision 仍必须保留在 history 中。
执行 helm rollback shop 1 -n rel-b。因为保留了 history,无需重新 install 即可恢复。若重新执行 helm install,history 会从 revision 1 重新开始,事故记录随之消失。rollback 后,helm history 会在 uninstalled revision 上方新增写有 'Rollback to 1' 的 revision。
用数字总结七个步骤
在 /root/hs-rel/out/report.txt 中写七行:RELEASES_TOTAL、STORAGE、HISTORY_MAX、REL_A_KEPT、REL_A_LATEST、RESOURCE_PREFIX、SCOPE。
不要猜测,请从 cluster 统计。用 helm list -A -a 查看 shop 数量,用 helm history shop -n rel-a 查看保留 revision 数及最大编号。STORAGE 用一个词写 Helm 3 把 release 存在哪里;SCOPE 用一个词说明 release name 的唯一范围;RESOURCE_PREFIX 填第 1 步看到的 Deployment 名称。