如何正确处理Docker容器依赖关系?

我刚刚开始了解Docker,并考虑通过Docker基础架构来replace基于VM的基础架构。 我想知道如何处理容器之间的依赖关系,以及如何决定何时/如何重新启动依赖容器,如果是这样,如何最大限度地减less停机时间。

为了更加精确,我发现了诸如无花果或装饰等工具来pipe理容器和依赖项,所以(如果幸运的话)我得到一个有向的非循环图,告诉我以何种顺序启动或取下容器。 例如,mongodb容器必须在webserver容器之前启动

所以,如果我更新MongoDB或更改一些设置,我想我应该closuresnetworking服务器,因为它不能很好地处理数据库不存在。 在这种情况下,如何最大限度地减lessclosures和重新启动容器造成的停机时间,包括重新部署Jetty Web应用程序等?

但是,如果我只是更新我的SMTP服务器(或多或less所有其他容器依赖),我不希望这触发重新启动我的整个容器基础设施。 所以,重新启动邮件服务器容器后,其他容器仍然能够到达以前连接的端口?

你如何处理这种情况? 我是否需要/是否有可能为每个容器ABC增加一个大使容器ABC_amb,这个ABC容器绝不会在ABC重新启动的时候断开连接。

所以我想我会做的第一件事是在“硬”和“软”之间拆分容器之间的依赖关系。

“硬依赖”意味着B非常依赖于A,如果A重新启动,B也必须重新启动。 (也许是因为有一个networking连接在启动的时候依赖于B的状态)在这种情况下,我将以一种依赖关系的方式重启容器:closuresB,然后A,然后启动A,最后B。无花果和甲板可以做得很好。

“软依赖性”意味着B使用来自A的服务,但不是那么多,如果A重新启动,则需要重新启动B. (典型的用例是A上Web应用程序的B上的Web代理)。在这种情况下,我只会重新启动A并保持B运行。

但是,对于软依赖关系,我不能使用Docker --link参数,因为在重新启动A之后,B已知的A的DNS名称将指向无处(IP地址在容器重新启动时发生更改)。 因此,在启动/closures之前,我将使用serf注册和取消注册A,并使用serf事件处理程序触发B上的configuration更改,即更新configuration文件中的A的IP地址,并重新加载服务。 ( 这篇博客文章介绍了这是如何工作的,但要注意他们的设置与我的不同。)

但是,为了不必在每台主机上都这样做,我将使用一个启用了serf的HAproxy服务器,该服务器充当A和B之间的大使.B将使用--link链接到此代理,以便软件在B上运行并不需要知道关于serf的任何信息,而是可以依靠DNS来连接到大使,这将代理与A的连接。

  A (webapp) <--[soft]-- A_ambassador (haproxy) <--[hard]-- B (nginx) 

这似乎是一个可行的方法来保持容器运行,而(软)相关的容器可以重新启动。 一个好的副作用是(如果事件处理程序脚本写得很好),HAproxy可以作为一个实际的负载平衡器,如果存在多个A实例的话。

开放式问题:

  • HAproxy如何在代理服务closures时保持连接 ?
  • 在某些情况下,B也将不得不重新启动(例如,连接到A所需的密码已更改)。 或者,A大使和B必须重新启动(例如,A所使用的端口已更改)。 如何检测这些案件并妥善处理?
  • 为每个服务添加一个额外的HAproxy实例是否可以忽略不计? 有更轻量级的解决scheme吗?
Interesting Posts