Любопытная разница в работе DNS для docker-compose run и docker-compose up
18/06/2018
В рамках перехода с Phantomjs на Headless Chrome (+ ChromeDriver) end-to-end тестирование текущего проекта и попутной докеризации мне пришлось немножко разобраться с тем, как Docker Compose чудесным образом позволяет ссылаться контейнерам друг на друга по доменным именам. Рассмотрим для примера конкретный docker-compose.yml
файл конфигурации:
version: '3'
services:
alpha:
image: alpine
command: ["/bin/sh", "-c", "while sleep 3600; do :; done"]
beta:
image: alpine
command: ["/bin/sh", "-c", "while sleep 3600; do :; done"]
Есть два сервиса alpha и beta. Если мы запустим их с помощью команды docker-compose up
, то оба сервиса могу разрезолвить доменные имена друг друга:
$ docker-compose -p project up -d
$ docker-compose -p project exec alpha ping -q -c 1 beta
PING beta (172.20.0.3): 56 data bytes
--- beta ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.081/0.081/0.081 ms
$ docker-compose -p project exec beta ping -q -c 1 alpha
PING alpha (172.20.0.2): 56 data bytes
--- alpha ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.117/0.117/0.117 ms
$ docker-compose -p projec down -t 1
Но всем меняется, когда мы пытаемся запустить сервисы через docker-compose run
:
$ docker-compose -p project run -d alpha
project_alpha_run_1
$ docker-compose -p project run -d beta
project_beta_run_1
$ docker-compose -p project run alpha ping -q -c 1 beta
ping: bad address 'beta'
$ docker-compose -p project run beta ping -q -c 1 alpha
ping: bad address 'alpha'
$ docker-compose -p project down -t 1
Доменные имена не добавляются в дефолтный DNS резолвер, который находится внутри Docker Engine. Ситуация немного лучше, когда добавляется директива depends_on
:
version: '3'
services:
alpha:
image: alpine
command: ["/bin/sh", "-c", "while sleep 3600; do :; done"]
depends_on:
- beta
beta:
image: alpine
command: ["/bin/sh", "-c", "while sleep 3600; do :; done"]
и запускаем тот же эксперимент:
$ docker-compose -p project run -d alpha
project_alpha_run_1
$ docker-compose -p project run alpha ping -q -c 1 beta
Starting project_beta_1 ... done
PING beta (172.21.0.2): 56 data bytes
--- beta ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.095/0.095/0.095 ms
$ docker-compose -p project run beta ping -q -c 1 alpha
ping: bad address 'alpha'
Как видно зависимый сервис автоматически добавляется в DNS резолвер. Но что делать, если нужны DNS записи обоих сервисов, но при этом хочется запускать команду docker-compose run
? Ответом на этот вопрос служи специальный малоупоминаемый флаг --use-aliases
:
$ docker-compose -p project run -d --use-aliases alpha
project_alpha_run_1
$ docker-compose -p project run alpha ping -q -c 1 beta
Starting project_beta_1 ... done
PING beta (172.21.0.2): 56 data bytes
--- beta ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.106/0.106/0.106 ms
$ docker-compose -p project run beta ping -q -c 1 alpha
PING alpha (172.21.0.3): 56 data bytes
--- alpha ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.112/0.112/0.112 ms
Прочитав цепочку GitHub Issues посвященных этой проблеме я понял, что данный флаг не включается по умолчанию, ибо так задумано авторами изначально. В большинстве случаев задавать обратные зависимости не требуется. Откровенно говоря я не вижу больших накладных расходов на добавление всех сервисов в DNS резолвер по умолчанию, но возможно это нарушает концепцию минимальной полезной конфигурации для инструмента. Однако, в некоторых случаях это крайне необходимо. Как я писал в начале, мне потребовалось, чтобы приложение с feature (e2e) тестами в контейнере могло подсоединяться к сервису Selenium Grid в отдельном контейнере по доменному имени, и в тоже время запросы бразуера в рамках этих тестов шли на контейнере с приложением ссылаясь на его доменное имя. Как раз для такого случая полезно знать о --use-aliases
.