Использование internal: true по умолчанию в docker-compose сети приводит к медленным тайм-аутам DNS - PullRequest
0 голосов
/ 17 января 2019

Фон

Мы пытаемся запустить набор тестов для довольно сложного стека приложений в настройке docker-compose. Пока все работает хорошо. Тем не менее, мы бы хотели убедиться, что не пропустили никаких внешних зависимостей или случайно не высовывали то, что не должны (например, производственные системы).

Это похоже на то, для чего в основном используется сетевая опция internal.

Проблема

При использовании internal: true в составной сети контейнеры не могут получить доступ к каким-либо внешним хостам, как ожидалось. Все идет нормально. Проблема заключается в том, что попытки разрешить имена хостов, которые не существуют в составленной сети, требуют много времени для ожидания. Вызов gethostbyname() может прерваться до 40 секунд, что ломает стек приложений разными способами.

Я хотел бы иметь возможность настроить настройку DNS в сети, чтобы просто дать мне немедленный NXDOMAIN для любого имени, которое не является контейнером в сети, но пока я не нашел никаких указаний что это даже возможно. Это похоже на очевидный вариант использования, и мне трудно поверить, что я первый решил эту проблему ...

Я гуглил все выше и ниже и перебрал всю документацию, которую смог найти, но пока безуспешно.

Минимальная настройка теста

Учитывая docker-compose.yml:

version: '3'

networks:
  default:
    internal: true

services:
  foo:
    image: debian:latest
    command: /bin/sleep 1000000000

  bar:
    build:
      context: ./bar
    command: /bin/true

И bar/Dockerfile:

FROM debian:latest
RUN apt-get update && apt-get install -y dnsutils bind9-host netcat-openbsd

Тогда:

$ docker-compose up -d
Creating network "foo_default" with the default driver
Creating foo_bar_1 ... done
Creating foo_foo_1 ... done
$ docker-compose run bar bash
root@f7f6bf6b65d4:/# time nslookup foo
Server:     127.0.0.11
Address:    127.0.0.11#53

Non-authoritative answer:
Name:   foo
Address: 192.168.96.3

real    0m0.010s
user    0m0.004s
sys 0m0.000s
root@f7f6bf6b65d4:/#

Мгновенный ответ. Пока все хорошо.

Но:

root@f7f6bf6b65d4:/# time nslookup foo.example.com 127.0.0.11
;; connection timed out; no servers could be reached

real    0m15.009s
user    0m0.004s
sys 0m0.004s
root@f7f6bf6b65d4:/#

Bad. Надеялся на мгновенный NXDOMAIN ответ.

Еще хуже:

root@f7f6bf6b65d4:/# time getent hosts foo.example.com

real    0m40.034s
user    0m0.000s
sys 0m0.000s
root@f7f6bf6b65d4:/#

Как уже упоминалось, это ломает наш стек несколькими путями и замедляет тестовые прогоны много .

Для справки, контейнер /etc/resolv.conf:

nameserver 127.0.0.11
options ndots:0

А /etc/nssswitch.conf составляет:

passwd:         compat
group:          compat
shadow:         compat
gshadow:        files
hosts:          files dns
networks:       files
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
netgroup:       nis

1 Ответ

0 голосов
/ 18 января 2019

Я протестировал эту настройку на своем Ubuntu 18.04 LTS и не могу воспроизвести вашу проблему.

Я получаю:

root@cedfc68cfa30:/# time nslookup foo.example.com 127.0.0.11
Server:     127.0.0.11
Address:    127.0.0.11#53

** server can't find foo.example.com: NXDOMAIN


real    0m0.025s
user    0m0.008s
sys     0m0.016s

После некоторого тестирования выясняется, что systemd-resolved выполняет требуемую магию, чтобы заставить это работать.

Если вы остановите systemd-resolved и используете внешний DNS-преобразователь, Docker отправит DNS-запросы с неверным исходным IP-адресом, поскольку в iptables для докера нет правила MASQUERADE.сети, а затем вам придется ждать тайм-аут.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...