如何创build容器之间的双向链接?

我必须链接两个容器,以便他们可以看到对方。 当然以下…

docker run -i -t --name container1 --link container2:container2 ubuntu:trusty /bin/bash docker run -i -t --name container2 --link container1:container1 ubuntu:trusty /bin/bash 

…在第1行失败,因为一个容器需要启动并运行才能成为链接目标:

 2014/08/15 03:20:27 Error response from daemon: Could not find entity for container2 

什么是创build双向链接最简单的方法?

Docker 1.10通过引入高级容器networking来很好地解决这个问题。 (详细信息: https : //docs.docker.com/engine/userguide/networking/dockernetworks/ )

首先,创build一个networking。 下面的例子创build一个基本的“网桥”networking,只在一个主机上工作。 您可以使用覆盖networking检查docker更完整的文档,以便跨主机执行此操作。

 docker network create my-fancy-network 

1.10中的Dockernetworking现在在容器内部创build一个特殊的DNSparsing器,以特殊的方式parsing名称。 首先,你可以继续使用–link,但正如你所指出的,你的例子不起作用。 我推荐在docker run命令中使用–net-alias =

 docker run -i -t --name container1 --net=my-fancy-network --net-alias=container1 ubuntu:trusty /bin/bash docker run -i -t --name container2 --net=my-fancy-network --net-alias=container2 ubuntu:trusty /bin/bash 

请注意,具有 – 名称容器2设置容器的名称,这也创build一个DNS条目和 – networking别名=容器2只是在networking上创build一个DNS条目,所以在这个特定的例子,你可以省略 – networking别名我把它留在那里,以防你想重命名你的容器,并仍然有一个DNS别名不符合你的容器名称。

(详情在这里: https : //docs.docker.com/engine/userguide/networking/configure-dns/ )

在这里你去:

 root@4dff6c762785:/# ping container1 PING container1 (172.19.0.2) 56(84) bytes of data. 64 bytes from container1.my-fancy-network (172.19.0.2): icmp_seq=1 ttl=64 time=0.101 ms 64 bytes from container1.my-fancy-network (172.19.0.2): icmp_seq=2 ttl=64 time=0.074 ms 64 bytes from container1.my-fancy-network (172.19.0.2): icmp_seq=3 ttl=64 time=0.072 ms 

并从container1

 root@4f16381fca06:/# ping container2 PING container2 (172.19.0.3) 56(84) bytes of data. 64 bytes from container2.my-fancy-network (172.19.0.3): icmp_seq=1 ttl=64 time=0.060 ms 64 bytes from container2.my-fancy-network (172.19.0.3): icmp_seq=2 ttl=64 time=0.069 ms 64 bytes from container2.my-fancy-network (172.19.0.3): icmp_seq=3 ttl=64 time=0.062 ms 

没有双向链接,因为您无法链接到非运行的容器。

除非禁用容器间通信 ,否则同一主机上的所有容器都可以看到networking上的其他容器。 所有你需要的是提供他们你想联系的容器的IP地址。

知道容器的IP地址的最简单方法是运行:

 docker inspect --format '{{ .NetworkSettings.IPAddress }}' container1 

你可以在启动两个容器后查看它(不要使用--link )。

如果您需要从container1内部自动知道container2的IP,有几个选项:

  1. 将docker socket安装为一个卷并使用远程API

    docker run -i -t –name container1 -v /var/run/docker.sock:docker.sock ubuntu:trusty / bin / bash echo -e“GET / containers / container2 / json HTTP / 1.0 \ r \ n” | nc -U /docker.sock | sed's /。 IPAddress“:”([0-9。] )。* / \ 1 /'

  2. 使用编排服务…有很多select,但我个人喜欢基于DNS的,如Skydock或注册者,并通过DNS名称访问容器。

  3. 使用dockerpipe理服务(例如dockerize.it -disclaimer:我正在处理它)将为您设置DNS服务。

由于没有双向链接,我用–net参数解决了这个问题。 这样他们使用相同的networking堆栈,因此可以通过回环设备(本地主机)互相访问。

 docker run -d --name web me/myserver docker run -d --name selenium --net container:web me/myotherserver 

所以我可以从networking访问selenium服务器(端口4444),我的selenium服务器可以访问我的Web服务器(端口80)。

以下是我为自己解决这个问题的方法:

首先,我遍历所有我的容器(需要相互了解)并创builddnsmasq条目,如下所示:

 for f in container1 container2 container3; do IP=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $f 2>/dev/null` if [ -n "$IP" ]; then echo $f "$IP" echo "host-record=$f,$IP" > /etc/dnsmasq.d/0host_$f else rm -f /etc/dnsmasq.d/0host_$f fi done 

然后,我启动一个dns容器,它已经安装了dnsmasq-base并启动了dnsmasq服务:

 docker run -d -P -h dns --name dns -v /etc/dnsmasq.d:/etc/dnsmasq.d:ro dns 

那么我得到这个容器的IP地址:

 DNS_IP=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' dns` 

像这样启动容器:

 docker run -d -P -h container1 --name container1 --dns $DNS_IP container1 docker run -d -P -h container2 --name container2 --dns $DNS_IP container2 docker run -d -P -h container3 --name container3 --dns $DNS_IP container3 

这是我的设置的简化版本,但它显示了要点。 我还添加了一个机制,当/etc/dnsmasq.d中的文件通过inotify-tools更改时,强制dnsmasq重新扫描。 这样,每当一个容器重新启动时,所有容器都会获得新的IP地址。

例如,我通过在每个容器的/ etc / hosts中附加一个ip-table来解决这个问题