更新Docker容器,无需停机

比方说,我有一个Web服务器的Docker容器(如Apache 2)。 现在我想更新它下面的操作系统。 这个SF答案说最好的方法是重build基础图像和我的Apache图像。 但是部署映像意味着停机时间,因为在创build新容器之前必须删除旧容器,因此只有一个容器绑定到端口80/443。

但是,如何以零停机时间部署此更新? 我应该使用负载均衡器并使用集装箱间通信吗? 我该如何更新负载均衡器?

理想的目标场景

是的,您应该使用负载平衡器并一次更新一个实例。 我不确定集装箱间的通讯是在哪里进行的。

举一个例子,假设你有一个负载平衡器来为你的站点A服务。用户只能连接到它,只知道它是“A”。 负载均衡器知道有两个或更多的后端(B,C等),以及它们是VM还是容器并不重要。

然后,你想升级后端,在这种情况下是Apache实例。

  1. 从负载均衡器的合格后端中取出B,使其不再接受任何stream量。
  2. 等待当前的实时请求被服务和现有的连接closures。
  3. 更新服务B的容器或底层虚拟机
  4. 重新启动B,等待它加载并开始工作
  5. testingB以确保它正确地提供新的请求
  6. 将B添加回负载均衡器后端池以重新启用stream量

然后,对C,D等进行相同的处理

请注意,从2013年11月开始, Docker容器就地升级就有了一个开放的请求 ,但似乎并没有太多的进展,所以上面的解决scheme就是你应该做的。

如何为现有的现场

据推测,你问这是因为你已经在这个模型中运行一个实时网站,你想升级它没有停机。 所以,我们需要达到上面的理想目标状态,但是是递增的。

我们假设:

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

如果这些假设是错误的,你应该首先修正它,这是正确的。

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

  1. 在新的IP上创build一个负载均衡器,并将其指向现有容器作为其唯一的后端
  2. 将DNS更改为直接指向负载均衡器而不是容器IP
  3. 使用相同的VM +容器设置添加一个相同的Apache后端
  4. 现在你有一个带有两个后端B和C的负载均衡器,所以按照“理想目标场景”部分的指导,一次一个地升级它们

如何更新负载平衡器

简单(托pipe)的方式

最简单的select是不要运行自己的平衡器。 例如,如果您使用的是提供负载平衡即服务的云平台,请考虑使用它,然后维护和更新负载平衡器不是问题。

手动的方式

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

  • 我们有一个主机名parsing到我们想要更新的负载均衡器A的IP
  • 我们的负载均衡器有一个P1,P2等的后端池

我们继续如下:

  • 用新的软件版本创build一个新的负载均衡器B.
  • 将所有后端池实例P1,P2等添加到我们的新负载均衡器B作为后端
  • 将B的IP地址与A一起添加到DNSparsing中

    • 现在我们正在有效地使用DNS作为负载平衡器
    • 如果A和B的条目是不加权的,那么它们实际上是50-50
    • 现在看看B如何执行,是否有任何错误等
    • 如果B有任何错误,撤消如下:

      1. 从DNSconfiguration中删除B.
      2. 等待DNS中的B条目消失(即等待TTL到期)
      3. 拒绝B
  • 假设你已经完成了B的“烧录”testing,一切都很好
  • 逐步更新DNS中B的优先级和权重
  • 完全从DNS中删除A.
  • 等待DNS TTL过期; A不应该再收到任何请求
  • 拒绝A

你完成了。

细节,图表和工具

看到这些写作和工具可以帮助你自动化的过程,但总体思路是一样的:

  • docker:零宕机部署
  • 零停机前端在CoreOS上部署Vulcand

道德

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