LabHub
学习 学习路径 课程

Helm 发布与回滚

把 release 打开看看 — 存在哪、保留窗口、复活

在 LabHub 中继续学习

目标

亲手解开 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 下。

步骤

  1. /root/hs-rel 创建 chart,安装到 rel-a,并使用名称 shop
  2. 解开 revision 1 的 release Secret,保存到 /root/hs-rel/out/release-v1.json
  3. 使用相同名称 shop,也安装到 rel-b
  4. 使用 --history-max 3 upgrade 四次,观察旧 revision 消失。
  5. helm get valueshelm get manifest 结果保存到 /root/hs-rel/out
  6. 删除 rel-b 的 release,使用 --keep-history 保存记录。
  7. 通过 rollback 恢复已删除的 release。
  8. /root/hs-rel/out/report.txt 中用七行总结。

参考

创建 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-ashop 添加 --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-akubectl -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 -ahelm 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-bshop 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_TOTALSTORAGEHISTORY_MAXREL_A_KEPTREL_A_LATESTRESOURCE_PREFIXSCOPE

不要猜测,请从 cluster 统计。用 helm list -A -a 查看 shop 数量,用 helm history shop -n rel-a 查看保留 revision 数及最大编号。STORAGE 用一个词写 Helm 3 把 release 存在哪里;SCOPE 用一个词说明 release name 的唯一范围;RESOURCE_PREFIX 填第 1 步看到的 Deployment 名称。