Подтвердить что ты не робот

Как создать двунаправленную связь между контейнерами?

Мне нужно связать два контейнера, чтобы они могли видеть друг друга. Конечно, следующее...

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

Каков самый простой способ создания двунаправленной ссылки?

4b9b3361

Ответ 1

Docker 1.10 очень хорошо описывает это, внедряя передовые контейнерные сети. (Подробнее: https://docs.docker.com/engine/userguide/networking/dockernetworks/)

Сначала создайте сеть. В приведенном ниже примере создается базовая "мостовая" сеть, которая работает только на одном хосте. Вы можете проверить докеры более полную документацию, чтобы сделать это через узлы, используя оверлейную сеть.

docker network create my-fancy-network

Докеревые сети в 1.10 теперь создают специальное разрешение DNS внутри контейнеров, которое может разрешать имена особым образом. Во-первых, вы можете продолжать использовать -link, но, как вы указали, ваш пример не работает. Я рекомендую использовать --net-alias = в ваших командах запуска docker:

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/)

И вот вы идете:

[email protected]:/# 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

И из контейнера1

[email protected]:/# 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

Ответ 2

Нет двунаправленной ссылки, поскольку вы не можете ссылаться на неиспользуемый контейнер.

Если вы не отключить межконтейнерную связь, все контейнеры на одном и том же хосте могут видеть любые другие контейнеры в сети. Все, что вам нужно, это предоставить им IP-адрес контейнера, с которым вы хотите связаться.

Простейший способ узнать IP-адрес контейнера:

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

Вы можете посмотреть его после запуска обоих контейнеров (просто не используйте --link).

Если вам нужно знать IP-адрес контейнера2 изнутри контейнера1 автоматически, существует несколько вариантов:

  • Подключите разъем док-станции в качестве тома и используйте удаленный API

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

  • Используйте службу оркестровки... есть так много на выбор, но мне лично нравятся DNS-серверы, такие как Skydock или registrator и получить доступ к контейнерам по имени DNS.

  • Используйте службу управления докере (например, dockerize.it -disclaimer: я работаю над ней), которая будет настраивать службы DNS для вас.

Ответ 3

Поскольку нет двунаправленной ссылки, я решил эту проблему с аргументом - net. Таким образом, они используют один и тот же сетевой стек и поэтому могут обращаться друг к другу через устройство loopback (localhost).

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

Таким образом, я могу получить доступ к веб-серверу selenium (порт 4444), и мой сервер selenium может получить доступ к моему веб-серверу (порт 80).

Ответ 4

Вот как я решил это для себя:

Сначала я просматриваю все свои контейнеры (которые нужно знать друг от друга) и создавайте записи 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

Затем я запускаю контейнер dns, в котором установлена ​​база данных dnsmasq, и запускается служба 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

Это упрощенная версия моей установки, но она показывает суть. Я также добавил механизм, который заставляет dnsmasq выполнять повторное сканирование при изменении файлов в /etc/dnsmasq.d с помощью инструментов inotify. Таким образом, все контейнеры получают новый IP-адрес при каждом перезапуске одного контейнера.

Ответ 5

Я решил это, добавив ip-таблицу в /etc/hosts каждого контейнера, для пример