Назад | Перейти на главную страницу

Контейнеры Docker не могут разрешить DNS на настольном хосте Ubuntu 14.04

У меня проблема с контейнерами Docker в Ubuntu 14.04 LTS. Docker работал нормально два дня, а затем внезапно я потерял все сетевое подключение внутри моих контейнеров. Приведенный ниже вывод ошибки изначально заставил меня поверить, что это произошло из-за того, что apt-get пытается разрешить DNS через IPv6.

Я отключил IPv6 на своем хост-компьютере и все же удалил все изображения, вытащил базовый ubuntu и все еще столкнулся с проблемой.

Я изменил свои серверы имен /etc/resolve.conf с локального DNS-сервера на общедоступные DNS-серверы Google (8.8.8.8 и 8.8.4.4), и мне все равно не повезло. Я также установил DNS в Google в DOCKER_OPTS в / etc / default / docker и перезапустил докер.

Я также попытался вытащить coreos, и yum тоже не смог разрешить DNS.

Это странно, потому что, хотя DNS не работает, я все равно получаю ответ, когда пингую те же серверы обновлений, которые apt-get не может разрешить.

Я не за прокси, я использую очень стандартную локальную сеть, и эта версия Ubuntu актуальна и свежа (я установил ее два дня назад, чтобы быть ближе к докеру).

Я тщательно исследовал это в других сообщениях о проблемах stackoverflow и github, но не нашел никакого решения. У меня нет идей, как решить эту проблему, может ли кто-нибудь помочь?

Сообщение об ошибке

➜  arthouse git:(docker) ✗ docker build --no-cache .
Sending build context to Docker daemon 51.03 MB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu:14.04
 ---> 5506de2b643b
Step 1 : RUN apt-get update
 ---> Running in 845ae6abd1e0
Err http://archive.ubuntu.com trusty InRelease
Err http://archive.ubuntu.com trusty-updates InRelease
Err http://archive.ubuntu.com trusty-security InRelease   
Err http://archive.ubuntu.com trusty-proposed InRelease  
Err http://archive.ubuntu.com trusty Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Err http://archive.ubuntu.com trusty-updates Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Err http://archive.ubuntu.com trusty-security Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Err http://archive.ubuntu.com trusty-proposed Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Reading package lists...
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-updates/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-security/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-proposed/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-updates/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-security/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-proposed/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Some index files failed to download. They have been ignored, or old ones used instead.

Контейнер IFCONFIG / PING

➜  code  docker run -it ubuntu /bin/bash
root@7bc182bf87bb:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:04  
          inet addr:172.17.0.4  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:4/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:738 (738.0 B)  TX bytes:648 (648.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:65536  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)

root@7bc182bf87bb:/# ping google.com
PING google.com (74.125.226.0) 56(84) bytes of data.
64 bytes from lga15s42-in-f0.1e100.net (74.125.226.0): icmp_seq=1 ttl=56 time=12.3 ms
--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 12.367/12.367/12.367/0.000 ms
root@7bc182bf87bb:/# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=44 time=21.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=44 time=21.7 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=44 time=21.7 ms

Кроме того, обновление apt-get не удается, когда я принудительно использую IPv4:

root@6d925cdf84ad:/# sudo apt-get update -o Acquire::ForceIPv4=true
Err http://archive.ubuntu.com trusty InRelease

Err http://archive.ubuntu.com trusty-updates InRelease

Err http://archive.ubuntu.com trusty-security InRelease

Err http://archive.ubuntu.com trusty-proposed InRelease

Err http://archive.ubuntu.com trusty Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Err http://archive.ubuntu.com trusty-updates Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Err http://archive.ubuntu.com trusty-security Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Err http://archive.ubuntu.com trusty-proposed Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Reading package lists... Done
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/InRelease  

Ву, я нашел сообщение на github, которое решило мою проблему.

После того, как Стив К. указал, что на самом деле это не проблема DNS, а проблема с подключением, я смог найти сообщение на github это описало, как решить эту проблему.

Видимо завис сетевой мост docker0. Установка bridge-utils и запуск следующего привели мой Docker в рабочее состояние:

apt-get install bridge-utils
pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
service docker restart

Если проблема связана с преобразователем DNS, вот решение:

Первое, что нужно проверить, это запустить cat /etc/resolv.conf в докер контейнер. Если у него недопустимый DNS-сервер, например nameserver 127.0.x.x, то контейнер не сможет преобразовать доменные имена в IP-адреса, поэтому ping google.com не удастся.

Второе, что нужно проверить, это запустить cat /etc/resolv.conf на хост-машина. Докер в основном копирует хост /etc/resolv.conf в контейнер каждый раз, когда контейнер запускается. Так что если хозяин /etc/resolv.conf неверно, тогда будет и докер-контейнер.

Если вы обнаружили, что хост /etc/resolv.conf неверно, тогда у вас есть 2 варианта:

  1. Зафиксируйте DNS-сервер в daemon.json. Это легко, но не идеально, если вы ожидаете изменения DNS-сервера.

  2. Исправить хозяев /etc/resolv.conf. Это немного сложнее, но он создается динамически, и вы не жестко кодируете DNS-сервер.


1. Жестко запрограммировать DNS-сервер в docker daemon.json

  • редактировать /etc/docker/daemon.json

    {
        "dns": ["10.1.2.3", "8.8.8.8"]
    }
    
  • Перезапустите демон docker, чтобы изменения вступили в силу:
    sudo systemctl restart docker

  • Теперь, когда вы запускаете / запускаете контейнер, докер заполняет /etc/resolv.conf со значениями из daemon.json.


2. Исправить хосты /etc/resolv.conf

