В вопросе связанном с DNS попил мне Docker кровушки основательно, ибо столько там разных мест в которых тебе предлагают написать заветные цифры, что прямо-таки глаза разбегаются.
Итак, задача: необходимо поднять окружение разработчика для одновременной работы с несколькими веб-проектами висящими на доменах вида example.app. При этом данные домены должны быть доступны из контейнеров, с хоста, а также, например, из эмулятора Genymotion. Кроме того, из контейнеров должен быть доступен и внешний интернет. Все это усугубляется корпоративным Intranet со своим внутренним DNS сервером.
Для решения нам потребуется:
Установку пп.1-3 пропускаю, как очевидную. Обратите внимание на версию docker-compose, нам нужна версия 1.8 или выше (на момент написания в репозитариях лежала старая версия).
Для опытногоработника дока докера нет никакой проблемы выбрать нужные образы, слинковать их, пробросить порты, установить дополнительные библиотеки — информации на эту тему достаточно. Но если вы хотите начать работу прямо сейчас, то давайте воспользуемся продуктом коллективного сознательного — laradock.
Итак, laradock — это yml-файл и набор сопутствующих сконфигурированных образов для
Немаловажным является то, что установка некоторых дополнительных плагинов или библиотек сводится к простой правке yml-файла, например:
и пересборке образа:
Кроме того, в laradock все готово, чтобы засунуть туда одновременно столько проектов, сколько душе угодно — просто обратите внимание на примеры конфигурации в
laradock прокидывает порт 80 из контейнера nginx/apache на хост-машину, поэтому чтобы после поднятия нужных контейнеров (набор вы выбираете самостоятельно)
увидеть сконфигурированные заранее в nginx/apache сайты example.app и mysite.app нужно просто прописать для них локальный IP в файле /etc/hosts
На самом деле, если у вас изолированные проекты и нет корпоративного intranet, то вы можете прерваться в данном месте и уже начать разработку. Проблема с DNS вас не коснулась.
Если вы читаете дальше, то вам видимо нужно:
Итак, решаем пункты 1 и 2. Пункт 3 решится сам собой, добавлением всего одной строки — адреса вашего intranet DNS. Сделаем так, чтобы наши домены были доступны из контейнеров (в частности из php-fpm). Для этого нам потребуется dnsmasq.
Устанавливаем его, если вы еще этого не сделали:
Для того, чтобы разрешить DNS имя dnsmasq заглядывает в /etc/resolv.conf в поисках IP вышестоящего DNS-сервера. В принципе, мы могли бы туда его и прописать, но в этом файле четко написано, что изменять его не стоит, т.к. он может быть перезаписан. Поэтому создадим собственный файл /etc/resolv.ext.conf со следующим содержимым:
Теперь нужно чтобы dnsmasq стал его использовать. В файле /etc/dnsmasq.conf нужно найти, раскомментировать и исправить параметр, указав там наш файл:
Однако не все так просто… хитрый dnsmasq не будет его использовать пока мы не выполним еще одну манипуляцию.
Но вернемся к нашему случаю. Для того, чтобы наш resolv.ext.conf всеже был прочитан необходимо в файле /etc/default/dnsmasq указать:
В целом это все. Осталось только объяснить Docker, что в нашем маленьком мирке за разрешение DNS отвечает dnsmasq. При установке, Docker создает интерфейс docker0, определим IP нашего компьютера в этой подсети:
получим что-то вроде этого:
Открываем /etc/default/docker и указываем найденный IP:
Рестартуем сервисы:
и...
… опять заминка:
все заработает только если в вашем линуксе используется система инициализации Upstart или SysVinit (об этом четко написано в данном файле). Но если вы используете, например, Ubuntu 15.04 или выше, то у вас используется уже более продвинутая systemd и нам потребуются дополнительные телодвижения. Но для начала проверим, что же мы используем:
Как видите, из вывода команды ясно что у нас используется systemd.
Ну что же, вылечим и этого. Конфигурация сервиса изначально лежит в /lib/systemd/system/docker.service. Можно его просто скопировать и подправить:
но мы поступим более порядочно — изменим только то, что следует изменить:
Как вы уже поняли, мы создали файл /etc/systemd/system/docker.service.d/docker.conf (так называемый drop-in) с изменениями стандартных параметров и передаем наши параметры dns, прописанные в
Осталось только перезапустить сервисы:
и убедиться что все в порядке:
В выводе этой команды вы увидите много уже знакомого: и подключенный drop-in, и стартовавший сервис с нашим dns. Вот теперь действительно ВСЕ!
Update:
В
Полезные ссылки:
Итак, задача: необходимо поднять окружение разработчика для одновременной работы с несколькими веб-проектами висящими на доменах вида example.app. При этом данные домены должны быть доступны из контейнеров, с хоста, а также, например, из эмулятора Genymotion. Кроме того, из контейнеров должен быть доступен и внешний интернет. Все это усугубляется корпоративным Intranet со своим внутренним DNS сервером.
Для решения нам потребуется:
- docker — движок для работы с контейнерами
- docker-compose — работа с мульти-контейнерными решениями
- dnsmasq — легкий DNS (а также DHCP и TFTP) сервер
- laradock (опционально) — готовое мульти-контейнерное решение для разработчика
Установку пп.1-3 пропускаю, как очевидную. Обратите внимание на версию docker-compose, нам нужна версия 1.8 или выше (на момент написания в репозитариях лежала старая версия).
Для опытного
Из названия laradock можно выявить намек на смычку Laravel + Docker. Так и было изначально, но в данный момент такая направленность ушла и теперь проект ориентируется на любые веб-приложения.
Итак, laradock — это yml-файл и набор сопутствующих сконфигурированных образов для
docker-compose, позволяющий разворачивать набор контейнеров с nginx, mysql, mongoDB и еще кучей разных плюшек типа Memcached, Aerospike и т.д. (уже сейчас набор очень широкий и постоянно расширяется).Немаловажным является то, что установка некоторых дополнительных плагинов или библиотек сводится к простой правке yml-файла, например:
- INSTALL_XDEBUG=true
и пересборке образа:
docker-compose build php-fpm
Кроме того, в laradock все готово, чтобы засунуть туда одновременно столько проектов, сколько душе угодно — просто обратите внимание на примеры конфигурации в
./nginx/sites.laradock прокидывает порт 80 из контейнера nginx/apache на хост-машину, поэтому чтобы после поднятия нужных контейнеров (набор вы выбираете самостоятельно)
docker-compose up -d nginx mysql phpmyadmin
увидеть сконфигурированные заранее в nginx/apache сайты example.app и mysite.app нужно просто прописать для них локальный IP в файле /etc/hosts
127.0.0.1 example.app 127.0.0.1 mysite.app
Контейнер phpmyadmin прокидывется на порт 8080, поэтому увидеть его в работе можно по адресуhttp://localhost:8080. Ну и имейте в виду, что контейнер с мускулом работает для всех остальных контейнеров на хостеmysql, к которому и следует подключаться.
На самом деле, если у вас изолированные проекты и нет корпоративного intranet, то вы можете прерваться в данном месте и уже начать разработку. Проблема с DNS вас не коснулась.
Если вы читаете дальше, то вам видимо нужно:
- Из своего приложения обратиться к своему же отдельному backend на другом домене.
- Из приложения, запущенного в эмуляторе Android (iOS и т.д.) обратиться к своему backend.
- Из своего приложения обратиться к стороннему API, но вы сидите в intranet с местным DNS-сервером.
Итак, решаем пункты 1 и 2. Пункт 3 решится сам собой, добавлением всего одной строки — адреса вашего intranet DNS. Сделаем так, чтобы наши домены были доступны из контейнеров (в частности из php-fpm). Для этого нам потребуется dnsmasq.
Устанавливаем его, если вы еще этого не сделали:
sudo apt-get install dnsmasq
Для того, чтобы разрешить DNS имя dnsmasq заглядывает в /etc/resolv.conf в поисках IP вышестоящего DNS-сервера. В принципе, мы могли бы туда его и прописать, но в этом файле четко написано, что изменять его не стоит, т.к. он может быть перезаписан. Поэтому создадим собственный файл /etc/resolv.ext.conf со следующим содержимым:
# Гугловские DNS nameserver 8.8.8.8 nameserver 8.8.4.4 # Корпоративный DNS (это и есть та самая срока, которая выведет вас из застенков интранет) nameserver <IP корпоративного DNS>
Теперь нужно чтобы dnsmasq стал его использовать. В файле /etc/dnsmasq.conf нужно найти, раскомментировать и исправить параметр, указав там наш файл:
resolv-file=/etc/resolv.ext.conf
Однако не все так просто… хитрый dnsmasq не будет его использовать пока мы не выполним еще одну манипуляцию.
Здесь нужно сделать маленькую ремарку: можно не заморачиваться с собственным файлом конфигурации, а засунуть nameserver'а в оригинальный resolv.conf, но засунуть правильно. Засовывать их нужно в /etc/resolvconf/resolv.conf.d/head и тогда они будут автоматически добавляться в начале resolv.conf Однако имейте в виду, что там может быть только 3 неймсервера, а в своем файле — сколько угодно.
Но вернемся к нашему случаю. Для того, чтобы наш resolv.ext.conf всеже был прочитан необходимо в файле /etc/default/dnsmasq указать:
IGNORE_RESOLVCONF=yes
Что за бред, скажете вы… Игнорировать файл, чтобы его прочитать? Не совсем так. Комментарий перед этой опцией четко разъясняет что она делает. Мы заставляем dnsmasq игнорировать вывод утилиты resolvconf, если она установлена и обратить внимание именно на наш файл.В целом это все. Осталось только объяснить Docker, что в нашем маленьком мирке за разрешение DNS отвечает dnsmasq. При установке, Docker создает интерфейс docker0, определим IP нашего компьютера в этой подсети:
ifconfig | grep -A1 docker0
получим что-то вроде этого:
docker0 Link encap:Ethernet HWaddr 02:82:c5:3c:31:60 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
Открываем /etc/default/docker и указываем найденный IP:
DOCKER_OPTS="--dns 172.17.0.1"
Рестартуем сервисы:
sudo service dnsmasq restart sudo service docker restart
и...
… опять заминка:
все заработает только если в вашем линуксе используется система инициализации Upstart или SysVinit (об этом четко написано в данном файле). Но если вы используете, например, Ubuntu 15.04 или выше, то у вас используется уже более продвинутая systemd и нам потребуются дополнительные телодвижения. Но для начала проверим, что же мы используем:
$ sudo stat /proc/1/exe Файл: '/proc/1/exe' -> '/lib/systemd/systemd'
Как видите, из вывода команды ясно что у нас используется systemd.
Ну что же, вылечим и этого. Конфигурация сервиса изначально лежит в /lib/systemd/system/docker.service. Можно его просто скопировать и подправить:
sudo cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
но мы поступим более порядочно — изменим только то, что следует изменить:
sudo [ ! -e /etc/systemd/system/docker.service.d/ ] && mkdir -p /etc/systemd/system/docker.service.d/ sudo cat << 'EOF' > /etc/systemd/system/docker.service.d/docker.conf [Service] EnvironmentFile=-/etc/default/docker ExecStart= ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS EOF
Как вы уже поняли, мы создали файл /etc/systemd/system/docker.service.d/docker.conf (так называемый drop-in) с изменениями стандартных параметров и передаем наши параметры dns, прописанные в
/etc/default/docker при старте сервиса.Осталось только перезапустить сервисы:
sudo systemctl daemon-reload sudo service docker restart
и убедиться что все в порядке:
sudo service docker status
В выводе этой команды вы увидите много уже знакомого: и подключенный drop-in, и стартовавший сервис с нашим dns. Вот теперь действительно ВСЕ!
Update:
В
DOCKER_OPTS лучше указывать IP хоста в подсети docker0.Полезные ссылки: