Докер не может разрешить DNS в частной сети

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

Хост

[email protected]:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1

[email protected]:~# ping privatedomain.io
PING privatedomain.io (192.168.0.101) 56(84) bytes of data.

Container

[email protected]:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

nameserver 8.8.8.8
nameserver 8.8.4.4

[email protected]:~# ping privatedomain.io
ping: unknown host privatedomain.io

Довольно очевидно, что общедоступные DNS-серверы Google не будут разрешать мои частные DNS-запросы. Я знаю, что могу заставить его с помощью docker --dns 192.168.0.1 или установить DOCKER_OPTS="--dns 192.168.0.1" в /etc/default/docker, но мой ноутбук часто переключает сети. Кажется, должен быть систематический способ решения этой проблемы.

Ответ 1

Docker заполняет /etc/resolv.conf, копируя хост /etc/resolv.conf и отфильтровывая все локальные серверы имен, такие как 127.0.1.1. Если после этого не останется серверов имен, Docker добавит общедоступные DNS-серверы Google (8.8.8.8 и 8.8.4.4).

Согласно документации Docker:

Примечание. Если вам нужен доступ к определителю локального хоста hosts, вы должны изменить службу DNS на хосте, чтобы прослушивать нелокальный адрес, доступный из контейнера.

Служба DNS на хосте - это dnsmasq, поэтому, если вы заставите dnsmasq прослушивать IP-адрес вашего докера и добавите его в resolv.conf, docker настроит контейнеры для использования этого в качестве сервера имен.

1 Создайте/отредактируйте /etc/dnsmasq.conf и добавьте следующие строки:

interface=lo
interface=docker0

2 Найдите свой IP-адрес докера (в данном случае 172.17.0.1):

[email protected]:~# ifconfig | grep -A2 docker0
docker0   Link encap:Ethernet  HWaddr 02:42:bb:b4:4a:50  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0

3 Создайте/отредактируйте /etc/resolvconf/resolv.conf.d/tail и добавьте /etc/resolvconf/resolv.conf.d/tail строку:

nameserver 172.17.0.1

4 Перезапустите сеть, обновите resolv.conf, перезапустите докер:

sudo service network-manager restart
sudo resolvconf -u
sudo service docker restart

Теперь ваши контейнеры смогут разрешать DNS с любых DNS-серверов, которые использует хост-машина.

† Путь может быть /etc/dnsmasq.conf, /etc/dnsmasq.conf.d/docker.conf, /etc/NetworkManager/dnsmasq.conf или /etc/NetworkManager/dnsmasq.d/docker.conf зависимости от вашего системные и личные предпочтения.

Ответ 2

Для Ubuntu 18.04 и других систем, использующих systemd-resolved, может потребоваться установить dnsmasq и resolvconf. systemd-resolved жестко запрограммирован на прослушивание 127.0.0.53, и Docker отфильтровывает любой адрес обратной связи при чтении resolv.conf.

1 Установите dnsmasq и resolvconf.

sudo apt update
sudo apt install dnsmasq resolvconf

2 Отредактируйте /etc/dnsmasq.conf и добавьте следующие строки:

interface=docker0
bind-interfaces
listen-address=172.17.0.1

3 Создайте/отредактируйте /etc/resolvconf/resolv.conf.d/tail и добавьте /etc/resolvconf/resolv.conf.d/tail строку:

nameserver 172.17.0.1

4 Перезапустите сеть, обновите resolv.conf, перезапустите докер:

sudo service network-manager restart
sudo resolvconf -u
sudo service dnsmasq restart
sudo service docker restart

Теперь ваши контейнеры смогут разрешать DNS с любых DNS-серверов, которые использует хост-машина.

Ответ 3

Этого было достаточно для Ubuntu 18.04 LTS:

sudo service network-manager restart
sudo resolvconf -u
sudo service dnsmasq restart
sudo service docker restart