使用 helm 进行数据库迁移

DB Migration with helm

我正在尝试迁移我们的 cassandra 表以使用 liquibase。基本上这个想法是微不足道的,有一个 pre-installpre-upgrade 的工作,它将 运行 一些 liquibase 脚本并将管理我们的数据库升级。

为此,我创建了一个自定义 docker 图像,它将具有实际的 liquibase cli,然后我可以从作业中调用它。例如:

apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ .Release.Name }}-update-job"
  namespace: spring-k8s
  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": pre-install, pre-upgrade
    "helm.sh/hook-weight": "5"
    "helm.sh/hook-delete-policy": before-hook-creation
spec:
  template:
    metadata:
      name: "{{ .Release.Name }}-cassandra-update-job"
      namespace: spring-k8s
      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: pre-install-upgrade-job
          image: "lq/liquibase-cassandra:1.0.0"
          command: ["/bin/bash"]
          args:
            - "-c"
            - "./liquibase-cassandra.sh --username {{ .Values.liquibase.username }} --password {{ .Values.liquibase.username }} --url {{ .Values.liquibase.url | squote }} --file {{ .Values.liquibase.file }}"

其中 .Values.liquibase.file == databaseChangelog.json.

所以这个图像 lq/liquibase-cassandra:1.0.0 基本上有一个脚本 liquibase-cassandra.sh 当传递一些参数时可以发挥它的魔力并更新数据库模式(不打算深入细节)。

问题是最后一个参数:--file {{ .Values.liquibase.file }}。显然,此文件位于 而非 中,而是位于每个微服务存储库中。

我需要一种将该文件“复制”到图像的方法,以便我可以调用它。一种方法是始终构建此 lq/liquibase-cassandra(与项目本身具有相同的生命周期)并将文件复制到其中,但这将花费时间并且看起来至少很麻烦。我错过了什么?

事实证明,helm 钩子可以用于其他事情,而不仅仅是工作。因此,我可以将此文件装载到 ConfigMap 之前 作业甚至开始(我关心的文件驻留在 resources/databaseChangelog.json 中):

apiVersion: v1
kind: ConfigMap
metadata:
  name: "liquibase-changelog-config-map"
  namespace: spring-k8s
  annotations:
    helm.sh/hook: pre-install, pre-upgrade
    helm.sh/hook-delete-policy: hook-succeeded
    helm.sh/hook-weight: "1"
data:
{{ (.Files.Glob "resources/*").AsConfig | indent 2 }}

然后在作业中引用它:

  .....
  spec:
  restartPolicy: Never
  volumes:
    - name: liquibase-changelog-config-map
      configMap:
        name: liquibase-changelog-config-map
        defaultMode: 0755
  containers:
    - name: pre-install-upgrade-job
      volumeMounts:
        - name: liquibase-changelog-config-map
          mountPath: /liquibase-changelog-file
      image: "lq/liquibase-cassandra:1.0.0"
      command: ["/bin/bash"]
      args:
        - "-c"
        - "./liquibase-cassandra.sh --username {{ .Values.liquibase.username }} --password {{ .Values.liquibase.username }} --url {{ .Values.liquibase.url | squote }} --file {{ printf "/liquibase-changelog-file/%s" .Values.liquibase.file }}"