跳到主要内容

Helm 包管理工具

· 阅读需 5 分钟

众所周知,k8s可以在多个node节点上管理容器资源,但每个容器需要对应的pod-yaml文件来进行管理。

这篇文章想聊的其实是 yaml 文件失控的问题。单个应用写一份 Deployment、一份 Service 不算什么负担,但集群里的应用一多,配置文件的数量会以肉眼可见的速度膨胀:改一个镜像标签要翻好几个文件,换一套环境又要把整批配置复制出来逐个改参数。到了这一步,靠人肉维护 yaml 就不再现实了。

从一堆 yaml 说起

我们先说问题:如果在一个namespace中有几十个pod需要进行配合部署,例如 mysql 集群,kafka集群,但部署kafka集群又需要先部署 zookeeper集群,应用程序又需要Redis 集群,以及一些MQ队列集群,还有应用程序自身的部署,微服务可能多达50-100个甚至更多的应用。

这样的场景让你来写 yaml 配置文件 我想你可能是拒绝的,就算你部署了一次,好不容易部署完成了,但异地机房集群还要再次部署怎么办? 更何况怎么做到多个不同机房中集群的配置信息完全一致?

这些 yaml 之间还有隐含的部署顺序和大量重复的配置项——镜像仓库地址、资源限额、存储类名称,几乎每个文件里都要抄一遍。一旦某个公共参数变了,漏改任何一处都是隐患。

所以这里的问题很明显了,我们需要一个可以集中管理所有 yaml 配置文件并且可以复用的工具。

Helm:k8s 上的包管理器

于是 Helm 就诞生了,他的定位类似于 CentOS 中的 Yum 包管理工具,又或者是 Debian中的 apt 包管理工具,只不过这次的包管理是基于 k8s 环境。

Helm 中的每个包都称为一个Chart,一个Chart是一个目录。目录里的核心内容可以概括成三部分:Chart.yaml 描述这个包的名称和版本等元信息;values.yaml 存放默认配置值,安装时可以被外部覆盖;templates/ 目录里放的是带模板语法的 k8s 资源文件。安装时 Helm 把 values 渲染进模板,生成真正的 yaml 再提交给集群,一次安装的结果称为一个 Release。

配置复用的关键就在这套模板机制上:不同机房、不同环境共用同一个 Chart,各自只维护一份小小的 values 文件,机房间配置不一致的问题自然就消解了。Chart 还可以声明依赖,像"部署 kafka 之前要先有 zookeeper"这种关系可以交给子 Chart 处理,不必再靠人来记顺序。

应用发布者可以通过Helm打包应用,管理应用依赖关系,管理应用版本并发布应用到软件仓库进行统一管理,在 k8s 中需要部署时 只需要一条指令即可部署整套 pod 应用。

日常用到的命令并不多:

# 添加一个 Chart 仓库(以常用的 bitnami 仓库为例)
helm repo add bitnami https://charts.bitnami.com/bitnami

# 更新本地缓存的仓库索引
helm repo update

# 一条命令部署整套应用,Chart 会自动创建所需的全部资源
helm install my-mysql bitnami/mysql

# 查看当前 namespace 下已部署的 Release
helm list

部署之后的升级和回滚也由 Helm 接管,每次变更都会记录成一个新的版本:

# 用自定义的 values 文件覆盖默认配置并升级
helm upgrade my-mysql bitnami/mysql -f my-values.yaml

# 升级出问题时回滚到上一个版本
helm rollback my-mysql

Helm的官方地址:

Helm

图形化管理:Kubeapps

官方的中文文档写的比较详细,有兴趣可以学习一下,我在这里再推荐一款 Helm 的UI 管理工具,可以更方便的管理企业 Helm 包信息。

kubeapps

Kubeapps - Kubeapps

Kubeapps 本身就是一个部署在集群里的 Web 应用,可以在页面上浏览仓库中的 Chart、通过表单填写配置完成安装,也能查看和升级已有的 Release。对不方便让所有人都用命令行操作集群的团队来说,这类工具能省不少事。

踩坑与注意

1) 自定义配置放在自己的 values 文件里

尽量用 -f 传入独立的 values 文件来覆盖默认值,而不是直接改 Chart 内的 values.yaml。前者在 Chart 升级时可以原样沿用,后者的改动很容易在更新 Chart 时被覆盖丢失。

2) 卸载动作要想清楚

注意

helm uninstall 会把 Release 关联的资源一并删除。对 mysql 这类有状态应用,动手前先确认存储卷的保留策略,避免连数据一起清掉。

3) Chart 版本和应用版本是两回事

Chart.yaml 里的 version 指 Chart 自身的打包版本,appVersion 才对应里面软件的版本。升级前看清楚变的是哪一个,避免以为只是改了模板、实际却把应用也升了级。

小结

Helm 把散落各处的 yaml 收拢成 Chart,用模板加 values 的方式解决了配置复用和多环境一致性的问题,部署、升级、回滚都收敛成一条命令。规模小的时候手写 yaml 还能应付,应用一多,早点引入 Helm 这层包管理,后面会省下大量重复劳动。再配合 Kubeapps 这样的 UI 工具,团队协作时的门槛也能降低不少。

评论 / COMMENTS