Docker应用程序实时升级

我是docker的新手,在docker涉及时devise一个简单的实时升级解决scheme时遇到一些问题。 目前,我正在使用基于fork()/exec()的模式进行应用程序实时升级:

  • 旧的服务器fork()是一个孩子的请求。
  • 子服务器exec()新的可执行文件,加载新的数据/configuration。
  • 旧服务器将必要的信息(套接字,内存数据等)传递给子服务器,以便它可以接pipe服务。
  • 旧服务器在小孩准备就绪后停止处理新请求(旧服务器不会exit() ATM)。
  • 如果升级成功,则手动停止旧服务器(这可能会延迟到下次实时升级之前),否则停止子服务器并通知旧服务器重新启动处理请求。

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

我们的大多数服务都是无状态的,或者状态非常简单,所以上述模式可以很容易实现,而且非常可靠。

我的问题是如何在docker执行上述模式(或类似的东西)? 也许我走错了方向,我是耳朵。

由于您的服务已经是无状态的,同时也可以为您的服务处理旧的连接和新的连接,因此在您的服务前使用负载平衡器,某种滚动升级策略可能最适合。

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

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

我有这样的感觉,简单的Docker是不够的,你想使用它。 我build议你看看更高级的容器编排解决scheme,它提供了诸如服务负载平衡和滚动更新等function。 当人们有这些更高级的要求时,Kubernetes是我首先想到的第一件事情。

随着Deployment对象的引入,Kubernetes在更新策略方面获得了很多权力。 您应该阅读Kubernetes部署 。 如果使用正确的运行状况检查,则Deployment的滚动更新策略应该能够为您提供所需的一切,包括回滚失败的部署。

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

Interesting Posts