Докер не может разрешить 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