Kubernetes滚动部署和数据库迁移

Gay*_*ewa 27 kubernetes

使用数据库迁移处理滚动更新时,kubernetes如何处理此问题?

对于一个实例 - 我有一个应用程序,从app-v1更新到app-v2,其中包括一个用于更改现有表的迁移步骤.所以这意味着它需要我在db:migrate部署后运行类似于rails应用程序的东西.

在3副本集上进行滚动部署时.它将从一个pod部署到另一个pod.可能允许没有新版本应用程序的POD中断.

虽然这种情况不是经常发生的事情.它很可能会.我想了解这种情况的最佳/推荐方法.

mbu*_*ann 15

防止旧版本破坏的一种方法是将迁移分成多个步骤.

例如,您要重命名数据库中的列.直接重命名列会破坏应用程序的旧版本.这可以分为多个步骤:

  • 添加插入新列的数据库迁移
  • 更改应用程序,以便所有写入都转到旧列和新列
  • 运行将所有值从旧列复制到新列的任务
  • 更改它从新列中读取的应用程序
  • 添加删除旧列的迁移

不幸的是,这很麻烦,但可以防止维护页面出现停机.

  • 这是一篇很好的文章,解释了这个想法:https://spring.io/blog/2016/05/31/zero-downtime-deployment-with-a-database (2认同)

tse*_*van 5

Kubernetes本身不会通过数据库迁移来处理滚动更新。这是特定于应用程序的,因此应用程序开发人员将必须处理它。您可能必须执行与非k8s设置相同的操作。

无论如何,我会这样做:

  • 将副本缩放到1。
  • 更新图像。
  • 将副本缩放到3。

这不是万无一失的,但不涉及代码更改。在db:migrate步骤与实际服务器侦听之间有一个小窗口,在该窗口中,请求将发送到较旧的副本(新副本就绪后将终止)。该请求可能失败也可能不会失败,具体取决于代码块是否与架构更改直接相关。

如果我不太关心停机时间,那么我将使用重新创建策略。


Den*_*s V 5

我最近正在解决这个问题,这是我的方法:

  • 使用部署注释来存储您通常需要在部署之前或之后运行的命令。
  • 创建一个脚本,该脚本将能够按名称读取您的部署,然后创建一个作业来运行部署注释中指定的命令。
  • 将图像推送到 docker 注册表时,添加一个 webhook,它将调用您在上一点中指定的脚本。
  • 为避免不兼容的数据库结构出现问题:
    • 不要以向后不兼容的方式修改 db 列。
    • 不要在迁移中立即删除未使用的列。你可以在下一个版本中做到这一点。这样,您将只有一个将在部署之前运行的迁移脚本。

PS 为了能够在您的脚本中使用 Kubernetes,您可能需要熟悉以下链接:Kubernetes API Kubernetes API 概述使用 Kubernetes API 的访问集群客户端库