【问题标题】:Docker application live upgradeDocker 应用实时升级
【发布时间】:2017-02-26 12:55:22
【问题描述】:

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

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

如您所见,无论升级是否失败,这种实时升级策略通常不会导致停机。

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

我的问题是如何在 docker 中实现上述模式(或类似的东西)?也许我走错了方向,我全神贯注。

【问题讨论】:

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

标签: linux docker fork high-availability


【解决方案1】:

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

fork 方法通常不适合 Docker 和容器背后的想法。 Docker 映像和生成的容器应始终包含运行服务所需的一切。另外,如果另一个容器基于同一个镜像启动,它应该总是启动完全相同的服务。

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

我觉得普通的 Docker 不足以满足您的需求。我建议您研究更高级的容器编排解决方案,这些解决方案提供服务负载平衡和滚动更新等功能。当人们有这些更高级的需求时,我总是首先想到 Kubernetes。

随着Deployment 对象的引入,Kubernetes 在更新策略方面获得了很多权力。你应该通读Kubernetes Deployments。如果与适当的健康检查一起使用,Deployment 的滚动更新策略应该可以为您提供所需的一切,包括回滚失败的部署。

Kubernetes 的缺点是设置和维护集群所需的工作量增加。但根据您的应用程序的大小、基础架构和服务的数量,这可能是值得的。

【讨论】:

    猜你喜欢
    • 2018-06-06
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2020-02-26
    • 1970-01-01
    相关资源
    最近更新 更多