脚本中Helm钩子脚本如何用

wen 实用脚本 3

本文目录导读:

脚本中Helm钩子脚本如何用

  1. Helm 钩子的基本用法
  2. 实际应用示例
  3. 高级技巧
  4. 最佳实践
  5. 常见问题

在 Helm 中,钩子(Hooks)是用于在 Release 生命周期的特定时刻执行操作的机制,它们定义在 Chart 模板中,通过特殊的注释和资源文件来实现。

Helm 钩子的基本用法

定义钩子资源

templates/ 目录下创建普通资源文件,添加 helm.sh/hook 注释:

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-pre-install
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-weight": "0"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      containers:
      - name: setup
        image: alpine
        command: ["echo", "This runs before install"]
      restartPolicy: Never

可用的钩子类型

钩子类型 触发时机 应用场景
pre-install 模板渲染后,资源创建前 初始化数据库、创建密钥、运行检查脚本
post-install 所有资源创建后 数据迁移、发送通知、注册服务
pre-delete 删除请求后,任何资源删除前 清理外部资源、备份数据
post-delete 所有资源删除后 清理验证、发送通知
pre-upgrade 升级时,模板渲染后,资源更新前 数据备份、版本检查
post-upgrade 升级后,所有资源更新后 数据迁移、缓存重建
pre-rollback 回滚时,模板渲染后,资源回滚前 备份当前状态
post-rollback 回滚后,所有资源回滚后 恢复验证、数据同步
test helm test 命令执行时 集成测试、健康检查

钩子权重控制

通过 helm.sh/hook-weight 控制执行顺序:

# 低权重先执行
annotations:
  "helm.sh/hook": pre-install
  "helm.sh/hook-weight": "-5"
# 高权重后执行
annotations:
  "helm.sh/hook": pre-install  
  "helm.sh/hook-weight": "10"

删除策略

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

删除策略选项:

  • hook-succeeded:成功后删除(默认)
  • hook-failed:失败后保留日志排查
  • before-hook-creation:新钩子创建前删除旧钩子

实际应用示例

数据库迁移 Job

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-migration
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/instance: {{ .Release.Name }}
  annotations:
    "helm.sh/hook": post-install,post-upgrade
    "helm.sh/hook-weight": "5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      containers:
      - name: migration
        image: {{ .Values.migration.image }}
        env:
        - name: DB_HOST
          value: {{ .Values.database.host }}
        - name: DB_USER
          value: {{ .Values.database.user }}
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Release.Name }}-db-secret
              key: password
        command: ["./migrate.sh"]
      restartPolicy: Never
      {{- if .Values.migration.serviceAccount }}
      serviceAccountName: {{ .Values.migration.serviceAccount }}
      {{- end }}

复杂的钩子脚本示例

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-init-script
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-weight": "-10"
data:
  init.sh: |
    #!/bin/sh
    echo "Checking prerequisites..."
    kubectl get namespace {{ .Values.namespace }} || kubectl create namespace {{ .Values.namespace }}
---
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-init
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": before-hook-creation
spec:
  template:
    spec:
      containers:
      - name: init
        image: bitnami/kubectl:latest
        command: ["/scripts/init.sh"]
        volumeMounts:
        - name: scripts
          mountPath: /scripts
      volumes:
      - name: scripts
        configMap:
          name: {{ .Release.Name }}-init-script
      restartPolicy: Never
      serviceAccountName: {{ .Release.Name }}-init-sa

高级技巧

条件执行钩子

{{- if .Values.migration.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-migration
  annotations:
    "helm.sh/hook": post-upgrade
spec:
  template:
    spec:
      containers:
      - name: migration
        image: {{ .Values.migration.image }}
        {{- with .Values.migration.command }}
        command: {{ . }}
        {{- end }}
      restartPolicy: Never
{{- end }}

钩子与 ConfigMap/Secret 配合

# templates/hooks/_helpers.tpl
{{- define "hooks.wait-for-service" -}}
{{- printf "until curl -f http://%s/health; do sleep 5; done" .Values.service.name }}
{{- end }}
# templates/hooks/post-install.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-wait
  annotations:
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "0"
spec:
  template:
    spec:
      containers:
      - name: health-check
        image: curlimages/curl
        command: ["/bin/sh", "-c"]
        args: 
        - |
          {{ include "hooks.wait-for-service" . }}
      restartPolicy: Never

钩子超时控制

values.yaml 或安装时设置:

helm install myapp . --timeout 600s
# 或
helm upgrade myapp . --timeout 10m --atomic

最佳实践

  1. 幂等性设计:确保钩子脚本可以安全重复执行
  2. 错误处理:使用 set -e 和适当的错误处理
  3. 资源清理:合理设置 hook-delete-policy 避免资源泄漏
  4. 权限最小化:为钩子使用专用的 ServiceAccount
  5. 日志记录:确保输出有意义的日志
  6. 测试验证:通过 helm test 验证钩子功能

常见问题

钩子不执行?

  • 检查注释语法(helm.sh/hook:"helm.sh/hook":
  • 确认钩子资源类型支持(通常用 Job)
  • 查看 helm install --debug 输出

钩子执行失败?

# 查看当前 Release 状态
helm status myapp --show-resources
# 查看失败的 Job Pod 日志
kubectl logs -l job-name=myapp-hook-job-name

钩子资源没清理?

# 手动清理
kubectl delete job <job-name>

使用 Helm 钩子可以优雅地处理复杂的部署流程,但要确保脚本健壮且可重入。

抱歉,评论功能暂时关闭!