docker.io DNS не работает, он пытается использовать 8.8.8.8


33

У меня установлена ​​новая версия Ubuntu 14.04, и я хочу использовать Docker для запуска моих старых приложений, для которых требуется 12.04. DNS внутри Docker не работает.

Resolv.conf моего ноутбука выглядит так:

nameserver 127.0.0.1

Который не работает с Докером, по-видимому. Поэтому он пытается установить серверы имен на 8.8.8.8 и 8.8.4.4; когда я делаю

$ sudo docker run -i -t ubuntu /bin/bash

Это говорит:

WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]

И, конечно же, внутри экземпляра Docker resolv.conf выглядит так:

nameserver 8.8.8.8
nameserver 8.8.4.4

Я могу успешно пропинговать оба из экземпляра Docker. Тем не менее, нет DNS (например, ping google.comсбои).

Вывод ifconfig внутри Docker:

eth0      Link encap:Ethernet  HWaddr aa:e9:9f:83:9d:92  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::a8e9:9fff:fe83:9d92/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:648 (648.0 B)  TX bytes:738 (738.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Что теперь?

Ответы:


23

Когда пакет Ubuntu Docker обновился до использования systemd, он прекратил поддержку /etc/default/dockerфайла конфигурации, поэтому первоначальное решение, предложенное rocketman10404 , больше не будет работать (отключение dnsmasqвсе равно будет работать, но имеет недостаток, заключающийся в том, что Ubuntu не может автоматически обновлять DNS-сервер) ,

Исправление в новом daemon.jsonфайле конфигурации

Найдите DNS-сервер вашей сети:

$ nmcli dev show | grep 'IP4.DNS'
IP4.DNS[1]:                             10.0.0.2

Откройте или создайте, если он не существует, /etc/docker/daemon.jsonи добавьте настройки DNS в ExecStartстроку:

# /etc/docker/daemon.json
{
    "dns": ["10.0.0.2", "8.8.8.8"]
}

Перезапустите демон докера:

$ sudo service docker restart

Я написал подробное сообщение в блоге, а также подал ошибку об этой проблеме, если вы хотите получить более подробную информацию.

(Первоначально я решил эту проблему, открыв /lib/systemd/system/docker.service и добавив настройки DNS в строку ExecStart , но это плохо - мы не должны редактировать системные файлы напрямую .)


Спасибо за ваше решение - оно было полезно в пути, которое я выбрал для своего решения - которое, я думаю, немного более элегантно соответствует моим собственным обстоятельствам и особенностям запуска Docker в Ubuntu (или других настольных дистрибутивах, использующих NetworkManager + dnsmasq).
Адриан

16

Сам я не пользуюсь докером, поэтому обычно я бы не стал задавать вопросы о докере, но я случайно прочитал об этом и наткнулся на какую-то докерскую документацию, которая, похоже, решает эту проблему . Подводить итоги...

Документация предлагает несколько обходных путей. Первый - указать DNS-сервер, который будет использоваться демоном docker для контейнеров, добавив следующую строку в /etc/default/docker:

docker_OPTS="--dns 8.8.8.8"

где предоставленный DNS может быть локальным сервером DNS, таким как 192.168.1.1 (шлюз). Затем перезапустите с

sudo restart docker

Альтернативное решение включает отключение dnsmasq в NetworkManager, закомментировав конфигурацию /etc/NetworkManager/NetworkManager.confследующим образом:

#dns=dnsmasq

затем перезапустите оба

sudo restart network-manager
sudo restart docker

3
отключение dnsmasq у меня сработало.
Бенил

2
Этот последний подход, конечно, будет означать, что сетевой менеджер не может контролировать dnsmasq, например, он не может изменить ваш DNS-сервер при смене сети, включая переключение на VPN. Первый подход кажется мне лучше, но я бы хотел, чтобы dnsmasq также прослушивал IP-адрес докера (172.17.0.1), чтобы я мог указать на хосты докера.
mc0e

1
Поскольку Ubuntu переключился на настройку Docker с помощью sytemd, он /etc/default/dockerбольше не действует. Посмотрите мое решение о том, как решить эту проблему в мире post-init.d / upstart.
Робин Уинслоу

/etc/NetworkManager/NetworkManager.confне существует в Ubuntu 18.04 LTS. : /
XtraSimplicity

Обратите внимание, что в некоторых настройках Ubuntu 18.04 (например, минимальное изображение на Amazon) systemd-resolvedпо умолчанию действует как кеширующий DNS-сервер и это вызывает WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.проблему (настройки Ubuntu 16.04 не включают его по умолчанию). Обходной путь должен либо отключить, systemd-resolvedлибо использовать --dnsопцию при запуске контейнера, как указано в основном ответе.
Anon

9

Я столкнулся с этим в моей ситуации, которая конкретно

  • Запуск Docker-контейнеров на моей локальной машине для разработки
  • Который подключен к VPN
  • Некоторые из наших сценариев сборки контейнера выполняют такие вещи, как запуск npm installиз пользовательского хранилища в VPN внутри контейнера.
    • Это работает с конвейера CI, но не с наших машин разработчиков, потому что npmне может выполнить успешный поиск DNS
    • У нас также были проблемы с контейнерами, которые должны выполнять поиск для вызова внешних REST API.

Ubuntu по умолчанию использует dnsmasqзапущенный NetworkManager для кэширования DNS-запросов и настраивает /etc/resolv.confуказание на этот экземпляр на127.0.1.1

  • VPN-клиент, который мы используем, не совместим с NetworkManager и принудительно использует собственный, /etc/resolv.confкоторый перезаписывает конфигурацию NetworkManager.
  • Это настраивает DNS-серверы для VPN
  • Docker /etc/resolv.confпо умолчанию скрывает ваш контейнер
    • Обычно в Ubuntu он передает DNS-серверы Google в контейнер (потому что знает о dnsmasqситуации.
    • Но он рад передать конфигурацию DNS-сервера VPN в контейнер
    • Нет маршрута от контейнера на docker0сетевом мосту до DNS-серверов через tap0адаптер VPN .
  • Ergo, все DNS-запросы в контейнере завершаются неудачно, потому что он не может связаться только с теми DNS-серверами, которые поставляются с ним
  • Кроме того, некоторые сети блокируют запросы к DNS-серверам Google, потому что они хотят иметь возможность отслеживать все ваши поиски DNS

Решение :

Казалось бы, было бы более элегантно использовать NetworkManager и его встроенный dnsmasqэкземпляр в том виде, как он был спроектирован.

  1. Скажите Docker использовать ваш dnsmasqэкземпляр для DNS

    • Добавьте или отредактируйте файл, /etc/docker/daemon.jsonчтобы указать докеру использовать docker0мостовой адаптер для DNS

      {
        "dns": ["172.17.0.1"]
      }
      
  2. Сконфигурируйте dnsmasqэкземпляр NM для прослушивания мостов Docker, потому что по умолчанию он слушает только 127.0.1.1 - создать файл/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. Мне не нравится грубое поведение этого VPN-клиента, и я бы предпочел использовать DNS на стороне VPN только для поиска VPN (если у вас вежливый VPN-клиент, который правильно использует NetworkManager, вам не придется этого делать )

    • Отключите функцию DNS в VPN-клиенте (она перестает перезаписываться resolv.confпри подключении, и теперь весь DNS dnsmasqснова проходит )
    • Добавьте файл конфигурации, чтобы указать, dnsmasqправильно ли направлять DNS-запросы для вашего домена - добавьте файл `/etc/NetworkManager/dnsmasq.d/vpn-dns.conf

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • При желании добавьте поисковый домен для своего домена, чтобы вы могли использовать короткие имена

      • Я просто добавил наш локальный домен в список поиска в моем сетевом подключении по умолчанию
  4. Перезапустите NetworkManager и Docker

    sudo service network-manager restart
    sudo service docker restart
    

На этом этапе ваши контейнеры Docker должны быть в состоянии обходиться nslookupбез проблем, когда вы находитесь в VPN, для доменов как внутри, так и вне вашей VPN.


1
Небольшая настройка, которая не требует жесткого кодирования IP-адреса моста docker0, заключается в использовании интерфейса вместо директивы listen-address: interface = docker0
siwyd

Потрясающие объяснения и инструкции. +1 заслуженно.
17

Cheers @simonwydooghe - я включил ваше предложение - вы также можете использовать подстановочные знаки в этом поле, поэтому я добавил шаблон для всех имен мостов, используемых сетями не по умолчанию (по крайней мере, как используется docker-compose).
Адриан

1
Кажется, что значение dns в daemon.json должно быть массивом, в противном случае я получаю ошибку: cannot unmarshal string into Go value of type []stringпри перезапуске службы Docker.
Славен

Обновление для Bionic: 18.04 больше не использует встроенный экземпляр dnsmasq, управляемый NetworkManager для DNS, и вместо этого использует systemd-resolved; это приносит свои собственные проблемы, потому что это не может быть настроено для прослушивания моста docker0. Я прибег к отключению, переустановке NetworkManager dnsmasq и правильной настройке.
Адриан

2

Вот как я настроил докер на моем сервере Ubuntu 14.04, работающем без головы.

Я работаю на сервере Ubuntu 14.04 со следующей установленной версией докера.

#docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1

Файл /etc/init/docker.io.conf и скрипт содержат следующую строку:

# modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
    DOCKER=/usr/bin/$UPSTART_JOB
    DOCKER_OPTS=

Ответ выше помог мне найти файл выше.

Я раскомментировал следующее в /etc/default/docker.io и добавил свой локальный DNS-сервер:

# Use DOCKER_OPTS to modify the daemon startup options.  
DOCKER_OPTS="--dns 192.168.X.X"

Перезапустил сервис с:

sudo service docker.io restart

Ран docker run <image> /bin/bash

Нет сообщений DNS при запуске контейнера.

Запустил новый контейнер, установил dnsutils.

Запустил dig, и сообщение сервера является правильным локальным DNS-сервером.


0

У меня была похожая проблема, я сообщил об этом в StackOverflow . Похоже, что я не смог запросить 8.8.8.8сервер имен, который указан в стандартной установке Ubuntu Docker; однако, я мог бы пинговать это. В этом случае используйте DNS-сервер, который вы можете запросить. Тест с

nslookup - dns.server.name

и запустить контейнер через

docker run --dns=ip.addr.of.dns

Мне еще предстоит найти способ на https://askubuntu.com/q/607172/30266 найти автоматическое решение.


Мой ответ может быть достаточно автоматическим для вас ...
Адриан

0

Вы можете использовать локальный DNS-распознаватель хоста (например dnsmasq) из ваших контейнеров Docker, если они находятся в определенной пользователем сети . В этом случае у контейнера /etc/resolv.confбудет сервер имен 127.0.0.11(он же встроенный DNS-сервер докера ), который может правильно перенаправлять DNS-запросы на петлевой адрес хоста.

$ cat /etc/resolv.conf
nameserver 127.0.0.1
$ docker run --rm alpine cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
$ docker network create demo
557079c79ddf6be7d6def935fa0c1c3c8290a0db4649c4679b84f6363e3dd9a0
$ docker run --rm --net demo alpine cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0    

Если вы используете docker-compose, он автоматически настроит сеть для ваших контейнеров (с форматом файла v2 + ). Однако обратите внимание, что, хотя docker-composeконтейнеры запускаются в определенной пользователем сети, они все равно строят их в сети по умолчанию . Чтобы использовать пользовательскую сеть для сборок, вы можете указать этот networkпараметр в конфигурации сборки (требуется формат файла v3.4 + ).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.