技术开发 频道

如何在Kubernetes部署期间正确处理DB模式

  【IT168 技术】本文介绍了如何在Kubernetes部署期间正确处理数据库模式,及其体系结构的功能特点。如果,您已经决定迁移到Kubernetes,但是不确定如何安全地推出微服务副本,同时还要协调对底层数据库架构的更改,那就请参考本文内容。

  大纲:

  1.Kubernetes的功能

  2.最受欢迎的数据迁移库

  3.简单、易用的工程实践

  正文:

  Architecture(架构)

  让我们思考一下以下“two-tier”场景。

  •   一个具有多个无状态微服务副本的“应用程序层”

  •   一个具有一个数据库的“数据库层”(在实际生产中,为了冗余可能还有多个副本)

  •   有一个用于创建和读取用户的API

  •   “数据库层”负责数据持久化

  实施:自顶向下

  Services(服务)

  上图所示的应用层和数据库层通过底层服务实现,Services本质提供:

  •   DNS名称,以便可以轻松将请求发送到“tier”

  •   将请求透明路由到底层Pods

  Pods

  微服务和数据库的运行都是在一个封闭的容器内,以达到资源隔离。这些容器本身封装在Pods中,Pods是Kubernetes中最小的可部署单元。

  Deployments(部署)

  配置Pod副本的数量以及其生命周期的管理是由部署完成的,这是我们解决问题需要注意的一点。

  Database Migrations(数据库迁移)

  但当您更改微服务代码时,您还需要更改数据模式使其适配。一个简单的方法就是通过数据库迁移。步骤如下:

  •   将您的架构版本化;

  •   将每个更改写入专用脚本(也被称为“migration”)模式中,该脚本可以通过版本号识别;

  •   将所有的脚本与代码打包;

  •   在启动时,检查您的架构版本,如果它已经过期,应用必要的迁移,以便与模式匹配。

  这种方法的优点:

  •   简单:在运行时不会引入新的移动基础架构;

  •   易于部署:在开发、测试和生产阶段,您都将拥有正确的版本模式。

  目前效果

  Kubernetes让我们很容易的就实现了上述设置,它为我们完成了很多复杂工作,将整个工序简化了很多。

  实际上,上面描述的整个“应用程序层”基本上都是在以下两个YAML清单中配置的:

  但是,上面的内容并不能提供所有您需要的特性,您也许想问如下一些问题:

  •   在部署新版本期间会发生什么?会出现宕机吗?容量如何变化?

  •   如果犯了一个错误,新版本在部署时崩溃怎么办?

  •   如果微服务在运行一段时间后崩溃,会发生什么?

  •   如果需要回滚应该怎样做?

  现在就让我们解答一下这些问题:

  实施:细节决定成败!

  Rolling Out(推出)

  默认情况下,Kubernetes使用“rolling update”策略部署Pod,一次删除1个旧Pod(maxUnavailable: 1)并添加1个新Pod(maxSurge: 1),这意味着有3个副本,在滚动新版本时,您将暂时失去33%的能力去服务终端用户。

  让我们通过将maxUnavailable更改为0来解决此问题。首先,Kubernetes将部署一个新的Pod,并且只有在部署成功时才能删除旧的Pod。但缺点是,集群中需要备用的容量来临时运行这个额外的副本,所以如果您容量已满,则可能需要添加额外的节点。

  但优点是,理论上零停机不会对终端用户产生影响。

  Readiness(准备就绪)

  当Kubernetes认为它已经“准备好(ready)”时,它会在其服务器的负载均衡中添加一个Pod。默认情况下,“ready”只意味着Pod的所有容器已经启动,Kubernetes可以执行它们。但是,如果要建立数据库的连接,并在启动时运行模式迁移,可能会需要一段时间,很显然我们需要更好的定义"ready"。

  从业务的角度看,我们的微服务已经准备就绪,可以开始响应终端用户的请求。因此,我们可以通过配置 HTTP readinessProbe将确切的信息告诉Kubernetes 。此外,我们需要在启动HTTP服务器之前创建数据库连接并运行迁移。

  一般来说,在每个Pod推出后稍等片刻也不是什么坏事。

  现在,如果我们在启动时崩溃了,或者无法连接到数据库,新部署失败的Pod将不会被添加到“应用程序层”的负载均衡中,而rollout将在那里停止。这意味着,即使在这个阶段出现问题也不会影响到最终用户。

  Liveness(活跃度)

  Kubernetes还会定期检查Pod是否还“活着”,默认情况下也是如此。在我们的示例中,如果数据库客户端以某种方式进入损坏状态,我们也许希望Kubernetes从负载均衡器中删除受影响的pod,然后启动一个新的。这可以通过添加检查(理想情况下,会代表系统的健康状况)、将其揭示给Kubernetes或者配置一个livenessProbe来实现。

  Rolling back(回滚)

  但是如果操作失败,你也许想要回滚到最新的工作版本。良好的工程实践可以帮助实现这一点。在我们的场景中,最主要的是我们微服务数据库模式的向后兼容性。

  例如,添加列并明确选择列,我们将可以在最新模式下运行先前版本的微服务,并且允许从v1.1.0平稳回滚到v1.0.0,而无需更改任何模式。

  重命名列将不能向后兼容。在这种情况下,您也许想使用“down migrations”恢复到以前的架构版本。但需要注意的是,前后滚动将打破“零停机时间”。实际上,终端用户会遇到各种暂时性错误,这取决于他们部署的阶段和遇到的副本。如果您不能接受这样的错误,你可能需要先推出一个能够同时支持新旧两种模式的微服务版本(通过拥有两个客户端,选择正确的一个或者同时尝试两个),然后推出具有迁移性的另一个版本,以便进行模式更改。

  这中间可能会出现很多问题,所以需要你仔细测试一下。

  对于大型系统,您可能需要研究“blue-green deployments(蓝绿部署)”,但这实现起来会很困难。

  少说话,多行动!

  想要实现这些设置,可以参考以下建议。

  我们建议使用Weave Cloud,因为它可以使前后滚变得简单易行,并且还可以在您更改系统时提供完整的系统可观性。

  例如,您可以使用Weave Cloud可视化设置:可以在推出新版本的微服务时,确保新副本正在处理流量:

  并且您可以任意查询收集到的指标,并清楚的看到新版本(蓝色垂直线)的影响。

0
相关文章