在高复制的K8部署中安全管理数据库迁移。
#网络开发人员 #php #kubernetes #migrations

因此,您想在运行Kubernetes群集的云本机应用程序中运行迁移,并且不要死尝试!

好吧,您在正确的位置!!

在多复制品和并发部署过程中,我在数据库迁移方面破坏了一些应用程序后,我想根据我的错误向您提供一些建议,如何以安全的方式运行您的迁移,并使用本机k8s规格为您提供迁移而且没有任何黑客。 (没有helm,否external deployers,纯和plaink8s流程精心策划)

问题

非常普遍,现代应用程序会更快地发展,新功能由产品满足最终用户而产生,并且每个新部署都非常普遍,需要以某种形式更改数据库,并且您拥有许多工具来允许您允许您管理针对数据库的迁移执行,但不是在发生时。

如果您有一个应用程序POD,请说使用4个副本,然后部署它,所有4将尝试同时运行迁移,并可能导致数据损坏和数据丢失,没有人想要。

何时运行迁移(the workflow)

在运行迁移的old-way中,我们曾经有类似的东西:

  • 将应用程序放入maintenance mode(将流量转移到特殊页面)
  • 运行数据库迁移
  • 部署新基本代码
  • 应用程序上禁用维护模式

显然,如果您想在实际的始终世界中实现zero-downtime部署,这是不可接受的方法,我们需要实现(在leats)以下步骤以确保迁移和应用程序以安全方式运行。

  • 在应用程序的旧版本仍在运行时运行迁移,并在成功运行迁移时进行滚动更新。

类似的东西:

Pipeline + cluster proposals-2.jpg

JobInitContainerRollingUpdates11

因此,在选择我们在k8s上运行migrations的策略之后,我们需要编写清单才能完成定义的工作流程。

首先,迁移作业本身:

apiVersion: batch/v1
kind: Job
metadata:
  name: availability-api-migrations
spec:
  ttlSecondsAfterFinished: 60
  backoffLimit: 1
  template:
    spec:
      containers:
        - name: migrations
          image: availability-api-migrations
          command:
            - '/bin/sh'
            - '-c'
            - ' bin/console doctrine:migrations:migrate --no-interaction -v'
          envFrom:
            - secretRef:
                name: protected-credentials-from-vault
      restartPolicy: Never

现在,在应用程序的部署清单中,我们需要定义2件事,对于允许我们的工作流程工作非常重要。

  • 滚动更新策略
  • 初始容器和命令禁止部署初始化,直到完成迁移。
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 0
   template:
      spec:
        initContainers:
          - name: wait-for-migrations-job
            image: bitnami/kubectl:1.25
            command:
              - 'kubectl'
            args:
              - 'wait'
              - '--for=condition=complete'
              - '--timeout=600s'
              - 'job/availability-api-migrations'

上面的该片段的含义是什么:

  • RollingUpdate策略:
    • 滚动更新允许我们定义我们要一次使用新代码更新多少个POD复制品的策略(您还可以在其他k8s策略之间进行选择,例如recreateblue/greencanary
  • InitContainer迁移工作观察者
    • 现在,我们希望以某种方式开始推出部署,直到迁移作业以完成状态完成为止。幸运的是,kubectl cli工具允许我们询问并等待k8s组件的状态,我们使用Kubelete API的优势在这里使用,并以某种方式“阻止”
$kubectl wait --for-condition=complete --timeout=600 job/availability-api-migrations

我们等待availability-api-migrations状态的工作,并拥有timeout o五分钟,kubectl将永久询问直到超时为止。显然,如果迁移作业在那里完成毫秒,则会自动等待循环结束并允许部署开始,否则部署将失败。超时是最大允许的时间等待在作业上要求完整的状态。

至少这样,我们可以保证数据一致性是保留的,但是对于如何在您的应用程序中编写和部署迁移方面,它遵循一些准则,下面我们将介绍。

安全建议

  • 写下您的迁移总是在快速执行中思考,如果您期望运行花费超过5分钟的迁移,请考虑要求使用维护窗口以限制对应用程序的流量访问。
  • 您的迁移始终考虑在生产中运行当前代码的复古兼容性。
    • 例如,请勿更改表格添加列不可为无效或没有默认值的表。
  • 如果您需要添加一列并删除其他,那么遵循的最佳策略是进行2个分开部署。
    • 运行第一个部署添加列,并验证所有在生产中的运行顺利。
    • 运行新部署仅从数据库中删除旧列。

支持我

如果您喜欢刚刚阅读的内容,并且发现它很有价值,那么您可以通过单击下图中的链接来给我买咖啡,这将不胜感激。

Buy Me A Coffee