Наверняка вы не раз сталкивались с проблемой нестабильной работы интернета в Docker при работе во внутренней корпоративной сети. Зачастую эта проблема связана с DNS, а именно с закрытым доступом к таким публичным DNS серверам, как 8.8.8.8 и 8.8.8.4, которые используются докером по умолчанию.
По умолчанию Docker при старте контейнера пытается взять адреса DNS серверов из /etc/resolv.conf хостовой машины, однако, встретив там адрес 127.0.0.53 предустановленного на Ubuntu systemd-resolved, решает использовать те самые публичные DNS сервера.
Воспроизведём проблему
Подлкючимся ко внутренней сети и проверим содержимое /etc/resolv.conf хостовой машины.
adpashnin@aspire:# 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
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 127.0.0.53
Запустим докер и проверим /etc/resolv.conf
adpashnin@aspire:~$ docker run --name dns_test -it ubuntu:latest
root@ca005a605c62:/# 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
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 8.8.8.8
nameserver 8.8.4.4
Попробуем получить адрес google.com
root@ca005a605c62:/# nslookup google.com
;; connection timed out; no servers could be reached
root@ca005a605c62:/#
Как же теперь решить данную проблему?
Первый способ - указание адреса DNS серверов при первом запуске контейнера с помощью docker run
adpashnin@aspire:~$ docker run --dns=8.8.8.8 --dns=8.8.8.4 --dns=192.168.2.1 -it --name dns_test ubuntu:latest
root@36f9673c14eb:/# cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.8.4
nameserver 192.168.2.1
root@36f9673c14eb:/# nslookup google.com
Server: 192.168.2.1
Address: 192.168.2.1#53
Non-authoritative answer:
Name: google.com
Address: 64.233.165.100
Name: google.com
Address: 64.233.165.138
Name: google.com
Address: 64.233.165.113
Name: google.com
Address: 64.233.165.139
Name: google.com
Address: 64.233.165.101
Name: google.com
Address: 64.233.165.102
Однако, данный способ не поможет при сборке образа через docker build или же в случае, если вам необходимо добавить или удалить какой-то из DNS серверов.
Второй способ - укзание DNS серверов в файле конфигурации Docker - /etc/docker/daemon.json
Создадим этот файл и добавим туда следующие строки:
{
"dns": ["192.168.2.1", "8.8.8.8", "8.8.8.4"]
}
Перезапустим докер
root@aspire:# service docker restart
Запустим контейнер и проверим /etc/resolv.conf
root@ca005a605c62:/# cat /etc/resolv.conf
nameserver 192.168.2.1
nameserver 8.8.8.8
nameserver 8.8.8.4
Всё, теперь мы снова можем получать адреса сервисов находясь во внутренней корпоративной сети.
В заключении хотелось бы отметить, что порядок следования DNS влияет на скорость разрешения имён. Поскольку каждый из сервером опрашивается последовательно, предпочтительно указывать вначале тот, который чаще всего будет доступен.