图表钩子

Helm 提供了钩子机制,允许图表开发者在发布生命周期的某些点进行干预。例如,您可以使用钩子来

  • 在安装任何其他图表之前,在安装期间加载 ConfigMap 或 Secret。
  • 执行 Job 以在安装新图表之前备份数据库,然后在升级后执行第二个 Job 以恢复数据。
  • 在删除发布之前运行 Job,以便在删除服务之前将其优雅地从轮换中移除。

钩子像普通的模板一样工作,但它们具有特殊的注释,导致 Helm 以不同的方式使用它们。在本节中,我们将介绍钩子的基本用法模式。

可用的钩子

定义了以下钩子

注释值描述
pre-install在渲染模板后执行,但在 Kubernetes 中创建任何资源之前执行
post-install在所有资源加载到 Kubernetes 中后执行
pre-delete在删除请求中执行,在从 Kubernetes 中删除任何资源之前执行
post-delete在删除请求中执行,在删除发布的所有资源之后执行
pre-upgrade在升级请求中执行,在渲染模板后执行,但在更新任何资源之前执行
post-upgrade在升级请求中执行,在所有资源升级后执行
pre-rollback在回滚请求中执行,在渲染模板后执行,但在回滚任何资源之前执行
post-rollback在回滚请求中执行,在所有资源修改后执行
test在调用 Helm 测试子命令时执行(查看测试文档

请注意,crd-install 钩子已被删除,取而代之的是 Helm 3 中的 crds/ 目录。

钩子和发布生命周期

钩子允许您(图表开发者)在发布生命周期的关键点执行操作。例如,考虑 helm install 的生命周期。默认情况下,生命周期如下所示

  1. 用户运行 helm install foo
  2. 调用 Helm 库安装 API
  3. 经过一些验证后,库会渲染 foo 模板
  4. 库将生成的资源加载到 Kubernetes 中
  5. 库将发布对象(和其他数据)返回给客户端
  6. 客户端退出

Helm 为 install 生命周期定义了两个钩子:pre-installpost-install。如果 foo 图表的开发者实现了这两个钩子,生命周期将更改为如下所示

  1. 用户运行 helm install foo
  2. 调用 Helm 库安装 API
  3. crds/ 目录中的 CRD 将被安装
  4. 经过一些验证后,库会渲染 foo 模板
  5. 库准备执行 pre-install 钩子(将钩子资源加载到 Kubernetes 中)
  6. 库按权重(默认分配权重 0)、资源类型,最后按名称升序对钩子进行排序。
  7. 然后,库将首先加载权重最低的钩子(负数到正数)
  8. 库将等待钩子处于“就绪”状态(CRD 除外)
  9. 库将生成的资源加载到 Kubernetes 中。请注意,如果设置了 --wait 标志,库将等待所有资源处于就绪状态,并且在它们就绪之前不会运行 post-install 钩子。
  10. 库执行 post-install 钩子(加载钩子资源)
  11. 库将等待钩子处于“就绪”状态
  12. 库将发布对象(和其他数据)返回给客户端
  13. 客户端退出

等待钩子就绪意味着什么?这取决于钩子中声明的资源。如果资源是 JobPod 类型,Helm 将等待它成功运行完成。如果钩子失败,发布将失败。这是一个阻塞操作,因此 Helm 客户端将在 Job 运行期间暂停。

对于所有其他类型,一旦 Kubernetes 将资源标记为加载(添加或更新),该资源就被认为是“就绪”的。当钩子中声明了许多资源时,这些资源将按顺序执行。如果它们有钩子权重(见下文),它们将按权重顺序执行。从 Helm 3.2.0 开始,具有相同权重的钩子资源将按照与普通非钩子资源相同的顺序安装。否则,顺序不受保证。(在 Helm 2.3.0 及之后,它们将按字母顺序排序。但是,这种行为不被视为具有约束力,将来可能会更改。)建议添加钩子权重,如果权重不重要,则将其设置为 0

钩子资源不会与相应的发布一起管理

钩子创建的资源目前不会作为发布的一部分进行跟踪或管理。一旦 Helm 验证钩子已达到其就绪状态,它将不再理会钩子资源。将来可能会将钩子资源的垃圾回收添加到 Helm 3 中,因此任何永远不能删除的钩子资源都应该用 helm.sh/resource-policy: keep 注释。

实际上,这意味着如果您在钩子中创建资源,您不能依赖 helm uninstall 来删除这些资源。要销毁此类资源,您需要要么在钩子模板文件中添加自定义 helm.sh/hook-delete-policy 注释,要么设置 Job 资源的生存时间 (TTL) 字段.

编写钩子

钩子只是 Kubernetes 清单文件,在 metadata 部分中具有特殊的注释。因为它们是模板文件,所以您可以使用所有正常的模板功能,包括读取 .Values.Release.Template

例如,此模板存储在 templates/post-install-job.yaml 中,声明了在 post-install 上运行的作业

apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ .Release.Name }}"
  labels:
    app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
    app.kubernetes.io/instance: {{ .Release.Name | quote }}
    app.kubernetes.io/version: {{ .Chart.AppVersion }}
    helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
  annotations:
    # This is what defines this resource as a hook. Without this line, the
    # job is considered part of the release.
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    metadata:
      name: "{{ .Release.Name }}"
      labels:
        app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
        app.kubernetes.io/instance: {{ .Release.Name | quote }}
        helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    spec:
      restartPolicy: Never
      containers:
      - name: post-install-job
        image: "alpine:3.3"
        command: ["/bin/sleep","{{ default "10" .Values.sleepyTime }}"]

使此模板成为钩子的注释是

annotations:
  "helm.sh/hook": post-install

一个资源可以实现多个钩子

annotations:
  "helm.sh/hook": post-install,post-upgrade

同样,可以实现给定钩子的不同资源数量没有限制。例如,可以将 secret 和 config map 都声明为 pre-install 钩子。

当子图表声明钩子时,也会评估这些钩子。顶级图表无法禁用子图表声明的钩子。

可以为钩子定义权重,这将有助于构建确定性执行顺序。权重使用以下注释定义

annotations:
  "helm.sh/hook-weight": "5"

钩子权重可以是正数或负数,但必须用字符串表示。当 Helm 启动特定类型的钩子的执行循环时,它将按升序对这些钩子进行排序。

钩子删除策略

可以定义策略来确定何时删除相应的钩子资源。钩子删除策略使用以下注释定义

annotations:
  "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded

您可以选择一个或多个定义的注释值

注释值描述
before-hook-creation在启动新的钩子之前删除之前的资源(默认)
hook-succeeded钩子成功执行后删除资源
hook-failed如果钩子在执行期间失败,则删除资源

如果未指定钩子删除策略注释,则默认情况下将使用 before-hook-creation 行为。