Helm 和 Kustomize:不只是含谷量的区别
Kustomize 问世的时候,我是比较鄙视的——非要造个谷歌的轮子么?不过最近抽出时间熟悉了一下 Kustomize,发现我还是带了有色眼镜。二者功能虽然有所重叠,但是工作思路的差别还是很大的,下面就简单做一点比较,权当引玉之砖。
Helm
Helm 是 Kubernetes 中的第一个对应用程序进行管理的支撑工具,经常会拿来同 Yum、apt 等工具进行类比。Helm 由几个不同的组件构成:
- CLI:客户端工具,有几大功能
- 从 Chart 服务器获取列表、搜索 Chart 项目
- 安装 Chart
- 构建 Chart
- 充当 Chart 服务器
- 和 Tiller 协同管理应用生命周期
- 渲染 Chart 为 Kubernetes 生成 YAML
- Tiller:需要用特定授权和 API Server 进行通信,Kubernetes 集群内外部署都可以。
- 它是 Helm 的内鬼,负责接收来自 Cli 的指令,完成对集群内应用生命周期的控制。
- 3.0 中将取消 Tiller。
- Repository:
- 是存储 Helm Chart 的仓库,可以被 Cli 工具缓存、检索,CLI 也可以获取 Chart 进行后续操作。
- 和 Tiller 一样,Repository 也不是必要组件,CLI 完全可以仅在本地工作。
Helm Chart
Helm 使用 Chart 对应用程序进行描述,它使用 Go Template 对应用部署所需的 YAML 进行抽象,形成应用部署模板,在需要进行部署时,可以编写 yaml 为模板中的变量进行赋值,也可以在 Helm CLI 的命令行中使用 --set name=value
的方式来对简单变量进行赋值,完成赋值之后,可以选择使用 helm template
指令将 Chart + Value 的组合渲染成为 YAML 供 kubectl
使用,也可以使用 helm install
直接通过 Tiller 进行安装。
Helm 的特色
- 强大的生命周期管理:有 Tiller 的帮助,可以实现对应用程序实例(Release)的查询、安装、卸载、升级、回滚等复杂操作。
- 严格的基础版本管控:Chart 是一种模板,Chart 的用户仅能通过对
values
的控制来定制应用的部署行为,模板中没有提供变量的位置,是无法在下游直接进行变更的。 - 方便的命令行:对于简单变量,可以在部署的同时直接指定内容,方便部署。
- 插件和工具:Helm 拥趸众多,提供了不少用于 CICD 或者其它方面辅助功能的插件和工具。
Kustomize
Kustomize 是一个新晋选手,只有一个 CLI 工具,在 Kubernetes 1.14 之后,甚至这唯一的工具也成为 kubectl 的一部分,可以说是很轻量级了。
Base + Overlay
在 Kustomize 的文档中明确说明:
kustomize is a command line tool supporting template-free, structured customization of declarative configuration targetted to k8s-style objects.
它放弃了对模板的要求,改用 Base + Overlay 的方式对应用的原始 YAML 进行派生
。Overlay
,顾名思义,就是覆盖。Kustomize 的 Overlay 可以在 Base 的基础上,通过对 resource
、generator
、transformer
等的定义,形成新的应用定义,不论 Base
还是 Overlay,都可以通过 kustomize build
生成有效的 YAML。
Kustomize 的特色
- 功能简单清晰,kubectl 直接支持。
- 不考虑派生,仅作为应用的 YAML 组织方式也很有帮助。
- 也有自己的插件系统。例如可以用简单的 YAML 定义,使用文件生成 Configmap/Secret。
比较
Kustomize 自称因为去掉了模板语法,更易使用,对此我保留看法,如果仅就入门使用来看,二者差异并不大。
Tiller 和 Repository 都并非必须,因此在部署上,Kustomize 的优势也不是很大。
我认为他们的区别主要在工作流程上:
- Helm 的基础流程比较
瀑布
:定义 Chart->填充->运行,在 Chart 中没有定义的内容是无法更改的; - Kustomize 的用法比较
迭代
:Base 和 Overlay 都是可以独立运作的,增加新对象,或者对编写 Base 时未预料的内容进行变更,都不在话下。
例如我们定义了一个很基础的应用,由 Deployment + Service 组成,如果后续部署中需要完成两个变更:
- 新建 Ingress 对象
- 修改镜像地址/名称/TAG
在 Helm 中需要:
- 在 Chart 中加入对 Ingress 的定义
- 用变量控制 Ingress 是否进行渲染
- Ingress 模板应该包含特定的主机名、注解等变量
- 把镜像也定义成变量
- 在 Values.yaml 中对这些变量进行赋值。
而在 Kustomize 中:
- 无需对 Base 进行修改
- 直接在新的 Overlay 中写入 Ingress Resource
- 使用内置的
image transformer
替换原有镜像
结论
要公开发布一个较为复杂的应用,例如 Istio
,编写良好的 Chart 能给用户很大帮助,用户在缺失一点发挥空间的情况下,通过对 values.yaml
的阅读,就能对这种复杂的部署产生一个较为深入的认识。
如果是常见的业务应用,因为不同部署之间的差异不大,但是未必可以提前做好变化限制,用 Kustomize 可能会是一个更好的选择。
相关链接
- Helm:
https://helm.sh/
- Kustomize:
https://github.com/kubernetes-sigs/kustomize
- Helm 3.0:
https://helm.sh/blog/helm-3-preview-pt1/
- Helm 工具:
https://www.infoq.cn/article/UemPsPu_AlzemkGEqb4Z
- Awesome Helm:
https://github.com/cdwv/awesome-helm