Helm部署PostgreSQL后执行数据库迁移再部署服务的配置问题
问题描述
我正在制作一个小型Helm Chart,包含以下组件:
- 依赖PostgreSQL
- 执行数据库Schema迁移的小型应用
- 依赖已完成迁移数据库的REST API服务
需要满足以下执行顺序:
- PostgreSQL依赖安装完成并就绪
- 数据库迁移Job执行完成
- REST API服务部署启动
但当前配置的Helm Hook会提前运行,不符合预期。相关配置如下:
Chart.yaml
apiVersion: v2 name: apicentral description: A Helm chart for Kubernetes # A chart can be either an 'application' or a 'library' chart. # # Application charts are a collection of templates that can be packaged into versioned archives # to be deployed. # # Library charts provide useful utilities or functions for the chart developer. They're included as # a dependency of application charts to inject those utilities and functions into the rendering # pipeline. Library charts do not define any templates and therefore cannot be deployed. type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) version: 0.1.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. appVersion: '1.16.0' dependencies: - name: postgresql version: "16.0.1" repository: "https://charts.bitnami.com/bitnami"
db-migrations.yaml
apiVersion: batch/v1 kind: Job metadata: name: "apicentral-db-migrate-{{ now | unixEpoch }}" annotations: "helm.sh/hook": pre-install,pre-upgrade "helm.sh/hook-weight": "0" "helm.sh/hook-delete-policy": before-hook-creation spec: backoffLimit: 5 activeDeadlineSeconds: 300 template: spec: restartPolicy: Never containers: - name: apicentral-db-migrate image: "{{ .Values.apicentral.postgres.schemaMigrationApp }}" args: - "/app/index.js" - "up" - "-h" - "{{ .Values.apicentral.postgres.host }}" - "-p" - "{{ .Values.apicentral.postgres.port }}" - "-d" - "{{ .Values.apicentral.postgres.database }}" - "-u" - "{{ .Values.apicentral.postgres.username }}" - "-P" - "{{ .Values.apicentral.postgres.password }}"
解决方案
要修复Hook提前运行的问题,需从Hook顺序控制、数据库就绪检查、服务依赖迁移三个维度调整配置:
1. 调整Hook类型与权重
默认pre-install/pre-upgrade Hook会在资源渲染完成后立即执行,不会等待PostgreSQL就绪。改用post-install/post-upgrade并设置更高权重,确保迁移Job在PostgreSQL依赖的Hook之后启动:
修改db-migrations.yaml的注解部分:
metadata: name: "apicentral-db-migrate-{{ now | unixEpoch }}" annotations: "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-weight": "1" # Bitnami PostgreSQL默认Hook权重为0,确保迁移在其之后执行 "helm.sh/hook-delete-policy": before-hook-creation "helm.sh/hook-timeout": "5m" # 设置超时时间,避免无限等待
2. 添加PostgreSQL就绪检查
在迁移Job中加入initContainers,确保数据库端口开放且可连接后,再执行迁移脚本:
方式一:使用busybox端口探测
spec: backoffLimit: 5 activeDeadlineSeconds: 300 template: spec: restartPolicy: Never # 添加初始化容器等待PostgreSQL initContainers: - name: wait-for-postgres image: busybox:1.36 command: - sh - -c - | until nc -z {{ .Values.apicentral.postgres.host }} {{ .Values.apicentral.postgres.port }}; do echo "Waiting for PostgreSQL port to open..." sleep 2 done containers: - name: apicentral-db-migrate image: "{{ .Values.apicentral.postgres.schemaMigrationApp }}" args: - "/app/index.js" - "up" - "-h" - "{{ .Values.apicentral.postgres.host }}" - "-p" - "{{ .Values.apicentral.postgres.port }}" - "-d" - "{{ .Values.apicentral.postgres.database }}" - "-u" - "{{ .Values.apicentral.postgres.username }}" - "-P" - "{{ .Values.apicentral.postgres.password }}"
方式二:使用PostgreSQL客户端做就绪验证(更严谨)
initContainers: - name: wait-for-postgres image: bitnami/postgresql:16.0.1 command: - sh - -c - | until pg_isready -h {{ .Values.apicentral.postgres.host }} -p {{ .Values.apicentral.postgres.port }} -U {{ .Values.apicentral.postgres.username }} -d {{ .Values.apicentral.postgres.database }}; do echo "Waiting for PostgreSQL to be fully ready..." sleep 2 done env: - name: PGPASSWORD value: "{{ .Values.apicentral.postgres.password }}"
3. 让API服务依赖迁移Job完成
在API服务的Deployment中添加initContainers,等待迁移Job执行成功后再启动服务:
步骤1:给迁移Job添加固定标签
修改db-migrations.yaml的metadata,添加便于筛选的标签:
metadata: name: "apicentral-db-migrate-{{ now | unixEpoch }}" labels: app: apicentral-db-migrate annotations: # ... 现有注解
步骤2:API服务添加等待逻辑
# API服务的Deployment模板示例 apiVersion: apps/v1 kind: Deployment metadata: name: apicentral-api spec: replicas: 1 template: spec: initContainers: - name: wait-for-migration image: bitnami/kubectl:1.28.3 command: - sh - -c - | until kubectl get jobs -l app=apicentral-db-migrate -o jsonpath='{.items[*].status.succeeded}' | grep -q "1"; do echo "Waiting for database migration to finish..." sleep 2 done containers: - name: apicentral-api image: "{{ .Values.apicentral.api.image }}" ports: - containerPort: 8080
关键说明
- Hook权重逻辑:Helm会按权重从小到大执行Hook,Bitnami PostgreSQL的默认Hook权重为0,设置迁移Job权重为1可确保执行顺序。
- 就绪检查必要性:即使PostgreSQL Pod启动,数据库可能仍处于初始化状态,initContainer能避免迁移脚本因连接失败而报错。
- 服务依赖保障:通过initContainer等待迁移Job的
succeeded状态,确保API服务启动时数据库Schema已完全就绪。
内容的提问来源于stack exchange,提问作者Kamil Janowski
相关产品推荐
相关产品推荐

