在项目迭代的过程中,我们经常会进行更新线上代码的操作,而更新的操作我们会希望影响的用户越少越好,最好是能做到零停机更新。

在目前云原生的大背景下,K8s 的滚动更新策略会更为人知一些,但是一些中小型项目的部署建立一套 K8s 服务从成本和收益的角度来看是有些得不偿失的。

本文介绍用 DockerTraefik 如何实现零停机升级服务。关于 Traefik更靠近云原生的反向代理神器-Traefik 一文中有更详细的介绍。

整个服务部署流程如下 zero downtime

本方案通过 gitlab CI/CD 来进行部署,开发人员仅需在对应的分支提交代码,服务器会自动完成 构建 -> 部署 -> 通知 等操作。 蓝绿发布流程

部署 阶段通过蓝绿发布的方式来进行零停机升级的。

蓝绿发布是通 shell 脚本进行操作的,由于 Traefikdocker provider 不支持动态的增删服务,本方案采取了 file provider,shell 会启动新服务的时候修改Traefikfile provider 来把新服务加入到负载均衡的集群,并在新服务启动完成后,把老服务从负载均衡迁出并停用老服务。

得益于 Traefik 对动态配置的支持,所有对配置文件的修改是无需重启 Traefik,它会自动发现配置文件的变动,把最新的配置加载到程序内部。

整个 部署 流程中始终都会有容器在线提供服务,我们也就实现了零停机升级系统的目标。

本文最后会附上一份完整的 demo 链接,感兴趣的可以下载之后运行一下了解整个操作机制。

本方案还存在一些局限,如蓝绿发布其实是 blue 和 green 交替提供服务,如果你本身是一个服务集群,这个方案并不能很好的适应。

如果你面临上述问题可以考虑 docker swarm 来解决问题,或者部署 K8s,其间的选择主要是看你服务的规模。

本文到此基本结束,如果你更好的想法,欢迎留言讨论。

示例代码:https://github.com/yunxi177/zero-downtime

References

zero-downtime deploys with Docker Compose and Traefik:https://github.com/maxcountryman/aquamarine