A. Ubuntu 16.04 и ранее

  • Для Ubuntu 16.04 и более ранних версий /etc/resolv.conf был динамически создан NetworkManager.

  • Закомментируйте строку dns=dnsmasq#) в /etc/NetworkManager/NetworkManager.conf

  • Перезапустите NetworkManager, чтобы восстановить /etc/resolv.conf :
    sudo systemctl restart network-manager

  • Проверить на хосте: cat /etc/resolv.conf

Б. Ubuntu 18.04 и новее

  • Ubuntu 18.04 изменен на использование systemd-resolved генерировать /etc/resolv.conf. Теперь по умолчанию он использует локальный кеш DNS 127.0.0.53. Это не будет работать внутри контейнера, поэтому Docker по умолчанию будет использовать DNS-сервер Google 8.8.8.8, который может сломаться для людей, находящихся за брандмауэром.

  • /etc/resolv.conf на самом деле символическая ссылка (ls -l /etc/resolv.conf) что указывает на /run/systemd/resolve/stub-resolv.conf (127.0.0.53) по умолчанию в Ubuntu 18.04.

  • Просто измените символическую ссылку, чтобы она указывала на /run/systemd/resolve/resolv.conf, в котором перечислены реальные DNS-серверы:
    sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

  • Проверить на хосте: cat /etc/resolv.conf

Теперь у вас должен быть действующий /etc/resolv.conf на хосте, чтобы докер мог скопировать в контейнеры.

Пытаясь добавить дополнительную ценность к проблеме, с которой я столкнулся; с альтернативным ответом:

Моя сеть была связана с офисом, и настройки Google DNS были заблокированы, чтобы контейнер мог пинговать IP-адреса, но не доменные имена.

Мой хозяин /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
search companyDomain.co.za

Это связано с тем, что Network Manager выполняет некоторую маскировку деталей DNS-сервера.

К сожалению, согласно руководства по докерам docker отфильтрует любые IP-адреса localhost при создании файла resolv.conf контейнера и заменит их IP-адресами DNS Google. Что в моем случае привело к тому, что доменные имена были запрещены.

Мне пришлось:

  • Сбросить мой /etc/default/docker по умолчанию, поэтому вместо этого контейнеры используют содержимое файла resolv.conf моего хоста.
  • редактировать /etc/NetworkManager/NetworManager.conf и закомментируйте строку dns=dnsmasq. Это сделано для того, чтобы NM мог указать фактические IP-адреса DNS вместо 127.0.0.1.
  • Перезапустите NM с помощью sudo service network-manager restart.
  • Перезапустите службу докеров с помощью sudo service docker restart.

Запуск контейнера позволил бы ему сделать apt-get update/upgrade, например.

Официальный документ Docker предоставляет инструменты для настройки DNS-сервера для использования Docker

  1. Открой /etc/default/docker файл для редактирования:

    sudo nano /etc/default/docker
    
  2. Добавьте настройку для Docker:

    DOCKER_OPTS="--dns 8.8.8.8"
    
  3. Заменить 8.8.8.8 с локальным DNS-сервером, например 192.168.1.1. Вы также можете указать несколько DNS-серверов. Разделите их пробелами, например:

    --dns 8.8.8.8 --dns 192.168.1.1
    

    Предупреждение: если вы делаете это на ноутбуке, который подключается к разным сетям, обязательно выберите общедоступный DNS-сервер.

    PS: nm-tool может использоваться для проверки DNS-сервера локального хоста

  4. Сохраните и закройте файл.

  5. Перезапустите демон Docker.

    sudo service docker restart
    

Ваша ошибка здесь:

 Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19).
 connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]

Это не ошибка DNS, вместо этого ваша система пытается подключиться к хостам IPv6 и не работает. Предположительно потому, что у вас нет доступа к IPv6 на вашем хосте. Фактический поиск IPv6-адреса завершается успешно. (Зеркало / архив ubuntu доступны как по IPv6, так и по IPv4. Вам просто не повезло, чтобы выбрать IPv6, потому что ваша система считает, что он должен работать.)

Вы должны либо исправить это, установка миредоили повторите попытку, пока не попадете в зеркало IPv4.

Опять же, здесь важно понять, что DNS не виноват, как вы можете видеть по вашим собственным тестам ping.

Для других читателей, которые приходят сюда при использовании boot2docker, вот как я исправил. Фактически, приведенный выше ответ указал мне правильное направление.

По сути, по какой-то причине контейнеры внутри boot2docker не могли разрешить имена хостов.

Итак, я просто перезапустил boot2docker и запустил контейнеры. Теперь имена хостов снова могут правильно разрешаться.

Я предполагаю, что проблема заключалась в запуске boot2docker во время подключения сети на хосте, что привело к запуску boot2docker и переходу в нерабочее состояние.

Я столкнулся с этой проблемой, когда разрешил установщику Ubuntu установить пакет Docker snap. Когда я отказался от этого и переключился на официальный пакет Docker, проблема исчезла сама собой.

sudo snap remove docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

У меня была такая же проблема в Windows. Эта команда заставила меня работать: docker-machine restart

Была аналогичная проблема, но также разрешение имен между контейнерами внутри сети, определенной пользователем, казалось немного нестабильным. Некоторые не могли решить ничего подобного вам.

Проблема заключалась в перемещении / var / lib / docker. Из соображений экономии места он был смонтирован через nfs. Добавление локальной файловой системы и перемещение файлов туда решает проблему.

Перезапустите демон Docker на Debian9

service docker restart

и соединения и сети работают нормально

Открыть файл /lib/systemd/system/docker.service

В ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock Добавить
--dns 8.8.8.8

Как это:

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --dns 8.8.8.8

Перезапустить службу докеров