如何使用Kubernetes和Skaffold处理数据库迁移

时间:2019-04-13 02:12:27

标签: docker flask kubernetes skaffold

问题:

在本地,我使用Skaffold(Kubernetes)来热重载代码的客户端和服务器端。当我关闭它时,它将删除我的服务器Pod,包括我的/ migrations /文件夹,因此与我的数据库alembic_version不同步。在生产中,我没有删除服务器Pod,但是在部署时正在重建docker映像,这导致替换了/ migrations /文件夹。

问题

我该如何处理这些迁移,以免数据库不同步?


应用程序设置

Flask / Python API并使用Flask Migrate。对于那些不熟悉的人,它要做的是创建一个带有5a7b1a44a69a_.py之类的版本文件的迁移文件夹。该文件的内部是def upgrade()downgrade()来操作数据库。它还在我的postgres窗格中记录了alembic_version表的修订和down_revision参考。

Kubernetes和Docker设置

我有一个服务器容器和postgres容器。我登录到服务器容器的外壳以运行迁移命令。它会在docker容器内创建版本文件并更新数据库。

逐步展示该问题的示例:

  1. sh进入服务器部署窗格并运行db init。
  2. 迁移文件夹已创建。
  3. 在服务器部署上执行迁移,以创建迁移文件并更新数据库。
  4. postgres pod db获得alembic_version输入并进行更新。
  5. 使用skaffold删除或ctrl-c skaffold。
  6. 服务器部署窗格被删除,但postgres未被删除。迁移文件夹消失。
  7. 启动skaffold备份,然后进入服务器部署窗格并尝试运行db migration。要求您进行数据库初始化。
  8. 如果您尝试从此处降级,则不会执行任何操作。现在,服务器Pod和Postgres Pod在alembic_version方面是不同步的。

最终提示

我以前在docker / kubernetes之前所做的工作是在本地运行的,我会将那个迁移版本文件提交到我的仓库中。它已在所有环境中同步,因此每个人的回购都在同一alembic_version上。我考虑过创建一个单独的,始终在线的“ migrations-deployment”吊舱,它是flask的另一个实例,因此它永远不会丢失/ migrations /文件夹。但是,这似乎是一个非常糟糕的解决方案。


希望获得最佳实践或想法!

1 个答案:

答案 0 :(得分:0)

我想出了一种解决方法。在其他人确认这是一个好方法之前,我不会将其设置为正确的答案。

基本上,我所做的是创建一个持久量声明。在服务器部署内部,我将migrations /文件夹连接到该永久卷。这样,无论何时删除Pod,迁移/文件夹都会保留并在Pod重新启动后保持不变。

在服务器部署中看起来像这样。

      containers:
      ..........
        volumeMounts:
          - name: migrationstuff
            mountPath: 'MyServerApplicationDirectory/migrations'
      volumes:
        - name: migrationstuff
          persistentVolumeClaim:
            claimName: migrate-pvc

PVC看起来像这样:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: migrate-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

对于那些决定采用长颈瓶迁移的方法,存在一个棘手的“鸡还是蛋”问题。当您运行flask db init时,它会在其中创建包含某些内容的migrations /文件夹。但是,如果有一个PVC创建了一个空的migrations /文件夹,则烧瓶迁移已经认为该文件夹存在。您也无法使用rmdir删除该文件夹,因为该文件夹上有正在运行的进程。但是,您需要将flask migration init命令的内容放入空的migrations /文件夹中.....

我发现的窍门是:

python flask db init --directory migration
mv migration/* migrations/

这会将您需要的所有文件初始化为一个新的“迁移”文件夹。然后,将其全部复制到migrations /文件夹中,然后再继续保存。如果省略--directory标志,则Flask migration会自动查找该文件夹。

然后删除迁移文件夹rmdir migration(或等到pod重新启动后再消失)。

您现在拥有一个包含所有内容的适当的migrations /文件夹。当关闭烧瓶吊舱并重新启动时,PVC注入将迁移文件/文件夹填充回吊舱。我现在可以升级/降级。只需注意不要删除pvc!