How to create a bidirectional link between containers?

前端 未结 5 1239
梦如初夏
梦如初夏 2020-11-30 01:00

I have to link two containers so they can see each other. Of course the following...

docker run -i -t --name container1 --link container2:container2 ubuntu:t         


        
相关标签:
5条回答
  • 2020-11-30 01:35

    Since there is no bidirectional link I solved this issue with the --net argument. That way they are using the same network stack and can therefore access each other over the loopback device (localhost).

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

    So I can access from web the selenium server (port 4444) and my selenium server can access my web server (port 80).

    0 讨论(0)
  • 2020-11-30 01:37

    There is no bi-directional link since you can not link to a non-running container.

    Unless you are disabling inter-container communication, all containers on the same host can see any other containers on the network. All you need is to provide them the ip address of the container you want to contact.

    The simplest way of knowing the ip address of a container is to run:

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

    You can look it up after starting both containers (just don't use --link).

    If you need to know the IP of container2 from inside container1 automatically, there are a few options:

    1. Mount the docker socket as a volume and use the remote 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. Use an orchestration service… there are so many to choose from, but I personally like the DNS-based ones like Skydock or registrator and access containers by dns name.

    3. Use a docker management service (such as dockerize.it —disclaimer: I am working on it—) that will setup the DNS services for you.

    0 讨论(0)
  • 2020-11-30 01:50

    Docker 1.10 addresses this very nicely by introducing advanced container networking. (Details: https://docs.docker.com/engine/userguide/networking/dockernetworks/ )

    First, create a network. The example below creates a basic "bridge" network, which works on one host only. You can check out docker's more complete documentation to do this across hosts using an overlay network.

    docker network create my-fancy-network
    

    Docker networks in 1.10 now create a special DNS resolution inside of containers that can resolve the names in a special way. First, you can continue to use --link, but as you've pointed out your example doesn't work. What I recommend is using --net-alias= in your docker run commands:

    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
    

    Note that having --name container2 is setting the container name, which also creates a DNS entry and --net-alias=container2 just creates a DNS entry on the network, so in this particular example you could omit --net-alias but I left it there in case you wanted to rename your containers and still have a DNS alias that does not match your container name.

    (Details here: https://docs.docker.com/engine/userguide/networking/configure-dns/ )

    And here you go:

    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
    

    And from 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
    
    0 讨论(0)
  • 2020-11-30 01:51

    I solved this by appending an ip-table into /etc/hosts of each container, for example

    0 讨论(0)
  • 2020-11-30 01:53

    Here's how I've solved this for myself:

    First, I go through all my containers (which need to know from each other) and create dnsmasq entries like so:

    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
    

    Then I start a dns container which has dnsmasq-base installed and starts the dnsmasq service:

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

    then I get the IP address of this container:

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

    And start the containers like so:

    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
    

    This is a simplified version of my setup but it shows the gist. I've also added a mechanism that forces dnsmasq to rescan when files in /etc/dnsmasq.d change via inotify-tools. That way all containers get the new ip address whenever one container is restarted.

    0 讨论(0)
提交回复
热议问题