Helm 的陷阱——关于这款领先的 K8s 包管理器 3 年使用经验的洞见

Helm 作为 Kubernetes 的事实标准包管理器,因在 YAML 之上依赖字符串模板、缺乏强 schema 的大而散的 `values.yaml`“API”,以及在升级、CRD 和 hooks 方面的脆弱行为而饱受批评。许多工程师认为 Helm 最适合分发第三方应用,但并不适合日常内部部署;他们更偏好 Kustomize、带 CRD 的 operator,或完整的编程语言方案(Pulumi、Jsonnet、CUE、Starlark、cdk8s)。一个反复出现的主题是:将配置视为真正的代码——具备类型、工具和清晰的状态归属——能带来比 Helm 的模板模型更易维护、也更易调试的 Kubernetes 工作流。

Helm 的角色以及适用场景

  • 许多人认为,Helm 的主要优势在于打包并公开分发复杂的 Kubernetes 应用,尤其是在使用者不想了解所有细节时。
  • 也有人认为 Helm 不是一个好的“包管理器”,更像是一个一般般的模板引擎;他们将其与传统操作系统包管理器作了不利比较。
  • 对于内部应用,很多人更偏好其他模式:简单的静态 YAML、kustomize 覆盖层,或者完整的 operator/CRD。

Helm 的常见痛点

  • values.yaml 实际上就是一个无类型、仅对 chart 生效的 API。大量、文档糟糕的 values 树被认为既压倒性又容易出错。
  • 缺乏对 values 的强模式校验是一个反复出现的抱怨;有人希望能从底层 Kubernetes API 推导出类型。
  • 在对空白敏感的 YAML 上使用 Go text 模板,会导致 chart 脆弱、模板难读,以及令人困惑的错误信息和行号。
  • 维护复杂且广泛分发的 chart 往往会把每个字段都推到 values 里,导致配置面不断膨胀。
  • 提出的运维问题包括:hooks 被视为反模式、不安全或令人意外的升级、有限的 diff/plan 能力、CRD 和 API 版本处理问题,以及在 CI 中难以轻松查看 hook 日志。

替代方案与变通方法

  • 常见模式是:使用 helm template 渲染 manifests,然后用其他工具(Pulumi、Terraform、kapp、kustomize、Tanka/Jsonnet)来应用它们。
  • Kustomize 因其 base+patch 模型以及最后一公里定制能力而受到赞赏(包括 patch Helm 的输出),但也因语法别扭以及每个环境需要多个文件而受到批评。
  • 许多人主张使用真正的语言来实现“配置即代码”:Pulumi(TS/Python 等)、cdk8s、直接用 Python/TypeScript/Kotlin 脚本、Pydantic 模型,或 Terraform+生成器。
  • 一些人认为专门的配置语言(Jsonnet、CUE、Dhall、Starlark)是更好的折中;另一些人则觉得它们仍然过于笨重或难以调试。
  • Operators + CRDs 被视为更符合惯用方式,适合复杂行为和升级,但编写难度更高,也常常会被谨慎的运维团队阻挡。

更广泛的配置语言反思

  • 对于结构化数据使用字符串模板,以及“YAML 无处不在”这一做法,存在强烈反弹。
  • 有几位预测会转向带类型、感知 schema 的、基于语言的工具和/或 WASM 沙箱化模块,而 GitOps 工具(ArgoCD、Flux、Carvel)则负责编排最终应用的 manifests。