Helm Hooks

在部署chart时,可能会有以下需求:

  • 在更新 chart 之前,执行一个 Job 来备份数据库,然后在升级后执行第二个 Job 还原数据
  • 在删除 release 之前运行一个 Job,将数据备份到S3

image-20211219210704555

Helm 提供了一种 Hook 机制,可以允许 chart 开发人员在 release 生命周期的某些时间点进行干预。


在 Helm 中定义了如下一些可供我们使用的 Hooks:

  • 预安装pre-install:在模板渲染后,kubernetes 创建任何资源之前执行
  • 安装后post-install:在所有 kubernetes 资源安装到集群后执行
  • 预删除pre-delete:在从 kubernetes 删除任何资源之前执行删除请求
  • 删除后post-delete:删除所有 release 的资源后执行
  • 升级前pre-upgrade:在模板渲染后,但在任何资源升级之前执行
  • 升级后post-upgrade:在所有资源升级后执行
  • 预回滚pre-rollback:在模板渲染后,在任何资源回滚之前执行
  • 回滚后post-rollback:在修改所有资源后执行回滚请求
  • 测试test:在调用 Helm test 子命令的时候执行(可以查看测试文档

image-20211219125210472

Hooks 的工作方式类似于普通的模板,但是他们具有特殊的注解,这些注解使 Helm 可以识别它们:

image-20211219125425942

因为它们是模板文件,所以你可以使用普通模板所有的功能,包括读取 .Values.Release.Template


如果在某个阶段有多个hook要执行,可以设置优先级来进行排序:

image-20211219125923223

hook 权重可以是正数也可以是负数,但是必须用字符串表示。当 Helm 开始执行特定种类的 hooks 的时候,它将以升序的方式对这些 hooks 进行排序。

动手实验

创建新的chart hooks-lab:

kongpingfan:~/environment/helm $ helm create hooks-lab
Creating hooks-lab
kongpingfan:~/environment/helm $ cd hooks-lab/

templates目录下除deployment.yaml外所有文件都删除,并在templates/目录下新建两个文件post-install.yamlpost-upgrade.yaml,最终文件目录结构如下:

kongpingfan:~/environment/helm/hooks-lab $ tree
.
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── post-install.yaml
│   └── post-upgrade.yaml
└── values.yaml

2 directories, 5 files

post-install.yaml内容如下:

apiVersion: batch/v1
kind: Job
metadata:
  name: install-hook
  annotations:
    "helm.sh/hook": post-install
spec:
  template:
    spec:
      containers:
      - name: install-hook
        image: alpine
        command: ["echo",  "Successful Installation"]
      restartPolicy: Never
  backoffLimit: 4

post-upgrade.yaml内容:

apiVersion: batch/v1
kind: Job
metadata:
  name: upgrade-hook
  annotations:
    "helm.sh/hook": post-upgrade
spec:
  template:
    spec:
      containers:
      - name: upgrade-hook
        image: alpine
        command: ["echo",  "Successful Upgradation"]
      restartPolicy: Never
  backoffLimit: 4

deployment.yaml内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent

部署第一版的release,此时会看到自动触发install-hook:

image-20211219212242663

对deployement.yaml做更新, 使用1.21版本的镜像:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .ReleaseName }}-nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.21
          imagePullPolicy: IfNotPresent

更新第二版的release,此时会看到自动触发upgrade-hook:

image-20211219213004049