null

Настройка DNS в Docker

Наверняка вы не раз сталкивались с проблемой нестабильной работы интернета в 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 влияет на скорость разрешения имён. Поскольку каждый из сервером опрашивается последовательно, предпочтительно указывать вначале тот, который чаще всего будет доступен.