Helm 将 Kubernetes 应用程序打包到图表中,图表是模板化的 Kubernetes 清单文件的集合。每个图表包含以下内容:
- example-chart/
- ├── .helmignore
- ├── Chart.yaml
- ├── values.yaml
- ├── charts/
- └── templates/
- └── tests/
- ...
每个文件作用:
.helmignore
– 定义打包 Helm 图表时要忽略的文件或模式(例如,、、、.vscode
秘密.git
文件)。Chart.yaml
– 如果图表将多个应用程序捆绑在一起,则包含有关 Helm 图表的顶级元数据,包括名称、版本和其他依赖项。依赖图表的示例包括将 Zookeeper 与 Kafka 打包或将 Prometheus 和 Grafana 组合在一起。 values.yaml
– 为模板目录下图表的所有模板部分设置默认值。这些默认值可以通过–values
或–set
标志覆盖。charts
– 存储依赖图表的 tar 文件(如果在Chart.yaml
.templates
– 保存定义应用程序的所有 Kubernetes 清单文件,包括但不限于 Deployment、Services、自动缩放、ConfigMaps 和 Secrets。除了核心 Kubernetes 文件,它还可以保存模板帮助程序、NOTES.txt 和测试文件。在底层,Helm 使用 Go 模板将值合并到相应的模板文件中。这意味着了解 YAML 语法以及 Go 的数据类型以创建、更新或使用 Helm 图表非常重要。
创建图表后,即可将其部署到 Kubernetes 集群中。Helm CLI 使用install
或upgrade
命令来触发新版本。每个版本都是版本化、模板化图表的独立部署工件。这意味着只要基础值不冲突,同一个图表就可以有多个版本。例如,可以使用相同的配置将 PostgreSQL Helm 图表部署到两个不同的命名空间。
此外,Helm 保留每个版本的历史记录,允许轻松回滚。要查看发布历史记录,请运行helm history
. 然后回滚,使用helm rollback
. 虽然这些 CLI 命令对开发很有用,但它们很可能由生产中更强大的 CD 系统控制。
现在我们对 Helm 的结构和生命周期有了很好的了解,我们将回顾一些与 Helm 图表交互的最佳实践和有用的技巧。
helm create
Helm 提供了一个优秀的骨架来通过命令引导一个新的 Helm 图表。无需从头开始手工制作单个 Helm 文件,而是利用该create
命令获取默认清单文件(例如 、、deployment.yaml
、hpa.yaml
和)以及提供唯一名称和注释的模板。ingress.yaml
service.yaml
serviceaccount.yaml
Helm 还提供了几个工具来在部署之前验证图表。YAML 和 Go 模板语法可能难以调试,尤其是由于简单的缩进或空值错误。
helm lint
– 检查图表是否存在语法问题,例如格式错误的 YAML 缩进或缺失值。–debug
使用标志运行此命令可以提供更多信息。helm template
– 使用提供的值在本地呈现模板。这对于查看覆盖值是否正确插入到清单模板中很有用。要专注于单个模板,请使用-s
标志:helm template my-chart -s templates/deployment.yaml
.--dry-run
– Lint 和模板命令只能通过静态分析捕获模板问题。要捕获与 Kubernetes 相关的错误(例如,使用已弃用的 Kubernetes API 版本),请--dry-run
在调用升级或安装命令之前运行该命令。如 Helm 结构部分所述,有时将多个应用程序打包到一个 Helm 图表中是有意义的。这种模式有助于将相关的应用程序或数据库组合成一个可部署的单元。常见用例包括使用 Django 应用程序打包 PostgreSQL 和 Redis,或者将 ELK/EFK 堆栈的所有组件捆绑在一起。使用子图表的另一种方法是捆绑常用帮助模板以添加注释、标签或默认值。在 Bitnami 的图表中可以找到一个很好的例子:
- apiVersion: v2
- appVersion: "3.2.1"
- dependencies:
- - condition: zookeeper.enabled
- name: zookeeper
- repository: "https://charts.bitnami.com/bitnami"
- version: 10.x.x
- - name: common
- repository: "https://charts.bitnami.com/bitnami"
- tags:
- - bitnami-common
- version: 2.x.x
- name: kafka
- version: 18.2.0
由于 Kubernetes 仅监视部署规范中的更改,默认情况下,更改挂载到 Pod 的 ConfigMap 或 Secret 的内容不会自动触发滚动更新。对于希望在调用升级命令时使用更新的值重新启动的用户来说,这可能是意外行为。
要自动滚动部署,您可以使用Reloader等工具或在部署规范中添加校验和注释:
- kind: Deployment
- spec:
- template:
- metadata:
- annotations:
- checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
注释对于为应该在安装或升级之前或之后运行的作业定义挂钩也很有用。常见用例可能包括运行 Flyway 迁移或运行清理作业。虽然这可以通过其他 CD 工具来实现,但Helm 挂钩提供了一种改变发布生命周期行为的本地方式:
- apiVersion: batch/v1
- kind: Job
- metadata:
- annotations:
- "helm.sh/hook": post-install
- "helm.sh/hook-weight": "-5"
- "helm.sh/hook-delete-policy": hook-succeeded
虽然 Helm 提供了一套功能,可以更轻松地打包和发布 Kubernetes 应用程序,但重要的是要注意 Helm 只是一个包管理器——它不是一个功能齐全的 CD 工具。换句话说,组织不应仅依赖 Helm 来提供端到端的 Kubernetes CI/CD 工具。相反,Helm 应该与更强大的工具集成,例如 ArgoCD、JenkinsX 或 Spinnaker,以保持部署的一致性。此外,由于 Helm 使用纯文本 YAML 作为主要模板接口,因此不能很好地处理 Secrets 和非 YAML 文件。这意味着秘密或配置二进制文件(例如,公钥、.dat 文件)可以通过另一个 CI/CD 工具在 Helm 之外更好地处理。
最后,虽然子图对于将相关组件组织在一起很有用,但深度嵌套的子图可能会导致模板问题。如果应用程序确实需要多个嵌套子图表,请寻找其他部署模式(例如 ArgoCD 的ApplicationSet)来将多个 Helm 图表组合在一起。