3. Helm 发布流程详解:install、upgrade、rollback 底层原理与工作流

Helm 作为 Kubernetes 的包管理工具,其核心价值在于将复杂的应用发布抽象为三个原子操作:安装(install)、升级(upgrade) 和 回滚(rollback)。理解这三个命令的底层工作流,是设计可靠回滚策略的前提。本章将深入剖析每个命令的执行阶段、状态机转换以及 Helm 如何通过 Release 对象管理应用的生命周期。

3.1 Helm Release 与 Revision 机制

在深入命令之前,必须先理解 Helm 的两个核心概念:Release 和 Revision。

  • Release:一次部署的实例。每个 Release 都有一个唯一的名称,关联一组 Kubernetes 资源。
  • Revision:Release 的版本号。每次 install、upgrade、rollback 或 uninstall 操作都会生成一个新的 Revision。Revision 从 1 开始递增,永不回退。

Helm 将 Release 的历史记录存储在 Kubernetes 的 Secret 资源中(默认命名空间为 kube-system 或 Release 所在命名空间)。每个 Secret 包含完整的 Chart 模板、Values 值以及生成的 Kubernetes 资源清单。

关键认知: Helm 的回滚本质上是“重新应用”历史 Revision 中的资源清单,而不是执行“反向操作”。这意味着回滚会覆盖当前集群状态,使其与历史 Revision 完全一致。

3.2 helm install:创建 Release 与 Revision 1

helm install 是发布流程的起点。其工作流分为三个阶段:渲染、验证、应用。

3.2.1 执行流程

  1. 加载 Chart:从本地路径或仓库加载 Chart 包,解析 Chart.yaml、values.yaml 及模板文件。
  2. 值合并:按照优先级合并 Values:内置默认值 < 用户提供的 values.yaml < --set 参数。
  3. 模板渲染:使用 Go 模板引擎,将合并后的 Values 注入到模板文件中,生成完整的 Kubernetes 资源 YAML 清单。
  4. 验证:对渲染后的 YAML 进行语法校验和 Schema 验证(如果 Chart 提供了 values.schema.json)。
  5. 创建 Release 记录:在 Kubernetes 中创建 Secret,记录 Revision 1 的元数据和渲染结果。
  6. 应用资源:通过 Kubernetes API 按顺序创建资源(通常先创建 Namespace、ConfigMap、Secret,再创建 Deployment、Service)。
  7. 状态更新:将 Release 状态标记为 deployed。
注意: 如果安装过程中任何一步失败,Helm 会尝试清理已创建的资源(除非指定了 --atomic 或 --wait 且超时),并将 Release 状态标记为 failed。

3.2.2 状态机转换

阶段 状态 说明
开始 pending-install Helm 正在执行安装流程
成功 deployed 所有资源已成功创建
失败 failed 安装过程中发生错误,资源可能部分创建
helm install 工作流 加载 Chart 值合并 模板渲染 验证 创建 Release 记录 应用资源 状态更新 关键点: • 安装失败时,Helm 默认会回滚已创建的资源(非原子操作)。 • 使用 --atomic 标志可确保安装失败时自动清理所有资源。

3.3 helm upgrade:创建新 Revision 并应用变更

helm upgrade 是发布流水线中最常用的命令。它不会直接修改现有资源,而是创建一个新的 Revision(Revision N+1),然后通过 diff 算法计算变更并应用。

3.3.1 执行流程

  1. 加载当前 Release:从 Kubernetes 中获取当前 Release 的最新 Revision 记录。
  2. 渲染新版本:使用新的 Values 重新渲染 Chart 模板,生成新的资源清单。
  3. 计算 Diff:对比当前 Revision 的资源清单与新渲染的资源清单,生成增、删、改的变更集。
  4. 创建新 Revision:在 Kubernetes 中创建新的 Secret,记录 Revision N+1 的元数据和渲染结果。
  5. 应用变更:通过 Kubernetes API 执行变更集。对于 Deployment,会触发滚动更新;对于 ConfigMap/Secret,需要手动触发 Pod 重启。
  6. 状态更新:将新 Revision 标记为 deployed,旧 Revision 标记为 superseded。
