可以(或者应该)2个docker容器通过本地主机相互交互?

我们正在dockerizing我们的微服务应用程序,我遇到了一些发现问题。

该应用程序configuration如下:

当服务以“非本地”模式启动时,它使用Consul作为其发现registry。 当服务以“本地”模式启动时,它会自动绑定每个服务的地址(例如,tcp:// localhost:61001,tcp:// localhost:61002等等。

在dockerizing应用之后(目前仅用于本地模式),每个服务都是一个容器(docker-compose和docker-machine一起编写,Docker-machine,如果这很重要)但是一个服务不能与另一个服务交互,因为他们不是在同一台机器上,tcp:// localhost:61001显然不起作用。

使用docker-compose和链接并指定localhost作为别名(service:localhost)不起作用。 有没有办法让2个容器“共享”相同的本地主机?

如果没有,最好的办法是什么? 我想过使用每个服务的特定主机名,然后在docker-compose的链接部分指定主机名。 (但我怀疑这是优雅的解决scheme)或者也许使用docker版本的Consul并与它集成?

这篇文章: 如何在两个不同的Docker容器之间共享本地主机? 提供了一些关于本地主机为什么不应该被混淆的见解 – 但是我仍然对这里的正确方法感到困惑。

谢谢!

但是一个服务不能与另一个服务交互,因为它们不在同一台机器上,tcp:// localhost:61001显然不起作用。

其实他们可以。 你是对的, tcp://localhost:61001将不起作用,因为在一个容器中使用localhost会引用容器本身,类似于默认情况下localhost在任何系统上的工作方式。 这意味着你的服务不能共享同一个主机。 如果你想要的话,你可以使用一个容器来提供这两种服务,虽然这并不是最好的devise,因为它打败了Docker Compose的一个主要目的。

要做到这一点的理想方法是使用docker-compose链接,您引用的指南显示了如何定义它们,但要实际使用它们,您需要在URL中使用链接容器的名称,就好像链接容器的名称具有在原来的容器的/etc/hosts (不是它实际上是这样,而只是让你明白)。 如果要将其更改为与链接容器的名称不同,可以使用链接别名,这些链接别名在您引用的相同指南中进行了介绍。

例如,使用像这样docker-compose.yml文件:

 a: expose: - "9999" b: links: - a 

0.0.0.0:99990.0.0.0:9999b可以通过从btcp://a:9999请求与a进行交互。 它也可以装入b并运行

 ping a 

这将从b容器发送ping请求到a容器。

因此,最后,请尝试用请求URL中的localhostreplace链接容器的文本名称(或链接别名,如果链接是使用别名定义的)。 这意味着

 tcp://<container_name>:61001 

应该工作,而不是

 tcp://localhost:61001 

只要确保你在docker-compose.yml定义了链接。

希望这可以帮助

在生产中,从来不使用docker工或docker工。 使用一个pipe弦乐队(牧场主,docker群,K8S,…),并在那里部署你的堆栈。 Orchestrator将会处理networking问题。 你的容器可以相互链接,所以你可以通过名字直接访问它们(不要太在意ip)。

在本地主机上,使用docker compose来启动你的容器并使用链接。 不要使用本地端口,而要使用链接的名称。 (如果您的容器A需要访问端口1234上的容器B,则使用名称BBBB链接到A的链接B,并使用tcp:// BBBB:1234从A访问容器)

如果你真的想将端口绑定到你的本地主机并使用它,那么通过你的主机IP访问端口,而不是本地主机。

如果现在不能更改硬编码地址,也许可以修改容器的启动脚本,将每个本地容器中的端口转发到其他机器中所需的服务。

这会产生一些复杂性,因为你必须在每个容器中设置ssh,并pipe理相应的密钥。

想想看,如果encryption不是问题,ssh是没有必要的。 使用socat或redir 可能就足够了 。

 socat TCP4-LISTEN:61001,fork TCP4:othercontainer:61001