求助:如何编写Helm Hook检查Release存在性及修订版本?
实现Helm预安装/升级Hook:检查Release存在性及修订版本
你需要的是pre-install和pre-upgrade阶段的Helm Hook Job,用来检查目标Release是否存在,同时可选验证修订版本。以下是完整实现方案:
完整Hook Job配置
apiVersion: batch/v1 kind: Job metadata: name: "{{ .Release.Name }}-pre-check" 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: "helm.sh/hook": pre-upgrade,pre-install "helm.sh/hook-weight": "-5" "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation spec: template: metadata: name: "{{ .Release.Name }}-pre-check" labels: app.kubernetes.io/managed-by: {{ .Release.Service | quote }} app.kubernetes.io/instance: {{ .Release.Name | quote }} helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" spec: # 若集群启用RBAC,需指定具备权限的ServiceAccount(需提前创建) # serviceAccountName: helm-hook-sa restartPolicy: OnFailure containers: - name: release-checker # 使用包含helm和jq的镜像,方便解析版本信息 image: alpine/helm:3.12.0 command: - sh - -c - | # 安装jq用于解析helm输出 apk add --no-cache jq RELEASE_NAME="{{ .Release.Name }}" NAMESPACE="{{ .Release.Namespace }}" # 检查Release是否存在 if helm list -n "${NAMESPACE}" -q | grep -q "^${RELEASE_NAME}$"; then echo "✅ Release ${RELEASE_NAME} exists in namespace ${NAMESPACE}" # 获取当前最新修订版本和已安装Chart版本 CURRENT_REVISION=$(helm history "${RELEASE_NAME}" -n "${NAMESPACE}" --max 1 -o json | jq -r '.[0].revision') INSTALLED_CHART_VERSION=$(helm show all "${RELEASE_NAME}" -n "${NAMESPACE}" | grep "^version:" | awk '{print $2}') TARGET_CHART_VERSION="{{ .Chart.Version }}" echo "📊 当前修订版本: ${CURRENT_REVISION}" echo "📦 已安装Chart版本: ${INSTALLED_CHART_VERSION}" echo "🎯 待安装Chart版本: ${TARGET_CHART_VERSION}" # 可选:添加版本校验逻辑,比如禁止降级 # if [ "$(printf '%s\n' "${TARGET_CHART_VERSION}" "${INSTALLED_CHART_VERSION}" | sort -V | head -n1)" != "${TARGET_CHART_VERSION}" ]; then # echo "❌ 待安装版本低于已安装版本,终止操作" # exit 1 # fi else echo "🔍 Release ${RELEASE_NAME} 不存在,将执行全新安装" fi
关键配置说明
Hook注解
helm.sh/hook: pre-upgrade,pre-install:指定Job在安装和升级操作前触发hook-weight: "-5":确保这个Hook比其他预操作Hook更早执行(数值越小优先级越高)hook-delete-policy:Hook执行成功后自动删除,且创建新Hook前清理旧实例,避免资源残留
容器逻辑
- 基于
alpine/helm镜像,自带helm CLI,安装jq用于解析JSON格式的helm输出 - 核心逻辑:
- 通过
helm list检查Release是否存在 - 若存在,提取当前修订版本和已安装Chart版本,与待安装版本对比
- 可自定义版本校验规则(比如禁止版本降级)
- 通过
- 基于
RBAC权限配置
如果集群启用RBAC,需给Hook Job的ServiceAccount赋予读取Secrets的权限(Helm 3将Release元数据存储在Secrets中),示例如下:# templates/rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: helm-hook-sa annotations: "helm.sh/hook": pre-upgrade,pre-install "helm.sh/hook-delete-policy": hook-succeeded --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: helm-hook-role annotations: "helm.sh/hook": pre-upgrade,pre-install "helm.sh/hook-delete-policy": hook-succeeded rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: helm-hook-binding annotations: "helm.sh/hook": pre-upgrade,pre-install "helm.sh/hook-delete-policy": hook-succeeded subjects: - kind: ServiceAccount name: helm-hook-sa roleRef: kind: Role name: helm-hook-role apiGroup: rbac.authorization.k8s.io
轻量替代方案(无需helm CLI)
如果不想依赖helm镜像,可直接通过Kubernetes Secrets检查Release存在性:
# 替换上述Job的containers部分 containers: - name: release-checker image: busybox:1.36 command: - sh - -c - | RELEASE_NAME="{{ .Release.Name }}" NAMESPACE="{{ .Release.Namespace }}" # 检查是否存在对应Release的Secrets if kubectl get secrets -n "${NAMESPACE}" -l "owner=helm,name=${RELEASE_NAME}" > /dev/null 2>&1; then echo "✅ Release ${RELEASE_NAME} exists" # 提取最新修订版本 LATEST_REVISION=$(kubectl get secrets -n "${NAMESPACE}" -l "owner=helm,name=${RELEASE_NAME}" -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | grep -E "sh\.helm\.release\.v1\..*\.v[0-9]+" | sort -Vr | head -n1 | awk -F'.v' '{print $NF}') echo "📊 最新修订版本: ${LATEST_REVISION}" else echo "🔍 Release ${RELEASE_NAME} 不存在,执行全新安装" fi
内容的提问来源于stack exchange,提问作者I__sh
相关产品推荐
相关产品推荐

