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

tgp*_*fer 6 dependencies admin docker fig

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

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

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

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

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

tgp*_*fer 2

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

“硬依赖”是指B非常依赖A,如果A重新启动,B也必须重新启动。(也许是因为启动时存在依赖于 B 状态的网络连接。)在这种情况下,我将以尊重依赖关系的方式重新启动容器:关闭 B,然后关闭 A,然后启动 A,最后启动 B。即无花果和装饰可以做得很好。

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

但是,对于软依赖项,我无法使用 Docker--link参数,因为在 A 重新启动后,B 已知的 A 的 DNS 名称将指向任何地方(IP 地址在容器重新启动时发生变化)。因此,我将在启动后/关机前使用serf来注册和注销 A,并使用serf 事件处理程序来触发 B 上的配置更改,即更新配置文件中 A 的 IP 地址并重新加载服务。(这篇博文介绍了它的工作原理,但请注意他们的设置与我的不同。)

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

  A (webapp)   <--[soft]--  A_ambassador (haproxy)  <--[hard]--  B (nginx)
Run Code Online (Sandbox Code Playgroud)

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

开放式问题:

  • 当代理服务关闭时, HAproxy 如何保持连接?
  • 在某些情况下,B 也必须重新启动(例如,连接到 A 所需的密码已更改)。或者,A_ambassador 和 B 必须重新启动(例如,A 使用的端口更改了)。如何发现这些情况并妥善处理?
  • 为每个服务添加一个额外的 HAproxy 实例的开销是否可以忽略不计?有没有更轻量级的解决方案?