1. Helm 架构总览:控制平面与资源模型
Helm v3 是 Kubernetes 生态中最流行的包管理工具,其架构设计在 v3 版本中经历了重大变革——Tiller 的移除彻底改变了控制平面的交互方式。本章从架构核心组件、控制平面与数据平面分离设计、以及资源模型(Chart、Release、Revision)三个维度,建立 Helm 故障排查的知识地基。
1.1 Helm v3 架构核心组件:Tiller 移除后的变化
Helm v2 时代,集群内运行着一个名为 Tiller 的服务端组件,它拥有集群管理权限,负责接收 Helm 客户端请求并执行安装、升级、删除等操作。这种设计带来了严重的安全隐患:Tiller 的权限过大,且缺乏细粒度的访问控制。
Helm v3 彻底移除了 Tiller,将控制逻辑全部迁移到客户端(CLI)和 Kubernetes API Server 之间直接交互。这一变化带来了以下核心优势:
- 安全性提升:不再需要在集群内部署一个拥有高权限的服务端组件,权限控制回归到 Kubernetes RBAC 体系。
- 架构简化:减少了集群内的组件数量,降低了运维复杂度和故障点。
- 操作原子性:所有操作直接通过 Kubernetes API 完成,不再依赖 Tiller 的状态管理。
| 对比维度 | Helm v2(含 Tiller) | Helm v3(无 Tiller) |
|---|---|---|
| 服务端组件 | Tiller(集群内 Deployment) | 无(直接调用 API Server) |
| 权限模型 | Tiller 拥有集群级权限 | 使用 kubeconfig 中的用户/ServiceAccount 权限 |
| Release 信息存储 | ConfigMap(默认命名空间) | Secret(Release 所在命名空间) |
| 安全风险 | 高(Tiller 成为攻击目标) | 低(遵循 Kubernetes RBAC) |
| 故障排查复杂度 | 需排查 Tiller 日志 + 客户端日志 | 只需排查客户端日志 + API Server 审计日志 |
forbidden: User "xxx" cannot create resource "secrets"),应优先检查 kubeconfig 中使用的用户或 ServiceAccount 是否具备对应命名空间下的 Secret 读写权限,而非怀疑 Tiller 组件。
1.2 控制平面与数据平面分离设计
Helm v3 的架构遵循了清晰的控制平面与数据平面分离原则。理解这一设计有助于在故障发生时快速定位问题边界。
- 控制平面:由 Helm CLI 客户端和 Kubernetes API Server 组成。CLI 负责解析 Chart、渲染模板、构建期望状态;API Server 负责接收请求、执行 RBAC 鉴权、持久化 Release 元数据。
- 数据平面:由 Kubernetes 集群内的实际工作负载(Pod、Service、Deployment 等)以及 Helm 用于存储 Release 信息的 Secret 资源组成。
这种分离设计的核心价值在于:控制平面的故障(如模板渲染错误、API 连接超时)不会直接影响数据平面中已运行的资源;反之,数据平面的故障(如 Pod CrashLoopBackOff)也不会阻塞控制平面执行新的 Release 操作。
helm install 返回超时错误,应检查控制平面(CLI 到 API Server 的网络);如果安装成功但 Pod 一直处于 Pending 状态,则属于数据平面问题(资源不足或调度失败)。
1.3 资源模型基础概念:Chart、Release、Revision
Helm 的资源模型是故障排查的核心线索。三个关键概念——Chart、Release、Revision——构成了 Helm 对 Kubernetes 资源进行生命周期管理的抽象层。
1.3.1 Chart:应用的打包定义
Chart 是 Helm 的打包格式,本质上是一个遵循特定目录结构的文件集合。它包含了部署一个应用所需的所有 Kubernetes 资源模板、默认配置值、依赖声明以及元数据。
my-chart/
├── Chart.yaml # 元数据:名称、版本、描述、API 版本
├── values.yaml # 默认配置值
├── values.schema.json # (可选)values 的 JSON Schema 校验
├── charts/ # (可选)子 Chart 依赖
├── templates/ # Go 模板文件,渲染后生成 Kubernetes 资源
│ ├── deployment.yaml
│ ├── service.yaml
│ └── _helpers.tpl # 模板辅助函数
└── README.md
在故障排查中,Chart 的 Chart.yaml 中的 apiVersion 字段决定了 Helm 的行为模式:v1 为旧版(Helm 2 兼容),v2 为当前推荐版本。错误的 apiVersion 可能导致模板渲染失败。
1.3.2 Release:Chart 的运行实例
Release 是 Chart 在特定命名空间下的一次具体部署实例。每次执行 helm install 都会创建一个新的 Release。Release 的名称在命名空间内必须唯一。
Release 的元数据(名称、Chart 版本、Values、Manifest 等)以 Secret 资源的形式存储在目标命名空间中,Secret 的名称格式为 sh.helm.release.v1.<release-name>.v<revision>。
helm list 无法显示,但 Kubernetes 资源仍在运行。此时需使用 helm list -a 查看所有 Release(包括标记为删除的),或通过 kubectl get secret -n <namespace> | grep sh.helm.release 手动恢复。
1.3.3 Revision:Release 的版本历史
每次对 Release 执行 helm upgrade 或 helm rollback 操作,都会生成一个新的 Revision。Revision 是一个递增的整数,从 1 开始。Helm 会保留最近的 N 个 Revision(默认 10 个),用于回滚操作。
| 操作 | Revision 变化 | Secret 变化 | 故障排查关注点 |
|---|---|---|---|
helm install |
创建 Revision 1 | 创建 Secret v1 | 检查 Secret 是否创建成功 |
helm upgrade |
创建 Revision 2 | 创建 Secret v2,保留 v1 | 比较 v1 和 v2 的 Manifest 差异 |
helm rollback |
创建 Revision 3(回滚到 v1) | 创建 Secret v3(内容与 v1 相同) | 确认回滚后的 Manifest 是否与预期一致 |
helm uninstall |
标记为删除,保留 Revision | Secret 添加删除标记 | 检查 Secret 的 status 字段 |
1.4 资源模型协同:故障排查中的关键路径
理解 Chart、Release、Revision 三者之间的协同关系,是定位 Helm 故障的核心能力。以下是一个典型的故障排查路径:
- 确认 Release 状态:使用
helm list -n <namespace> -a查看所有 Release,确认目标 Release 是否存在、状态是否为deployed、failed或pending-upgrade。 - 检查 Revision 历史:使用
helm history <release> -n <namespace>查看每个 Revision 的 Chart 版本、App 版本、状态和描述信息。重点关注failed或superseded状态的 Revision。 - 对比 Manifest 差异:使用
helm get manifest <release> --revision <N> -n <namespace>获取指定 Revision 的渲染后 Manifest,与当前集群中的实际资源进行对比。 - 检查 Values 注入:使用
helm get values <release> --revision <N> -n <namespace>查看该 Revision 使用的 Values,确认配置是否正确注入。 - 验证 Chart 完整性:如果怀疑 Chart 本身有问题,使用
helm lint <chart-path>检查 Chart 结构,或使用helm template <release> <chart> --values <values>在本地渲染模板,验证输出是否符合预期。
helm history my-app -n production 发现 Revision 3 状态为 failed,但 Revision 2 为 deployed。执行 helm get manifest my-app --revision 2 -n production 获取正常版本的 Manifest,与当前集群资源对比,发现 Revision 3 错误地修改了 Service 的端口映射。回滚到 Revision 2 后服务恢复。