可以(或应该)2个docker容器通过localhost相互交互吗?

时间:2017-08-07 16:50:30

标签: docker docker-compose microservices consul docker-networking

我们将微服务应用程序停靠,我遇到了一些发现问题。

该应用程序配置如下:

当服务以“非本地”模式启动时,它使用Consul作为其Discovery注册表。 当服务以“本地”模式启动时,它会自动绑定每个服务的地址(例如,tcp:// localhost:61001,tcp:// localhost:61002等等。硬编码地址)

将应用程序停靠后(仅适用于本地模式),每个服务都是一个容器(使用docker-compose编写的Docker镜像。如果重要的话,使用docker-machine) 但是一个服务不能与另一个服务交互,因为它们不在同一台机器上,tcp:// localhost:61001显然不起作用。

将docker-compose与links一起使用并将localhost指定为别名(service:localhost)不起作用。 2个容器是否有办法“共享”同一个本地主机?

如果没有,最好的方法是什么? 我考虑过为每个服务使用特定的主机名,然后在docker-compose的links部分指定主机名。 (但我怀疑这是优雅的解决方案) 或者可以使用Consul的版本化版本并与之集成?

这篇文章:How to share localhost between two different Docker containers?提供了一些关于为什么不应该将localhost搞砸的见解 - 但我仍然对这里的正确方法感到困惑。

谢谢!

3 个答案:

答案 0 :(得分:6)

  

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

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

理想的方法是使用docker-compose链接,您引用的指南显示了如何定义它们,但实际上使用它们需要在URL中使用链接容器的名称,就好像链接容器的名称在原始容器的/etc/hosts中定义了一个IP映射(实际上并不是这样,但只是让你明白了)。如果要将其更改为与链接容器名称不同的内容,可以使用链接别名,这在您引用的同一指南中有说明。

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

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

a 0.0.0.0:9999 b通过ab提出请求,tcp://a:9999可以与b进行互动。也可以归入ping a 并运行

a

会从b容器向localhost容器发送ping请求。

因此,最后,尝试使用链接容器的文字名称替换请求URL中的tcp://<container_name>:61001 (如果使用别名定义链接,则使用链接别名)。这意味着

tcp://localhost:61001

应该起作用而不是

docker-compose.yml

只需确保在/usr/bin/python中定义链接。

希望这有帮助

答案 1 :(得分:3)

在制作时,不要单独使用docker或docker。使用一个orchestrator(牧场主,docker swarm,k8s,...)并在那里部署你的堆栈。 Orchestrator将负责网络问题。您的容器可以相互链接,因此您可以通过名称直接访问它们(不要太在意ip)。

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

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

答案 2 :(得分:2)

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

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

想想看,如果加密不是问题,则不需要ssh。使用socatredirprobably be enough

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