Docker应用程序实时升级

问题描述:

我是新来的docker,并且在涉及docker时设计一个简单的实时升级解决方案时遇到一些问题。要求时Docker应用程序实时升级

  • 旧服务器fork()孩子:目前我使用一个fork()/exec()基于模式的应用程序实时升级。
  • 子服务器exec()新的可执行文件,加载新的数据/配置。
  • 旧服务器将必要的信息(套接字,内存数据等)传递给子级服务器,以便它可以接管服务。
  • 旧的服务器在孩子准备好后将停止处理新的请求(旧服务器不会exit() ATM)。
  • 如果升级成功,手动停止旧服务器(这可以在未来升级直播之前被延迟,直到不久),否则停止子服务器,并通知旧服务器重新启动处理请求。

正如您所看到的,这种实时升级策略通常不会造成停机,无论升级是否失败。

我们的大部分服务都是无状态或者有非常简单的状态,所以上面的图案可以轻松实现,这是非常可靠的。

我的问题是如何在Docker中实现上述模式(或类似的东西)?也许我走错了方向,我都是耳朵。

+0

为什么不简单地在服务器前使用负载平衡器? – hek2mgl

+0

@ hek2mgl我们有,如果涉及负载平衡器,升级过程会更长。由于该系统的即时回滚功能,我们可以自动升级整个系统(几乎)。如果在自动升级过程中出现任何问题,我们可以关闭所有新服务器并立即重启旧服务器。 – user416983

当你的服务已经无状态的,并在同一时间处理旧的连接和新的连接,也可以为你服务,使用你的服务的前负载平衡器和某种形式的滚动升级策略是什么可能最适合。

fork方法不适合Docker和容器背后的想法。 Docker镜像及其结果容器应始终包含运行该服务所需的所有内容。另外,如果另一个容器基于相同的图像启动,它应该始终启动完全相同的服务。

在基于叉升级的解决方案,二进制文件/容器内的可执行程序将初始启动后更改。这意味着如果出于任何原因您决定启动基于同一图像的另一个容器,它将不会运行相同版本的服务。当然,您可以添加一些图片,以便在启动时自动升级到最新版本,但这会使部署复杂化。在我看来,这会违反Docker世界中太多的书面和不成文的规则,我会考虑这种不好的做法。

我有这样的感觉,朴素的Docker对于你想使用它的东西是不够的。我建议你看看更高级的容器编排解决方案,它提供了诸如服务负载均衡和滚动更新等功能。当人们有这些更高级的要求时,Kubernetes是我脑中总是首先想到的东西。

通过引入Deployment对象,Kubernetes获得关于更新策略了大量的电能。您应该通读Kubernetes Deployments。如果与适当的健康检查一起使用,Deployment的滚动更新策略应该会为您提供所需的一切,包括回滚失败的部署。

Kubernetes的缺点是需要更多的努力来设置和维护群集。但取决于您的应用程序的大小,基础设施和服务的数量,这可能是值得的。