用四个修订造出一段部署史
目标
亲手创建 install、upgrade、失败、rollback 共四个 revision,并确认 Helm 把这段历史以何种形式保存在 cluster 的什么位置。
为什么重要
Helm 3 没有常驻 cluster 的 server component。那么“这个 release 当前是第几版”保存在哪里?答案是 release 所在namespace 的 Secret。名称为 sh.helm.release.v1.<릴리스이름>.v<리비전>,类型为 helm.sh/release.v1,其中压缩保存 chart metadata、render 后 manifest、values 与状态。每个 revision 都新增一个 Secret,因此部署历史保留在 cluster 本身。必须亲身体会两点。第一,失败的 upgrade 也会留下 revision:状态记录为 failed,实际 resource 保持上一状态。第二,rollback 不是把编号倒退,而是创建新 revision:rollback 到 revision 2 时,编号不会回到 2,而会新增 revision 4。revision 永远只向前推进。
步骤
- 在
/root/helm/rel/lab-app创建 chart(helm create lab-app即可),安装到 namespacehelm-lab,release name 为lab-app:helm install lab-app /root/helm/rel/lab-app -n helm-lab --create-namespace --set replicaCount=1。这是revision 1。helm-lab中必须出现一个带app.kubernetes.io/managed-by=Helmlabel 的 Deployment。另请预先创建产物目录/root/helm/rel/out。 - 用
helm upgrade lab-app /root/helm/rel/lab-app -n helm-lab --set replicaCount=3创建revision 2。然后把该 revision 使用的 user values 保存到/root/helm/rel/out/rev2-values.json(helm get values lab-app -n helm-lab --revision 2 -o json)。文件必须是有效 JSON,且replicaCount为 3。 - 用
helm history lab-app -n helm-lab -o json > /root/helm/rel/out/history.json保存历史。至少有 2 个 revision;每项必须含chart、app_version、status,且至少一个 revision 状态为superseded。 - 故意执行一次能 render、但会被 API server 拒绝的 upgrade:
helm upgrade lab-app /root/helm/rel/lab-app -n helm-lab --set replicaCount=abc。replicas必须为整数,因此 manifest 会被拒绝。将包括标准错误在内的输出保存到/root/helm/rel/out/failed.txt(> /root/helm/rel/out/failed.txt 2>&1)。这是revision 3,状态保留为failed,实际 Deployment 的spec.replicas仍为 3。不要添加--atomic,否则会自动 rollback,无法观察失败 revision。 - 用
helm rollback lab-app 2 -n helm-lab恢复 revision 2 的状态。这是revision 4。history 最新 revision 编号必须至少为 4,description 中包含 rollback,状态为deployed,实际 Deployment 的spec.replicas为 3。 - 分别保存
helm get values lab-app -n helm-lab -a -o json > /root/helm/rel/out/all-values.json与helm get values lab-app -n helm-lab -o json > /root/helm/rel/out/user-values.json。all values 文件顶层 key 至少 3 个且包含image,user values 文件 key 数必须更少。 - 用
kubectl get secret -n helm-lab -l owner=helm检查 release Secret。数量应与 revision 相同(至少 4 个),类型为helm.sh/release.v1,名称格式为sh.helm.release.v1.lab-app.v<리비전>。在/root/helm/rel/out/storage-note.txt中用一两行记录结果,必须说明 release 状态存在哪个 namespace 的哪种 object 中。 - 创建
/root/helm/rel/out/report.json,含四个 key。revisions是每个 revision 含revision与status的数组,长度与实际 history 相同,且必须包含status为failed的项。current_revision为当前最新 revision 编号,rolled_back_to为2,deployed_replicas为当前 Deployment 的spec.replicas。
参考
- 每个实验会启动新 Pod,其他实验的 chart 或 release 不会保留。chart 与 namespace 都要从头创建,这体现 chart 是可复现 package。
helm history、helm get values、helm status都必须用-n指定 namespace。Helm 按 namespace 记忆 release。- 添加
-a(--all)时返回合并 chart 默认值后的最终 values;不添加时只返回用户实际传入的 values。故障排查中可据此区分默认值与人工设置值。 - 默认保留 10 个 revision,可用
--history-max调整,因此 Secret 不会无限堆积。 - 常见错误 1:第 4 步保存时遗漏
2>&1,导致文件为空。失败消息写到标准错误。 - 常见错误 2:以为 rollback 后 revision 编号会回到 2。rollback 会根据 revision 2 的 chart 与 values 创建一个新 revision。
首次安装并创建 revision 1
在 /root/helm/rel/lab-app 创建 chart(helm create lab-app 即可),安装到 namespace helm-lab,release name 为 lab-app:helm install lab-app /root/helm/rel/lab-app -n helm-lab --create-namespace --set replicaCount=1。这是revision 1。helm-lab 中必须出现一个带 app.kubernetes.io/managed-by=Helm label 的 Deployment。另请预先创建产物目录 /root/helm/rel/out。
release 按 namespace 记忆。安装到不存在的 namespace 时,可以预先创建,也可以通过安装选项同时创建。replica 数从 1 开始。
通过 upgrade 创建 revision 2
用 helm upgrade lab-app /root/helm/rel/lab-app -n helm-lab --set replicaCount=3 创建revision 2。然后把该 revision 使用的 user values 保存到 /root/helm/rel/out/rev2-values.json(helm get values lab-app -n helm-lab --revision 2 -o json)。文件必须是有效 JSON,且 replicaCount 为 3。
只改变一个 value 后重新部署,再把该 revision 使用的 user values 以 JSON 保存。需要使用指定 revision 的选项。
以 JSON 保存 release history
用 helm history lab-app -n helm-lab -o json > /root/helm/rel/out/history.json 保存历史。至少有 2 个 revision;每项必须含 chart、app_version、status,且至少一个 revision 状态为 superseded。
history 中每个 revision 都包含状态与 chart 信息。请观察新 revision 出现后,上一 revision 的状态变为什么。
制造失败的 upgrade
故意执行一次能 render、但会被 API server 拒绝的 upgrade:helm upgrade lab-app /root/helm/rel/lab-app -n helm-lab --set replicaCount=abc。replicas 必须为整数,因此 manifest 会被拒绝。将包括标准错误在内的输出保存到 /root/helm/rel/out/failed.txt(> /root/helm/rel/out/failed.txt 2>&1)。这是revision 3,状态保留为 failed,实际 Deployment 的 spec.replicas 仍为 3。不要添加 --atomic,否则会自动 rollback,无法观察失败 revision。
填入能 render 但会被 API server 拒绝的值,例如在 replica 数位置填入非整数。错误写到标准错误,保存时必须一并捕获。
Rollback 到 revision 2
用 helm rollback lab-app 2 -n helm-lab 恢复 revision 2 的状态。这是revision 4。history 最新 revision 编号必须至少为 4,description 中包含 rollback,状态为 deployed,实际 Deployment 的 spec.replicas 为 3。
rollback 不是倒退编号,而是创建新 revision。rollback 后同时检查 history 最新编号与实际部署的 replica 数。
比较 user values 与 all values
分别保存 helm get values lab-app -n helm-lab -a -o json > /root/helm/rel/out/all-values.json 与 helm get values lab-app -n helm-lab -o json > /root/helm/rel/out/user-values.json。all values 文件顶层 key 至少 3 个且包含 image,user values 文件 key 数必须更少。
在同一命令上增加一个选项,即可取得合并 chart 默认值后的结果。两个结果的 key 数不同才正常。
确认 release 保存位置
用 kubectl get secret -n helm-lab -l owner=helm 检查 release Secret。数量应与 revision 相同(至少 4 个),类型为 helm.sh/release.v1,名称格式为 sh.helm.release.v1.lab-app.v<리비전>。在 /root/helm/rel/out/storage-note.txt 中用一两行记录结果,必须说明 release 状态存在哪个 namespace 的哪种 object 中。
Helm 3 没有常驻 cluster 的 server,那么状态存在哪里?按 label 筛选后,会看到与 revision 数相同的 object。
创建生命周期报告
创建 /root/helm/rel/out/report.json,含四个 key。revisions 是每个 revision 含 revision 与 status 的数组,长度与实际 history 相同,且必须包含 status 为 failed 的项。current_revision 为当前最新 revision 编号,rolled_back_to 为 2,deployed_replicas 为当前 Deployment 的 spec.replicas。
从 history 与实际部署状态提取数字并整理为 JSON。不能遗漏失败 revision,数字应从命令输出读取而非手写。