在将新版本的应用部署到Kubernetes群集之前,我想要运行数据库迁移。我希望这些迁移作为Continuous Delivery管道的一部分自动运行。迁移将封装为容器映像。什么是实现这一目标的最佳机制?
解决方案的要求:
我曾认为Kubernetes中的Jobs功能会让这很容易,但似乎有一些挑战:
restartPolicy
never
。使用"裸豆荚"是一个更好的方法?如果是这样,那该怎么办?
答案 0 :(得分:9)
您可以尝试通过执行以下操作使迁移作业和应用程序彼此独立:
结合这两种设计方法,您应该能够彼此独立地开发和执行迁移作业和应用程序,而不必引入任何时间耦合。
这个想法实际上是否合理,取决于您的案例的更具体细节,例如数据库迁移工作的复杂性。正如您所提到的,另一种方法是将非托管pod部署到执行迁移的集群中。这需要更多的布线,因为您需要定期检查结果并区分成功和失败的结果。
答案 1 :(得分:5)
在等待排队作业的结果时阻塞似乎需要手动滚动脚本
借助kubectl wait
命令,不再需要此操作。
这是我在CI中运行数据库迁移的方式:
kubectl apply -f migration-job.yml
kubectl wait --for=condition=complete --timeout=60s job/migration
kubectl delete job/migration
万一发生故障或超时,前两个CLI命令之一将返回错误的退出代码,然后强制其余CI管道终止。
migration-job.yml
描述了配置了Job
和相当低的restartPolicy: Never
的kubernetes activeDeadlineSeconds
资源。
您也可以使用spec.ttlSecondsAfterFinished
attribute来代替手动运行kubectl delete
,但这在撰写本文时仍处于Alpha状态,并且至少不受Google Kubernetes Engine支持。
答案 2 :(得分:2)
考虑到这个问题的年龄,我不确定当时是否有initContainers
可用,但现在它们非常有用。
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
我最近设置的方式是让postgres
pod和我们的django
应用程序在同一名称空间中运行,但django
pod有3 initContainers
:
这样做会同时运行django
窗格和postgres
窗格,但也会持续运行initContainers
,直到postgres
窗格出现,然后再迁移应该跑。
至于pods不断重启,也许他们现在已经修复了restartPolicy
。我目前对kubernetes很新,但我发现这对我有用。