Как общаться между контейнерами Docker через " имя хоста"
Я планирую разделить свой монолитный сервер на множество небольших контейнеров docker, но пока не нашел хорошего решения для "межконтейнерной связи". Это мой целевой сценарий:

Я знаю, как связать контейнеры вместе и как открыть порты, но ни одно из этих решений не удовлетворяет меня.
есть ли какое-либо решение для связи через имена хостов (имена контейнеров) между контейнерами, как на традиционном сервере сеть?
6 ответов:
редактировать: после того, как Докер 1.9, тег
docker networkкоманда (см. ниже https://stackoverflow.com/a/35184695/977939) является рекомендуемым способом для достижения этой цели.
мое решение состоит в том, чтобы настроить dnsmasq на хосте для автоматического обновления записи DNS: записи "A" имеют имена контейнеров и автоматически указывают на IP-адреса контейнеров (каждые 10 сек). Элемент автоматическое обновление скрипта вставить здесь:
#!/bin/bash # 10 seconds interval time by default INTERVAL=${INTERVAL:-10} # dnsmasq config directory DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.} # commands used in this script DOCKER=${DOCKER:-docker} SLEEP=${SLEEP:-sleep} TAIL=${TAIL:-tail} declare -A service_map while true do changed=false while read line do name=${line##* } ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name) if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed then service_map[$name]=$ip # write to file echo $name has a new IP Address $ip >&2 echo "host-record=$name,$ip" > "${DNSMASQ_CONFIG}/docker-$name" changed=true fi done < <(${DOCKER} ps | ${TAIL} -n +2) # a change of IP address occured, restart dnsmasq if [ $changed = true ] then systemctl restart dnsmasq fi ${SLEEP} $INTERVAL doneсделать убедитесь, что ваш сервис dnsmasq доступен на
docker0. Затем, начните свой контейнер с--dns HOST_ADDRESSчтобы использовать эту мини-службу dns.
новая сетевая функция позволяет подключаться к контейнерам с помощью их имя, поэтому если вы создали новую сеть, любой контейнер, подключенный к эта сеть может достигать других контейнеров по их имени. Пример:
1) создать новую сеть
$ docker network create <network-name>2) Подключение контейнеров к сети
$ docker run --net=<network-name> ...или
$ docker network connect <network-name> <container-name>3) пинг контейнер по имени
docker exec -ti <container-name-A> ping <container-name-B> 64 bytes from c1 (172.18.0.4): icmp_seq=1 ttl=64 time=0.137 ms 64 bytes from c1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.073 ms 64 bytes from c1 (172.18.0.4): icmp_seq=3 ttl=64 time=0.074 ms 64 bytes from c1 (172.18.0.4): icmp_seq=4 ttl=64 time=0.074 msпосмотреть этой раздел документации;
Примечание: в отличие от legacy
linksновая сеть не будет создание переменных среды, а также совместное использование переменных среды с другими контейнерами.эта функция в настоящее время не поддерживает псевдонимы
что нужно что
--linkна, по крайней мере для хоста.
С докер 1.10, и PR 19242 что будет:docker network create --net-alias=[]: Add network-scoped alias for the container(см. раздел ниже)
что это обновление
/etc/hostsfile подробностив дополнение к переменным среды Docker добавляет запись узла для исходного контейнера в .
например, запустите сервер LDAP:
docker run -t --name openldap -d -p 389:389 larrycai/openldapи определите образ для тестирования этого сервера LDAP:
FROM ubuntu RUN apt-get -y install ldap-utils RUN touch /root/.bash_aliases RUN echo "alias lds='ldapsearch -H ldap://internalopenldap -LL -b ou=Users,dc=openstack,dc=org -D cn=admin,dc=openstack,dc=org -w password'" > /root/.bash_aliases ENTRYPOINT bashвы можете выставить '' в '
internalopenldap' в тестовом изображении с --link:docker run -it --rm --name ldp --link openldap:internalopenldap ldaptestзатем, если вы наберете "lds", этот псевдоним будет работать:
ldapsearch -H ldap://internalopenldap ...что бы вернуть людей. Значит
internalopenldapправильно достигается изldaptestизображения.
конечно, докер 1.7 добавит
libnetwork, который обеспечивает собственную реализацию Go для подключения контейнеров. Смотрите блоге.
Он представил более полную архитектуру, с моделью контейнерной сети (CNM)
это обновит CLI Docker с помощью новых команд "сеть" и задокументирует, как "
-net" флаг используется для назначения контейнеров сетям.
настройки 1.10 появился новый раздел сетевой псевдоним, теперь официально документированы в
network connect:в то время как ссылки обеспечивают разрешение частных имен, локализованное в контейнере, псевдоним в области сети обеспечивает способ обнаружения контейнера альтернативным именем любым другим контейнером в области конкретной сети.
В отличие от псевдонима связи, который определяется потребителем службы, псевдоним в области сети является определяется контейнером, который предлагает услугу сети.продолжая приведенный выше пример, создайте еще один контейнер в
isolated_nwс сетевым псевдонимом.$ docker run --net=isolated_nw -itd --name=container6 -alias app busybox 8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17 --alias=[]добавить сетевой псевдоним для контейнера
можно использовать
--linkвозможность связать другой контейнер с предпочтительным псевдонимомможно приостановить, перезапустить и остановить контейнеры, подключенные к сети. Приостановленный контейнеры остаются подключенными и могут быть обнаружены с помощью проверки сети. Когда контейнер остановлен, он не появляется в Сети, пока вы не перезагрузите его.
если указано, IP-адрес(Ы) контейнера повторно применяется при перезапуске остановленного контейнера. Если IP-адрес больше не доступен, контейнер не запускается.
один из способов гарантировать доступность IP-адреса-указать
--ip-rangeпри создании сети, и выбрать статические IP-адреса из-за пределов этого диапазона. Это гарантирует, что IP-адрес не будет передан другому контейнеру, пока этот контейнер не находится в сети.$ docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 multi-host-network $ docker network connect --ip 172.20.128.2 multi-host-network container2 $ docker network connect --link container1:c1 multi-host-network container2
редактировать: это больше не кровоточащий край:http://blog.docker.com/2016/02/docker-1-10/
Оригинальный Ответ
Я боролся с ним всю ночь. Если вы не боитесь кровотечения края, последняя версия Docker engine и Docker compose оба реализуют libnetwork.С правильным конфигурационным файлом (который нужно поместить в версию 2), вы создадите службы, которые все увидят друг с другом. И, бонус, вы можете масштабировать их с помощью docker-compose (вы можете масштабировать любую услугу, которую хотите, которая не привязывает порт на хосте)
вот пример file
version: "2" services: router: build: services/router/ ports: - "8080:8080" auth: build: services/auth/ todo: build: services/todo/ data: build: services/data/и ссылка на эту новую версию compose file: https://github.com/docker/compose/blob/1.6.0-rc1/docs/networking.md
насколько я знаю, с помощью только Docker это невозможно. Вам нужен DNS для сопоставления IP-адресов контейнеров с именами хостов.
Если вы хотите из коробки решение. Одним из решений является использование, например Контена. Он поставляется с технологией наложения сети от Weave, и эта технология используется для создания виртуальных частных сетей локальной сети для каждой службы, и каждая служба может быть достигнута с помощью
service_name.kontena.local-address.вот простой пример файла YAML приложения Wordpress где сервис Wordpress подключается к серверу MySQL с помощью wordpress-mysql.контена.местный адрес:
wordpress: image: wordpress:4.1 stateful: true ports: - 80:80 links: - mysql:wordpress-mysql environment: - WORDPRESS_DB_HOST=wordpress-mysql.kontena.local - WORDPRESS_DB_PASSWORD=secret mysql: image: mariadb:5.5 stateful: true environment: - MYSQL_ROOT_PASSWORD=secret
Я только что нашел Tumtum Blog и наткнулся на этот пункт в официальной документации Докера. Я не знаю, пропустил ли я этот абзац все время или он был недавно добавлен, но это должно быть именно то, что мне нужно:)

Comments