如何在容器之间创建双向链接?

时间:2014-08-15 10:24:08

标签: docker

我必须链接两个容器才能看到对方。当然以下......

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

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

4 个答案:

答案 0 :(得分:28)

Docker 1.10通过引入先进的容器网络很好地解决了这个问题。 (详情:https://docs.docker.com/engine/userguide/networking/dockernetworks/

首先,创建一个网络。下面的例子创建了一个基本的"桥接"网络,仅在一台主机上运行。您可以查看docker的更完整文档,以便使用覆盖网络在主机上执行此操作。

docker network create my-fancy-network

1.10中的Docker网络现在在容器内创建一个特殊的DNS解析,可以以特殊方式解析名称。首先,您可以继续使用--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

请注意,让--name container2设置容器名称,它也会创建一个DNS条目,而--net-alias = container2只是在网络上创建一个DNS条目,所以在这个特定的例子中你可以省略--net -alias但是我把它留在那里以防你想要重命名你的容器并且仍然有一个与你的容器名称不匹配的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

答案 1 :(得分:14)

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

除非您是disabling inter-container communication,否则同一主机上的所有容器都可以查看网络上的任何其他容器。您只需要为他们提供您要联系的容器的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. 使用业务流程服务...有很多可供选择,但我个人喜欢基于DNS的,如Skydockregistrator,并通过dns名称访问容器。

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

答案 2 :(得分:14)

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

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

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

答案 3 :(得分:9)

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

首先,我浏览了所有容器(需要彼此了解)并创建dnsmasq条目,如下所示:

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

然后我启动一个安装了dnsmasq-base的dns容器并启动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地址。