无需停机即可更新 Docker 容器

无需停机即可更新 Docker 容器

假设我有一个带有 Web 服务器(如 Apache 2)的 Docker 容器。现在我想更新其下的操作系统。这个 SF 答案说最好的方法是重建基础映像和我的 Apache 映像。但部署映像意味着停机,因为我必须先删除旧容器,然后才能创建新容器,因此只有一个容器绑定到端口 80/443。

但是,如何才能在零停机时间内部署此更新?我应该使用负载均衡器并使用容器间通信吗?如何更新负载均衡器?

答案1

理想的目标情景

是的,您应该使用负载平衡器并一次更新一个实例。我不确定容器间通信从何而来。

举例来说,假设您有一个为站点 A 提供服务的负载均衡器。用户只能以“A”的身份连接到它,并且只知道它是“A”。负载均衡器知道有两个或多个后端(B、C 等),至于它们是虚拟机还是容器并不重要。

然后,您需要升级后端,在本例中是 Apache 实例。

  1. 将 B 从负载均衡器的合格后端中移除,这样它就不再接受任何流量。
  2. 等待当前活动的请求被处理并且现有连接关闭。
  3. 更新为 B 提供服务的容器或底层虚拟机
  4. 重启B,等待其加载并开始工作
  5. 测试 B 以确保它能正确处理新请求
  6. 将 B 添加回负载均衡器后端池以重新启用流量

然后,对 C、D 等执行相同的过程。

请注意Docker 容器就地升级的开放请求,从 2013 年 11 月开始,但似乎没有太大进展,所以上述解决方案是您目前应该做的事情。

对现有的实时网站该做什么

想必您之所以问这个问题,是因为您已经在这种模式下运行了一个实时网站,并且想要在不停机的情况下对其进行升级。因此,我们需要逐步达到上述理想的目标状态。

假设:

  • 您有一个指向容器的 DNS 名称
  • 你的容器在某个 IP 地址上运行
  • 你的用户不知道容器的 IP 地址,并且它没有在任何地方进行硬编码

如果这些假设是错误的,您应该首先修复它以确保其正确。

然后,按照以下步骤操作:

  1. 在新 IP 上创建一个负载均衡器,并将其指向现有容器作为其唯一后端
  2. 将 DNS 更改为指向负载均衡器,而不是直接指向容器 IP
  3. 添加具有相同 VM + 容器设置的相同 Apache 后端
  4. 现在您有一个具有两个后端 B 和 C 的负载均衡器,因此请按照“理想目标场景”部分中的说明一次升级它们

如何更新负载均衡器

简单(托管)方式

最简单的选择是不运行自己的平衡器。例如,如果您正在使用提供负载平衡服务的云平台,请考虑使用它,这样负载平衡器的维护和更新就不是问题了。

手动方式

如果您正在运行自己的负载均衡器,添加另一层间接层(即 DNS)将有所帮助。让我们假设以下内容:

  • 我们有一个主机名,可以解析为负载均衡器 A 的 IP,我们想要更新它
  • 我们的负载均衡器有一个后端池 P1、P2 等。

我们的操作如下:

  • 使用新软件版本创建新的负载均衡器 B
  • 将所有后端池实例 P1、P2 等添加到我们的新负载均衡器 B 作为后端
  • 将 B 的 IP 地址与 A 一起添加到 DNS 解析中

    • 现在我们有效地使用 DNS 作为负载平衡器
    • 如果 A 和 B 的条目未加权,则它们实际上是 50-50
    • 现在观察 B 的表现如何,是否有任何错误等等。
    • 如果 B 有任何问题,请按如下方式撤消:

      1. 从 DNS 配置中删除 B
      2. 等待 DNS 中的 B 条目消失(即等待生存时间直到到期为止)
      3. 拒绝B
  • 假设你已经完成了 B 的“老化”测试,并且一切正常
  • 更新优先级和权重DNS 中 B 的逐渐
  • 从 DNS 中完全删除 A
  • 等待 DNS TTL 过期;A 应该不会再收到任何请求
  • 拒绝A

您就完成了。

详细信息、图表和工具

请参阅这些文章和工具,它们可以帮助您实现流程自动化,但总体思路是一样的:

道德

“计算机科学中的所有问题都可以通过另一个级别的间接来解决,当然间接次数过多的问题除外。”大卫·惠勒

相关内容