3. 资源模型详解:Release 对象在 Kubernetes 中的存储机制

Helm 的 Release 对象是 Helm 控制平面与 Kubernetes 资源模型交互的核心载体。理解 Release 在 Kubernetes 中的存储机制、Revision 版本管理原理以及 Rollback 回滚的底层实现,是进行 Helm 故障排查的必备知识。本章将深入剖析这三个关键环节。

3.1 Release 对象的存储机制:Secrets vs ConfigMaps

Helm 默认使用 Secrets 来存储 Release 对象,但早期版本(Helm 2)及部分自定义配置中可能使用 ConfigMaps。两者在存储内容、安全性和生命周期管理上存在显著差异。

特性 Secrets(默认) ConfigMaps(可选)
数据编码 Base64 编码(非加密,仅混淆) 明文存储
存储位置 Kubernetes Secrets API Kubernetes ConfigMaps API
默认启用 Helm 3 默认 需通过 --store 或环境变量启用
敏感信息 适合存储密码、 等(但 Helm 不加密) 不适合存储敏感数据
大小限制 1MB(etcd 默认限制) 1MB(etcd 默认限制)
审计与 RBAC 支持更严格的 RBAC 控制 RBAC 控制相对宽松
Helm 版本 Helm 3 默认,Helm 2 需手动指定 Helm 2 默认,Helm 3 可选
关键提示: Helm 3 默认使用 Secrets 存储 Release 对象,但 Secrets 仅对数据进行 Base64 编码,并非加密。对于生产环境,建议启用 etcd 加密或使用外部密钥管理服务(KMS)对 Secrets 进行静态加密。

Release 对象在 Kubernetes 中的命名格式为:sh.helm.release.v1.<release-name>.v<revision>。每个 Release 的每个 Revision 对应一个独立的 Secret 或 ConfigMap 资源。

# 查看指定 Release 的所有 Revision 对应的 Secret
kubectl get secret -n <namespace> | grep "sh.helm.release.v1.<release-name>"

# 示例输出
sh.helm.release.v1.my-app.v1   Opaque   1   10d
sh.helm.release.v1.my-app.v2   Opaque   1   5d
sh.helm.release.v1.my-app.v3   Opaque   1   1d

3.2 Revision 版本管理原理

Helm 的 Revision 机制是版本控制和回滚的基础。每次执行 helm upgrade、helm install 或 helm rollback 操作,都会生成一个新的 Revision。

3.2.1 Revision 的生命周期

  1. 创建(Install):首次安装时生成 Revision 1。
  2. 更新(Upgrade):每次 helm upgrade 递增 Revision 号(如 v1 → v2)。
  3. 回滚(Rollback):执行 helm rollback 时,会基于目标 Revision 生成一个新的 Revision(如从 v3 回滚到 v1,实际生成 v4,其内容与 v1 相同)。
  4. 删除(Uninstall):删除 Release 时,默认保留历史 Revision 的 Secret(可通过 --keep-history 控制)。
Revision 递增规则: Helm 使用单调递增的整数作为 Revision 号,不会复用已删除的 Revision 号。即使删除 Release 后重新安装,Revision 也会从 1 重新开始。

3.2.2 Revision 存储结构

每个 Revision 的 Secret 中存储了完整的 Release 对象,包括 Chart 模板渲染后的所有 Kubernetes 资源清单(Manifest)、Values 值、Chart 元数据等。其数据结构如下:

# 查看某个 Revision 的 Secret 内容(Base64 解码后)
kubectl get secret sh.helm.release.v1.my-app.v1 -n <namespace> -o jsonpath='{.data.release}' | base64 -d | base64 -d | gunzip

# 解码后的 JSON 结构(简化)
{
  "name": "my-app",
  "info": {
    "status": "deployed",
    "first_deployed": "2024-01-01T00:00:00Z",
    "last_deployed": "2024-01-10T00:00:00Z",
    "deleted": ""
  },
  "chart": {
    "metadata": { ... },
    "templates": [ ... ],
    "values": { ... }
  },
  "config": { ... },
  "manifest": "---\napiVersion: v1\nkind: Service\n...",
  "version": 1,
  "namespace": "default"
}
注意: Release 对象在存储时经过了 两次 Base64 编码 + Gzip 压缩。直接使用 kubectl get secret 看到的是经过双重编码的数据,需要逐层解码才能查看原始内容。

3.3 Rollback 回滚的底层实现

Helm 的 Rollback 操作并非简单地“切换”到历史 Revision,而是通过创建一个新的 Revision 来“重现”历史状态。这种设计保证了 Revision 历史的完整性和可追溯性。

3.3.1 Rollback 执行流程

  1. 读取目标 Revision:Helm 从 Kubernetes 中读取指定 Revision 的 Secret(如 v1)。
  2. 生成新 Revision:基于目标 Revision 的 Manifest 和 Values,生成一个新的 Release 对象,Revision 号为当前最大 Revision + 1(如 v4)。
  3. 应用 Manifest:将新 Revision 中的 Manifest 应用到 Kubernetes 集群(等同于执行 kubectl apply)。
  4. 更新状态:将新 Revision 的 Secret 写入集群,并将旧 Revision(如 v3)的状态标记为 superseded。
Helm Rollback 底层实现流程 用户执行 helm rollback 读取目标 Revision Secret(如 v1) 生成新 Revision(v4 = v1 内容) 应用 Manifest 到集群 更新状态:v4=deployed, v3=superseded 关键特性 • 不修改历史 Revision • 创建新 Revision 重现历史 • 保证 Revision 历史完整 • 支持回滚到任意历史版本

3.3.2 Rollback 与 Upgrade 的本质区别

操作 Revision 变化 Manifest 来源 状态变更
Upgrade vN → vN+1 当前 Chart + 新 Values 旧 Revision → superseded,新 Revision → deployed
Rollback vN → vN+1 目标历史 Revision 的 Manifest 旧 Revision → superseded,新 Revision → deployed
故障排查要点: 当 Rollback 失败时,应检查:
1. 目标 Revision 的 Secret 是否存在且未被损坏。
2. 目标 Revision 中的 Manifest 是否引用了已删除的 CRD 或 API 版本。
3. 集群资源配额是否足够(Rollback 会重新创建所有资源)。
4. 是否存在资源冲突(如 Namespace 已被删除)。

3.4 存储机制与故障排查的关联

理解 Release 对象的存储机制对于故障排查至关重要。以下是一些常见场景:

  • Secret 损坏或丢失:如果某个 Revision 的 Secret 被意外删除,将无法回滚到该版本。建议启用 --history-max 限制历史 Revision 数量,避免 Secret 过多。
  • 存储后端切换:从 ConfigMaps 切换到 Secrets(或反之)时,Helm 不会自动迁移已有 Release 对象。需要手动处理或使用 helm migrate 工具。
  • etcd 存储压力:大量历史 Revision 会占用 etcd 存储空间。建议根据实际需求设置 --history-max(默认 10)。
# 设置最大历史 Revision 数量为 5
helm upgrade my-app ./chart --history-max 5

# 查看当前 Release 的历史 Revision 数量
helm history my-app -n <namespace>
生产环境建议:
1. 始终使用 Secrets 存储 Release 对象(Helm 3 默认)。
2. 启用 etcd 静态加密或 KMS 加密保护敏感数据。
3. 定期清理不需要的历史 Revision(使用 --history-max 或手动删除 Secret)。
4. 在 CI/CD 流程中,避免频繁执行 helm upgrade 导致 Revision 数量激增。