2. Helm架构详解:Tiller架构(v2)与客户端-插件架构(v3)的演进、Helm与Kubernetes API交互原理
Helm 的架构演进是理解其与 Kubernetes 控制平面集成方式的关键。从 v2 到 v3 的转变,不仅仅是组件的增减,更是对安全性、架构简洁性以及 Kubernetes 原生生态的深度拥抱。本章将详细拆解两种架构的核心差异,并深入 Helm 与 Kubernetes API 的交互原理。
2.1 Helm v2:Tiller 架构
Helm v2 采用典型的 客户端-服务端 架构。客户端是 helm CLI,服务端是部署在集群内的 Tiller 组件。Tiller 拥有对 Kubernetes API 的完全访问权限,负责处理所有 Chart 的安装、升级和删除操作。
核心特征: Tiller 作为集群内的特权服务端,持有服务账号(ServiceAccount)和 RBAC 权限,直接与 API Server 通信。
2.1.1 Tiller 架构工作流程
- 用户执行命令: 用户通过
helm install命令将 Chart 包和自定义 values 发送给 Tiller。 - Tiller 接收请求: Tiller 在集群内监听 gRPC 端口(默认 44134),接收来自客户端的请求。
- 渲染模板: Tiller 将 Chart 模板与 values 文件合并,渲染出完整的 Kubernetes 资源清单(YAML)。
- 调用 API Server: Tiller 使用其绑定的服务账号,通过 Kubernetes API 将渲染后的资源清单提交到 API Server。
- 存储 Release 记录: Tiller 将 Release 的元数据(包括配置、状态、Manifest)存储在 Kubernetes 的 ConfigMap 或 Secrets 中(位于 Tiller 所在的命名空间)。
安全风险: Tiller 拥有集群级或命名空间级的超级权限。一旦 Tiller 被攻破,攻击者可以控制整个集群。此外,Tiller 默认监听端口未加密,存在中间人攻击风险。
2.1.2 Tiller 架构示意图
2.2 Helm v3:客户端-插件架构
Helm v3 彻底移除了 Tiller,回归到纯粹的 客户端-插件 架构。客户端 helm CLI 直接使用用户的 kubeconfig 文件中的凭据和上下文,通过 Kubernetes API 与 API Server 交互。这消除了集群内的特权服务端,将权限控制交还给 Kubernetes 原生的 RBAC。
架构哲学: “以客户端为中心,以 Kubernetes 原生权限为基础”。Helm v3 不再是一个独立的服务端,而是 Kubernetes 的一个高级客户端工具。
2.2.1 客户端-插件架构工作流程
- 用户执行命令: 用户通过
helm install命令,CLI 读取本地 kubeconfig 获取集群访问权限。 - 本地渲染模板: CLI 在本地将 Chart 模板与 values 文件合并,渲染出完整的 Kubernetes 资源清单。
- 直接调用 API Server: CLI 使用 kubeconfig 中的用户凭据,通过 Kubernetes API 将渲染后的资源清单提交到 API Server。
- 存储 Release 记录: Release 的元数据(包括配置、状态、Manifest)存储在 Kubernetes 的 Secrets 中(位于 Release 所在的命名空间)。
关键改进: 不再需要 Tiller 的服务账号。用户使用自己的身份(User/Group)与 API Server 交互,权限完全由 Kubernetes RBAC 控制,实现了最小权限原则。
2.2.2 客户端-插件架构示意图
2.3 Helm v2 与 v3 架构对比
| 对比维度 | Helm v2 (Tiller 架构) | Helm v3 (客户端-插件架构) |
|---|---|---|
| 服务端组件 | Tiller(集群内特权 Pod) | 无(纯客户端) |
| 权限模型 | Tiller 服务账号(RBAC) | 用户 kubeconfig 凭据(RBAC) |
| API 交互方式 | Tiller 通过内部服务账号调用 API | CLI 直接通过 kubeconfig 调用 API |
| Release 存储 | ConfigMap 或 Secrets(Tiller 命名空间) | Secrets(Release 所在命名空间) |
| 安全性 | 较低(Tiller 权限过大,端口暴露) | 较高(遵循最小权限原则) |
| 模板渲染位置 | Tiller 服务端渲染 | CLI 客户端本地渲染 |
| 依赖管理 | 依赖 Chart 需提前下载到 Tiller 缓存 | 依赖 Chart 在客户端本地处理 |
2.4 Helm 与 Kubernetes API 交互原理
无论是 v2 还是 v3,Helm 与 Kubernetes 控制平面的交互核心都是通过 Kubernetes API。Helm 本质上是一个 模板引擎 + API 客户端。它不直接管理 Pod 或 Service,而是将渲染后的 YAML 清单提交给 API Server,由 API Server 负责实际的资源调度和管理。
2.4.1 交互流程详解
- 身份认证与授权:
- v2: Tiller 使用其绑定的 ServiceAccount 的 进行认证。API Server 根据该 ServiceAccount 绑定的 RBAC 角色进行授权。
- v3: CLI 读取 kubeconfig 中的用户证书或 进行认证。API Server 根据该用户或 Group 绑定的 RBAC 角色进行授权。
- API 请求构建:
- Helm 将渲染后的 YAML 清单解析为 Go 结构体,构建对应的 RESTful API 请求(如 POST、PUT、DELETE)。
- 请求路径对应 Kubernetes 资源类型(如
/api/v1/namespaces/{ns}/pods)。
- 请求发送与响应处理:
- Helm 通过 HTTPS 将请求发送到 API Server 的端点。
- API Server 对请求进行准入控制(Admission Control)、验证、持久化到 etcd,并返回响应。
- Helm 解析响应,判断操作是否成功,并更新本地 Release 状态。
2.4.2 核心交互组件
| 组件 | 作用 | 在 Helm 中的体现 |
|---|---|---|
| REST Client | 发送 HTTP 请求到 API Server | Helm 使用 client-go 库中的 RESTClient 或 ClientSet |
| Serializer | 序列化/反序列化 YAML/JSON | Helm 使用 k8s.io/apimachinery 中的序列化器 |
| Discovery Client | 发现 API Server 支持的资源组和版本 | Helm 在安装前通过 Discovery Client 验证 API 版本兼容性 |
| Dynamic Client | 处理非结构化资源(如 CRD) | Helm 使用 Dynamic Client 管理自定义资源 |
2.4.3 Helm 与 API Server 交互示意图
实践要点: 理解 Helm 与 API 的交互原理,有助于排查权限问题(RBAC 绑定是否正确)、API 版本兼容性问题(Chart 中定义的 apiVersion 是否被集群支持)以及网络问题(CLI 到 API Server 的连通性)。