13

周末我在docker 的 IRC上问了这个问题,但在我想通答案之前不得不离开:

如果我有许多在容器中运行的应用程序(让我们暂时假设它们都在相同的物理硬件上运行,但不一定是这种情况)并且我希望它们中的每一个都能够找到每个其他自动。

使用某种注册表(例如etcd或 DNS-SD/Bonjour),您可以宣布您的服务和任何相关细节,并让其他应用程序了解它们并相应地路由流量。

这里的问题是,虽然应用程序可以知道它容器中服务于哪个主机名/端口,但这不一定是它可以访问的端口或地址。有两个信息需要连接:

  • 可以访问服务的位置从容器外部访问
  • 服务做什么(版本号、服务类型);可从容器内部访问

您如何建议我通过容器屏障获取此信息?

  1. 我可以通过 TCP 向容器公开 docker,因此应用程序可以查询它的显示位置,但这似乎违反了关注点分离。
  2. 我可以在我的容器中打开一个文件/端口,在容器启动后主机系统会查询该文件/端口以准备发布,但这感觉有点像我要重新发明 WSDL。

关于我应该如何解决这个问题的任何想法或指导?

4

2 回答 2

4

我想也许是在启动容器后执行服务注册的方法。然后其他容器可以执行注册表查找以发现这些服务。

更新

maestro项目给出了一个如何在外部配置容器然后启动以建立容器协作网络的示例。

于 2013-08-13T22:41:37.760 回答
3

我也遇到过这个问题。我相信你的想法的错误是容器本身是唯一知道它做什么的。

容器不是今天服务于 MySQL 的自我感知实体,并决定明天成为队列处理器。

相反,有一个控制器(可能只是一个自动化系统,或者您在命令行上),并且该控制器知道应该运行特定的应用程序,要运行该应用程序,需要一组特定的服务,并且这就是为什么首先启动容器的原因。

控制器知道需要一个 MySQL 服务,并且一个 MySQL 服务代表一个要连接的主机:端口。如果是这样,它也可能知道一个服务是由两个或三个端口组成的。

因此,主机/控制器要么告诉容器注册哪个地址,要么询问它正在服务于哪个本地端口(或者更有可能根据容器定义知道端口),这在架构上是正确的。

实际上,主机可能会告诉容器“在此特定端口上的 LAN 接口上运行您的服务,我将注册它”、“在此 LAN 接口上的任何端口上自己运行您的服务并自己注册”或“运行您的在此端口上提供服务并将其注册到主机:端口,我将设置映射以确保它在那里可用”。

所有这些在架构上都很好:最后,它总是由主机/控制器决定,因为它确实是唯一一个同时知道哪些服务运行以及它们可访问的位置。

我发现 docker 中的一个实际问题是容器 IP 和主机映射端口是动态分配的,以至于在容器运行之前您无法真正获得任何信息;这就是为什么Flynn自己选择主机端口映射而不是让 docker 自动执行它的原因。

我已经写下了我对此的一些想法。

于 2014-02-05T12:25:51.383 回答