为什么我不能通过主机将一个docker容器与另一个容器卷曲

时间:2016-12-15 18:37:45

标签: docker

我真的不明白这里发生了什么。我只是想在发布的端口上使用主机的公共IP 从一个docker容器内部,另一个docker容器,通过主机执行http请求。 / p>

这是我的设置。我有我的开发机器。我有一个带有两个容器的docker主机。 CONT_A在端口3000上侦听并发布Web服务。

DEV-MACHINE

HOST (Public IP = 111.222.333.444)
  CONT_A (Publish 3000)
  CONT_B

enter image description here

在我的开发机器上(一台完全不同的机器)

我可以毫无问题地卷曲

curl http://111.222.333.444:3000 --> OK

当我通过SSH进入主机

我可以卷曲而没有任何问题

curl http://111.222.333.444:3000 --> OK

当我在CONT_B内执行

不可能,只是超时。 Ping虽然很好......

docker exec -it CONT_B bash
$ curl http://111.222.333.444:3000 --> TIMEOUT
$ ping 111.222.333.444 --> OK

为什么吗

Ubuntu 16.04,Docker 1.12.3(默认网络设置)

3 个答案:

答案 0 :(得分:5)

我知道这不是问题的严格答案,但有更多的Docker-ish方法来解决你的问题。我会忘记发布用于集装箱间通信的端口。而是使用docker swarm创建覆盖网络。您可以找到完整的指南here,但实际上您可以执行以下操作:

//create network    
docker network create --driver overlay --subnet=10.0.9.0/24 my-net
//Start Container A
docker run -d --name=A --network=my-net producer:latest
//Start Container B
docker run -d --name=B --network=my-net consumer:latest

//Magic has occured
docker exec -it B /bin/bash
> curl A:3000 //MIND BLOWN!

然后在容器内部,您可以只卷曲主机名A,它将为您解决(即使您开始进行缩放等)。

如果您不热衷于使用Docker swarm,您仍然可以使用Docker旧链接:

docker run -d --name B --link A:A consumer:latest

将链接A容器中任何已公开(未发布)的端口。

最后,如果你开始转向生产......忘掉链接&完全覆盖网络...使用Kubernetes :-)更难以初始设置,但他们引入了一堆概念&用于链接的工具扩展容器集群更容易!但那只是我个人的意见。

答案 1 :(得分:0)

我有类似的问题,我在一个容器中有一个nginx服务器(让我们称之为web),有几个服务器块,而cron安装在另一个容器中(我们称之为cron)。我用docker compose。我想不时使用从cron到web的curl来在其中一个应用程序上执行一些php脚本。它应该如下所示:

curl http://app1.example.com/some_maintance.php

但是一段时间后我总是无法接通主机。

第一个解决方案是更新cron容器中的/ etc / hosts,并添加:

1.2.3.4 app1.example.com

其中1.2.3.4是web容器的ip,并且它有效 - 但这是一个黑客 - 据我所知,不鼓励这样的手动更新。您应该在docker compose中使用extra_hosts,这需要使用显式IP地址而不是容器名来指定IP地址。

我尝试使用自定义网络解决方案,正如我所见,这是解决这个问题的正确方法,但我从未在这里成功过。如果我学会了如何做到这一点,我保证会更新这个答案。

最后,我使用curl功能指定服务器的IP地址,并将域名作为标题传递给单独的参数:

curl -H'Host: app1.example.com' web/some_maintance.php

不是很漂亮,但确实有效。

(这里是我的nginx容器的名称)

答案 2 :(得分:0)

通过使用--network host参数运行容器B,您可以简单地使用localhost访问容器A,不需要公共ip。

> docker run -d --name containerB --network host yourimagename:version

使用上述命令运行容器B之后,您可以尝试像这样从容器B卷曲容器A

> docker exec -it containerB /bin/bash
> curl http://localhost:3000