常见陷阱: 如果升级过程中发生错误,Helm 默认不会自动回滚到上一个 Revision。资源可能处于部分更新的不一致状态。此时需要手动执行 helm rollback 或使用 --atomic 标志让 Helm 自动处理。

3.3.2 升级策略对比

策略 描述 适用场景
默认 直接应用变更,不等待 Pod 就绪 快速迭代,可接受短暂中断
--wait 等待所有 Pod 进入 Ready 状态,超时则失败 生产环境,需要确保服务可用性
--atomic 升级失败时自动回滚到上一个 Revision 关键业务,需要保证发布一致性
--cleanup-on-fail 升级失败时清理新创建的资源 避免残留资源占用集群

3.4 helm rollback:回到历史 Revision

helm rollback 是回滚策略的核心执行者。它不会删除当前 Revision,而是基于历史 Revision 创建一个新的 Revision(Revision N+1),并将集群状态恢复到历史时刻。

3.4.1 执行流程

  1. 查找目标 Revision:根据用户指定的 Revision 编号,从 Kubernetes Secret 中读取对应的历史资源清单。
  2. 渲染目标版本:使用目标 Revision 中存储的 Values 重新渲染 Chart 模板(确保与历史状态一致)。
  3. 计算 Diff:对比当前 Revision 的资源清单与目标 Revision 的资源清单,生成回滚变更集。
  4. 创建新 Revision:在 Kubernetes 中创建新的 Secret,记录 Revision N+1(回滚后的版本),元数据中标记 rollback 操作。
  5. 应用回滚变更:通过 Kubernetes API 执行变更集,将集群状态恢复到目标 Revision 的状态。
  6. 状态更新:将新 Revision 标记为 deployed,当前 Revision 标记为 superseded,目标 Revision 保持 superseded。
重要: 回滚后,Revision 编号会继续递增。例如,当前是 Revision 5,回滚到 Revision 3 后,会生成 Revision 6。Revision 3 仍然是 superseded 状态,Revision 6 成为新的 deployed 状态。
helm rollback 工作流 查找目标 Revision 渲染目标版本 计算 Diff 创建新 Revision 应用回滚变更 状态更新 Revision 状态转换示例: 初始状态:Revision 3 (superseded) → Revision 4 (superseded) → Revision 5 (deployed) 执行 rollback 到 Revision 3: 结果:Revision 3 (superseded) → Revision 4 (superseded) → Revision 5 (superseded) → Revision 6 (deployed) Revision 6 的内容与 Revision 3 完全一致,但编号不同。

3.5 三个命令的底层原理对比

特性 helm install helm upgrade helm rollback
创建 Revision 是(Revision 1) 是(Revision N+1) 是(Revision N+1)
资源操作 创建全部资源 增、删、改资源 恢复到历史资源状态
Values 来源 用户提供 用户提供(可部分覆盖) 历史 Revision 中存储的 Values
失败处理 默认清理已创建资源 默认不清理,资源可能不一致 默认不清理,资源可能不一致
原子性支持 --atomic --atomic --atomic
状态标记 deployed / failed deployed / superseded deployed / superseded

3.6 关键设计原则

  • Revision 不可变:一旦创建,Revision 的内容(资源清单、Values)不可修改。这是回滚可靠性的基础。
  • 回滚是正向操作:回滚不是“撤销”,而是“重新应用历史状态”。因此,回滚后可以再次回滚到其他 Revision。
  • Secret 存储限制:默认情况下,Helm 保留最近 10 个 Revision(可通过 --history-max 配置)。超过限制的 Revision 会被自动清理。
  • 资源依赖:Helm 不处理资源间的依赖顺序(如 Service 必须在 Deployment 之前创建)。这需要 Chart 开发者通过模板顺序或 Helm Hooks 来保证。
实践建议: 在生产流水线中,始终使用 --atomic --wait --timeout 5m 组合参数执行 helm upgrade。这样可以在升级失败时自动回滚,避免集群进入不一致状态。