Kubernetes 并不以简单著称,主要是因为它提供了对用于管理微服务应用的各种对象的细粒度控制。随着这些应用不可避免地变得更加复杂,管理它们也变得更具挑战性。Helm 和 Kustomize 是两个常用的工具,旨在使这一过程更加容易管理。虽然两者都旨在简化 Kubernetes 环境中的复杂应用部署,但它们采取了不同的方法来解决问题。
在这篇文章里,我们将看看它们的关键特性,比较它们各自的长处和短处,帮助您在任何部署阶段选择最适合的工具。
Helm 是一个云原生命令行工具,目前已成为最广泛使用的 Kubernetes 包管理器。它允许用户通过 Helm charts 定义、安装和管理应用程序。Helm charts 包含生成应用程序部署所需的所有资源和配置,使其配置易于跨不同项目进行共享和重用。Helm 使用基于 Go 模板的模板引擎,基于用户定义的模板和配置值生成 Kubernetes 资源描述文件。Helm 还支持版本控制、回退和依赖管理,使其成为管理 Kubernetes 中复杂应用的强大工具。
我们最近发布了一篇详细的Helm指南,分享了关键命令、常见错误、最佳实践,并且包含了一个详细的FAQ,解答了许多与Helm相关的问题。快去瞧一瞧。
Helm 图表本质上是部署应用程序到 Kubernetes 集群的一种蓝图。它将所有必要的 Kubernetes 资源(例如 Pod、Service、ConfigMap 等)打包成一个包,可以将其部署为一个发行版。这些图表存储在 Helm 仓库中,用户可以轻松地下载并安装预配置的应用。
要创建 Helm 图表,请使用以下命令。
helm create <chart-name>:可以创建一个新的chart,其中<chart-name>是你指定的名称。
这建立了基本文件结构,包括存放你自定义 Kubernetes 资源文件的 templates/
目录和定义可配置参数的 values.yaml
文件。Helm charts 是在 Kubernetes 环境中打包和部署应用程序的绝佳起点。但它们也有一些 棘手的限制,例如:
一个典型的Helm图表结构通常如下。
mychart/ Chart.yaml values.yaml charts/ templates/ deployment.yaml service.yamlya
Chart.yaml
: 包含关于图表包的元数据信息(名称、版本等)。values.yaml
: 包含默认配置值,这些值可以被自定义并动态地应用到模板中。templates/
: 持有每个资源的 Kubernetes 资源文件(例如 Deployment、Service 等资源)。关于 Helm,这里提到的内容只是它的一部分,还有很多其他的内容。如前所述,之前发布的一篇深入指南深入探讨了 Helm。接下来我们将会主要讨论 Helm 和 Kustomize 之间的对比。
Kustomize 是在 Helm 之后开发的一种原生 Kubernetes 工具,旨在解决无需使用模板即可管理 Kubernetes 配置的需求。许多 Kubernetes 用户希望使用 kubectl 命令来操作纯 YAML 文件,无论是处理多个文件、创建或更新 ConfigMaps
和 Secrets
,还是跨环境部署变更。Kustomize 应运而生,成为配置管理的解决方案,使用基础清单来创建特定环境的版本。
与 Helm 不同,它依赖于模板,Kustomize 使用叠加的方式来应用不同的配置到一组基础资源。这允许你维护基础 YAML 文件,并根据不同的环境(如 开发
, 测试
, 或 生产
)叠加特定的更改。
我们最近发布了一篇[Kustomize深入教程],该教程探讨了各种补丁、转换器和生成器的类型,并分享了使用该工具的最佳实践。务必查看,获取更多详细指南。
Kustomize 允许你通过分层叠加修改来管理和自定义 Kubernetes 配置,而不改变原始文件的内容。典型的 Kustomize 配置包括一个包含基础和叠加层的目录结构。
base/
目录不仅包含一个 kustomization.yaml 文件,还包含了适用于所有环境的常见资源清单。kustomization.yaml
文件定义了所有环境都需要的核心资源,比如 Deployments
和 Services
。
overlays/
目录下的 kustomization.yaml
文件引用了基础目录中的资源,并应用了环境特定的补丁或自定义修改。这些补丁可能包括但不限于更改标签、资源限制、标签或其他特定于环境的配置。overlay 目录下的 kustomization.yaml
文件允许你为例如开发、预发布或生产等环境应用修改,而不直接修改基础配置。
├── base/ │ ├── kustomization.yaml # 基础配置文件 │ ├── deployment.yaml # 部署配置文件 │ ├── service.yaml # 服务配置文件 └── overlays/ ├── production/ │ ├── kustomization.yaml # 生产环境的基础配置文件 │ └── replica-patch.yaml # 生产环境的副本补丁文件 └── staging/ ├── kustomization.yaml # 预发布环境的基础配置文件 └── resource-patch.yaml # 预发布环境的资源补丁文件
Kustomize 没有一个固定的项目结构。这只是 Kustomize 文档推荐的一种结构,因为它相当灵活,所以经常被广泛采用。
Helm 采用了一个模板引擎,允许用户将值传递到预定义的模板中,以实现动态和可重复的配置设置。然而,这会引入复杂性,因为未解析的模板阅读和调试起来较为困难。
相比之下,Kustomize 更侧重于使用普通的 Kubernetes 清单来定义声明式的配置,这使其更直观易读。虽然 Kustomize 简化了配置管理过程,但它缺少 Helm 的一些命令式功能,例如状态的管理,在更复杂的情况下,这些功能会非常有用。
Helm 通常被认为更便于打包整个应用程序,这得益于其广泛的预构建图表生态系统。然而,Kustomize 并不一定是使用更难,它只是为不同的用途而设计。Kustomize 在对现有资源定义文件进行小幅、有针对性的修改方面表现出色,使其在跨多个环境管理配置方面成为理想选择,而不是像 Helm 那样打包整个应用。
Helm 的一个缺点是其未渲染的动态模板很难解读。相比之下,Kustomize 管理和修改普通的 YAML 文件,使其更易于读取和理解。工程师在查看代码库时,可能会认为 Kustomize 的配置比 Helm 图表更加直观和容易理解。
Helm 是专门用于打包和分发 Kubernetes 应用程序的,而 Kustomize 更适合对现有 YAML 配置进行修改。如果你需要全面的应用生命周期管理,Helm 可能更适合你。对于细粒度资源定制,Kustomize 更合适。
从 Kubernetes 版本 1.14 开始,Kustomize 与 kubectl 原生集成,这意味着你可以直接使用它,无需额外工具。而 Helm 则需要安装 Helm CLI。
安装 kubectl
后运行:
kubectl apply -k <kustomization 目录路径>
相比之下,Helm 专门设计用于 Kubernetes 环境,但是它并没有和 kubectl
集成。
Kustomize 专注于生成 Kubernetes 资源的期望状态,而不内置历史记录跟踪功能。虽然它没有内置的发布管理功能,但可以通过以下方式实现类似的功能:
在 Kustomize 配置中添加标签
结合使用 kubectl apply --prune
来清理资源
虽然 Helm 和 Kustomize 都用于 CI/CD 管道中,但 Helm 的发布管理和回滚功能通常更适合自动化的持续交付流程。Kustomize 通过专注于资源定制,非常适合 GitOps 流程 中变更的版本控制,但在大规模环境中跟踪和管理变更时可能需要更多工具。
Helm由于其模板系统和需要理解Helm特定语法因此,学习曲线更陡峭。Kustomize更接近原生Kubernetes,对于已经熟悉Kubernetes资源定义的用户来说,可能会觉得更加直观。不过,这种简洁性也可能会在处理更复杂的配置时带来挑战。
Helm 和 Kustomize 可以各自作为独立工具来使用,但在实际操作中,人们常常会将它们结合使用,以更有效地管理 Kubernetes 部署。在以下情况中,不妨试试将它们一起使用。
将 Helm 和 Kustomize 结合有三种方式,但并非所有方式都同样成熟且可靠。
helm template
并用 Kustomize 应用:在此方法中,您使用 helm template
从 Helm chart 生成 Kubernetes 清单文件,然后使用 Kustomize 应用补丁或叠加。由于 Kustomize 负责将资源部署到 Kubernetes,Helm 不会管理部署,因此不会进行基于 Helm 的版本跟踪。helm install
并用 Kustomize 预先修改:通过此方法,Helm 负责应用程序的部署,因此它管理和跟踪应用程序的生命周期,而 Kustomize 在将清单应用到集群之前对其进行修改。这使您仍可以利用 Helm 的部署管理功能。helmCharts
字段实现。此功能需要 --enable-helm
标志:kustomize build --enable-helm
Helm 在打包应用方面表现出色,它提供了丰富的功能,如回滚功能、版本管理和依赖管理。然而,它使用模板的方式使其受 Go 模板框架限制,并且特别是在维护大规模和复杂的部署时,可能会变得非常复杂。
另一方面,Kustomize 采用了一种更简单、无模板的方法,专注于基于补丁的配置管理方式。它特别适用于管理不同的环境(开发、预发布、生产),而无需复杂的模板逻辑的依赖。这使得 Kustomize 成为一个显而易见的选择,当你需要优雅且直接地为一组通用的基础配置添加变化时特别有用。
实际上,将Helm的打包能力与Kustomize的灵活覆盖系统结合使用,可以实现最佳效果。两者共同作用,能够实现稳健、可维护且灵活的Kubernetes部署,其中Helm负责应用程序的发布,Kustomize则很好地处理特定环境的定制。虽然有些人可能觉得使用两个不同的工具进行Kubernetes包管理不太方便,甚至可能增加复杂性,但在更全面的一体化解决方案出现之前,这种组合仍然是最有效的方法之一。