Докер потрясающий. Я люблю это. На самом деле, мне это очень нравится. Однако, когда вы работаете с более чем 10 микросервисами в любой день, может быть сложно управлять отношениями между этими сервисами при локальном развитии.

На производстве у нас есть надежные домены, которые мы можем использовать для поиска других сервисов. Когда мы работаем локально, мы находимся в прихоти переменных среды Docker Compose и сложного связывания для достижения локальных конвейеров. Это приводит к запутанным и сложным настройкам, которым нужно много времени, чтобы 1) изучить и 2) научить новых разработчиков.

Насколько мне известно, это по-прежнему наиболее распространенный способ поиска информации о других контейнерах Docker при локальной работе с Docker.

Я знаю, это слишком хорошо, чтобы быть правдой ... Ну, это не так. DNSDock - инструмент, который позволяет именно эту функцию. DNSDock цитируется как обнаружение службы DNS для контейнеров Docker, я предпочитаю называть это источником жизненной силы локальной разработки Docker.

«Обнаружение службы DNS для контейнеров Docker»

Круто вы говорите. Что именно это значит? Что ж, это означает, что вы можете назначать домены своим контейнерам в файле docker-compose, и эти домены будут доступны не только для других контейнеров, работающих на вашей виртуальной машине, но и для вашего хост-компьютера.

Хотите знать, какие данные находятся в вашем контейнере Redis? Подключаем его прямо к RDM. Используете PostgresSQL или MySQL? Просто запустите Sequel Pro и посмотрите. Хотя все это вполне возможно без DNSDock, это также огромная PITA!

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

Конечная цель

Сначала давайте посмотрим на наш ожидаемый результат. По сути, нам нужен файл Docker Compose, который выглядит так…

# myapp/docker-compose.yml
redis:
  image: redis
  environment:
    DNSDOCK_NAME: cache
    DNSDOCK_IMAGE: myapp
  ports:
    - "6379":"6379"
mysql:
 image: mysql:5.6
  environment:
    DNSDOCK_NAME: db
    DNSDOCK_IMAGE: myapp
    MYSQL_ALLOW_EMPTY_PASSWORD: yes
  ports:
    — “3306:3306”
myapp:
  build: .
  environment:
    REDIS_HOST: cache.myapp.docker
    DB_HOST: db.myapp.docker
    HOST: api.myapp.docker
    DNSDOCK_NAME: api
    DNSDOCK_IMAGE: myapp
  ports:
    - "8001":"8001"

В этой конфигурации наш клиент Redis доступен по адресу cache.myapp.docker, наша база данных mysql - по адресу db.myapp.docker, а наш API доступен по адресу api.myapp.docker.

Теперь с нашего хост-компьютера мы можем легко просматривать наши данные Redis или MySQL, а также получать доступ к API через наше нормализованное доменное имя. Если вам нужно развернуть некоторые другие восходящие или нисходящие сервисы, вы можете просто установить переменную окружения API_HOST, и не будет необходимости добавлять сложные ссылки Docker и external_links.

Это позволяет нам иметь чистые переменные среды, не относящиеся к Docker, которые мы можем использовать во всех средах, как внутри, так и за пределами виртуальной машины Docker. Вы можете легко заменить REDIS_HOST и MYSQL_HOST в тестовой и производственной средах, при этом приложению не нужно знать, где оно выполняется.

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

Как туда добраться

Итак, что именно нужно, чтобы это волшебство произошло? Настройка DNSDock немного сложна, но как только вы настроите ее правильно, ваши друзья и коллеги будут хвалить вас как героя, упростившего локальный процесс разработки.

Сначала давайте посмотрим, как работает DNSDock. (Примечание: документы в репозитории DNSDock намного лучше, чем все, что я мог бы предоставить. Цель этой статьи - больше осведомленность, чем инструкции.)

Dnsdock подключается к Docker Remote API и поддерживает актуальный список запущенных контейнеров. Если запрос DNS соответствует некоторым контейнерам, возвращаются их локальные IP-адреса.

Вот и все, прямо из документации. Однако, чтобы это работало на виртуальной машине и на главном компьютере (эта статья посвящена Mac OSX), нам нужно немного поработать.

Настройка вашей машины

Первое, что нам нужно сделать, это настроить некоторую информацию о маршрутизации для нашей хост-машины. Выполнение следующих команд настроит ваш хост-компьютер для маршрутизации любых запросов к * .docker на IP-адрес компьютера Docker.

# make resolver dir if it does not exist
sudo mkdir -p /etc/resolver >/dev/null 2>&1
# add nameserver entry for *.docker URLs
echo "nameserver 172.17.42.1" | sudo tee /etc/resolver/docker > /dev/null
# remove previous entry for DNSDocker in case docker machine has different IP
sudo route -n delete -net 172.17.0.0
# add entries to route table for docker machine
sudo route -n add 172.17.0.0/16 $(docker-machine ip <your_docker_machine_name>)
sudo route -n add 172.17.42.1/32 $(docker-machine ip <your_docker_machine_name>)

Настройка контейнера DNSDock

Теперь, когда хост-компьютер настроен для поддержки пересылки доменов * .docker на машину Docker, мы можем запустить контейнер DNSDock и опробовать наши новые функции.

Во-первых, давайте запустим контейнер…

docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -p 172.17.42.1:53:53/udp tonistiigi/dnsdock

А теперь давайте посмотрим, что это на самом деле делает ...

# share the docker socket to the container so that DNSDock can connect to the Docker API
-v /var/run/docker.sock:/var/run/docker.sock
# expose the default DNS port to the docker0 bridge interface
-p 172.17.42.1:53:53/udp

Вот и все! Разверните некоторые службы с помощью docker-compose, и вы сможете получить к ним доступ с вашего хост-компьютера и изнутри вашей виртуальной машины по любому доменному имени, которое вы им назначите!

Надеюсь, это принесет вам столько же радости и эффективности, сколько принесло мне!

СОВЕТЫ!

Вы также можете установить переменную env DNSDOCK_ALIAS в вашем файле компоновки докеров, что позволит вам также установить псевдонимы для ваших контейнеров ...

myapp:
  build: .
  environment:
    REDIS_HOST: cache.myapp.docker
    DB_HOST: db.myapp.docker
    HOST: api.myapp.docker
    DNSDOCK_NAME: api
    DNSDOCK_IMAGE: myapp
    DNSDOCK_ALIAS: api.v2.myapp.docker, m.api.myapp.docker, etc...
  ports:
    - "8001":"8001"

Вы также можете установить желаемый суффикс домена, если не предпочитаете значение по умолчанию .docker

docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -domain container -p 172.17.42.1:53:53/udp tonistiigi/dnsdock

Если мы воспользуемся нашим примером myapp, теперь мы получим такие URL-адреса, как api.myapp.container. (Если вы измените домен, вам потребуется создать сервер имен для этого суффикса домена, см. информацию о маршрутизации выше.)

Благодарности

Я хотел бы поблагодарить @ steven.merrill с https://www.phase2technology.com/. Спасибо, что просмотрели мой пост и помогли с техническими вопросами!

Другое примечание

Технология Phase 2 предоставила мне бета-доступ к некоторым фантастическим инструментам докеров, которые делают все это за вас! Следите за обновлениями, как только они будут официально выпущены с открытым исходным кодом!