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

时间:2014-07-30 02:04:32

标签: dependencies admin docker fig

我刚刚开始了解Docker,并考虑用Docker基础架构替换基于VM的基础架构。我想知道如何处理容器之间的依赖关系以及如何确定何时/是否需要重新启动依赖容器,如果需要,如何最小化停机时间。

为了更精确,我发现了诸如figdecking之类的工具来管理容器和依赖项,所以(如果我很幸运)我得到一个有向的非循环图,它告诉我以哪个顺序启动或取下容器。例如,mongodb容器必须在webserver容器等之前启动。

因此,如果我更新MongoDB或更改某些设置,我想我也应该关闭网络服务器,因为它不能很好地处理数据库不存在。在这种情况下,如何最大限度地减少因关闭和重新启动容器而导致的停机时间,包括重新部署Jetty webapp等?

但是,如果我只更新我的SMTP服务器(或多或少所有其他容器依赖),我不希望这会触发我的整个容器基础设施的重启。那么,在重新启动邮件服务器容器后,其他容器是否仍能够访问以前链接的端口?

你如何应对这种情况?我是否需要/是否可以为每个容器ABC添加一个大使容器ABC_amb,它将永远不会停止并在ABC重启时保持连接等。

1 个答案:

答案 0 :(得分:2)

所以我认为我要做的是首先在“硬”和“软”之间拆分容器之间的依赖关系。

“硬依赖”意味着B在很大程度上取决于A,如果A重新启动,B也必须重新启动。 (也许是因为网络连接在启动时依赖于B的状态。)在这种情况下,我将以依赖关系的方式重新启动容器:关闭B,然后关闭A,然后启动A,最后启动B.这是无花果和甲板可以做得很好。

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

对于软依赖项,我不能使用Docker --link参数,因为重新启动A后,A已知的A的DNS名称将指向无处(IP容器在容器重启时更改)。因此,我将在启动/关闭之前使用serf注册和注销A,并将使用serf event handler触发B上的配置更改,即更新配置文件中的A的IP地址并重新加载服务。 (This blog post介绍了它的工作原理,但要注意它们的设置与我的设置不同。)

但是,为了不必在每个主机上执行此操作,我将使用支持serf的HAproxy服务器,该服务器充当A和B之间的大使.B将使用--link链接到此代理,以便在B上运行的软件不需要了解有关serf的任何信息,而是可以依靠DNS连接到大使,后者将代理连接到A。

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

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

未解决的问题:

  • HAproxy hold connections while the proxied service is down怎么样?
  • 在某些情况下,B还必须重新启动(例如,连接到A所需的密码已更改)。或者,A_ambassador和B必须重新启动(例如,A使用的端口已更改)。如何检测这些案件并妥善处理?
  • 每个服务添加一个额外的HAproxy实例的开销是否可以忽略不计?是否有更轻量级的解决方案?