docker.io DNS не працює, він намагається використовувати 8.8.8.8


33

У мене є нова установка Ubuntu 14.04, і я хочу використовувати Docker для запуску своїх старих речей, яким потрібно 12.04. DNS всередині Docker не працює.

Роздільна здатність мого ноутбука виглядає так:

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 резолюція.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все ще працюватиме, але це має недолік запобігання автоматичного оновлення сервера DNS Ubuntu) .

Виправлення в новому daemon.jsonконфігураційному файлі

Знайдіть DNS-сервер вашої мережі:

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

Відкрийте або створіть, якщо його немає, /etc/docker/daemon.jsonі додайте до ExecStartрядка налаштування DNS :

# /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 працювало на мене.
bennyl

2
Цей останній підхід, звичайно, означає, що мережевий менеджер не може керувати dnsmasq, тобто, наприклад, що він не може змінити ваш dns-сервер при зміні мережі, включаючи перемикання на VPN. Колишній підхід мені здається кращим, але я хотів би мати можливість dnsmasq також слухати IP-адресу докера (172.17.0.1), щоб я міг вказати хостів докера на це.
mc0e

1
Оскільки Ubuntu перейшов на налаштування Docker за допомогою sytemd, це /etc/default/dockerбільше не впливає. Дивіться моє рішення, як вирішити це в світі після 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параметр при запуску контейнера, як зазначено в основній відповіді.
Анон

9

Я зіткнувся з цим у своїй ситуації, яка конкретно

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

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ситуацію).
    • Але радий передати конфігурацію сервера VPN DNS до контейнера
    • Немає маршруту від контейнера на docker0мережевому мосту до серверів DNS через tap0адаптер VPN .
  • Ерго, усі пошукові запити 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, полягає у використанні інтерфейсу замість директиви прослуховування адреси: interface = docker0
siwyd

Дивовижні пояснення та інструкції. +1 заслужено.
ereOn

Будьте здорові @simonwydooghe - я включив вашу пропозицію - ви також можете використовувати символи в цьому полі, тому я додав шаблон для всіх імен мостів, використовуваних мережами, що не використовуються за замовчуванням (принаймні, як це використовується докер-композитом).
Адріан

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

Оновлення для Bionic: 18.04 більше не використовує примірник екземпляра dnsmasq, керований NetworkManager для DNS, а натомість використовує системне рішення; що спричиняє власні проблеми, тому що це не може бути налаштовано на прослуховування моста docker0. Я вдався до його відключення та перевстановлення dnsmasq NetworkManager та його правильної настройки.
Адріан

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.

Ran 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-сервер Docker ), який може належним чином пересилати запити 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.