使用 helm 进行数据库迁移
DB Migration with helm
我正在尝试迁移我们的 cassandra 表以使用 liquibase
。基本上这个想法是微不足道的,有一个 pre-install
和 pre-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 }}"
我正在尝试迁移我们的 cassandra 表以使用 liquibase
。基本上这个想法是微不足道的,有一个 pre-install
和 pre-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 }}"