如何最好地在kubernetes集群中运行一次性迁移任务

Pet*_*son 23 docker kubernetes

在将新版本的应用程序部署到Kubernetes集群之前,我想要运行数据库迁移.我希望这些迁移作为Continuous Delivery管道的一部分自动运行.迁移将封装为容器映像.实现这一目标的最佳机制是什么?

解决方案的要求:

  • 能够确定迁移是否失败,以便我们随后不会尝试将新版本的应用程序部署到群集中.
  • 如果迁移失败则放弃 - 不要继续重试.
  • 能够访问日志以诊断失败的迁移.

我曾假设Kubernetes中的Jobs功能会让这很容易,但似乎有一些挑战:

使用"裸舱"会更好吗?如果是这样,那该怎么办?

Ale*_*ksi 16

在等待排队作业的结果时阻塞似乎需要手动滚动脚本

由于该kubectl wait命令,这不再是必需的。

这是我在 CI 中运行数据库迁移的方式:

kubectl apply -f migration-job.yml
kubectl wait --for=condition=complete --timeout=60s job/migration
kubectl delete job/migration
Run Code Online (Sandbox Code Playgroud)

在失败或超时的情况下,前两个 CLI 命令之一返回错误的退出代码,然后强制其余 CI 管道终止。

migration-job.yml描述了一个Job配置了restartPolicy: Never和一个相当低的 kubernetes资源activeDeadlineSeconds

您也可以使用该spec.ttlSecondsAfterFinished 属性而不是手动运行,kubectl delete但在撰写本文时仍处于 alpha 阶段,至少 Google Kubernetes Engine 不支持。


Tim*_*ann 10

您可以尝试通过执行以下操作使迁移作业和应用程序彼此独立:

  • 即使迁移失败,也可以成功返回迁移作业.将机器可消耗的记录保存在迁移结果的某个位置.这可以显式地(通过,例如,将最新的模式版本写入某个数据库表字段)或隐式地(例如,假设必须已经沿着成功的迁移作业创建特定字段)来完成.如果由于技术原因失败,则迁移作业将仅返回错误代码(由于数据库不可用,应该应用迁移).这样,您可以通过Kubernetes Jobs进行迁移,并依赖其最终运行完成的能力.
  • 构建了新的应用程序版本,以便它可以在迁移前和迁移后阶段使用数据库.这意味着什么取决于您的业务需求:应用程序可以在迁移成功完成之前转为空闲,或者根据当前阶段可能会向客户端返回不同的结果.这里的关键点是应用程序处理迁移作业之前生成的迁移结果,并相应地执行操作而不会错误地终止.

结合这两种设计方法,您应该能够独立地开发和执行迁移作业和应用程序,而不必引入任何时间耦合.

这个想法是否合理实施取决于您的案例的更具体细节,例如数据库迁移工作的复杂性.正如您所提到的,另一种方法是将非托管pod部署到执行迁移的集群中.这需要更多的布线,因为您需要定期检查结果并区分成功和失败的结果.