14

Я не могу выполнить команду, требующую подключения к Интернету, внутри любого контейнера Docker.

Работает:

docker run ubuntu /bin/echo 'Hello world'

Не работает:

docker run ubuntu apt-get update

Err:1 http://archive.ubuntu.com/ubuntu xenial InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:3 http://archive.ubuntu.com/ubuntu xenial-security InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Reading package lists...
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial-updates/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial-security/InRelease  Temporary failure resolving 'archive.ubuntu.com'

Аналогично с pip и ping .

Я нахожусь на Ubuntu 16.04 и не использую брандмауэр или корпоративный прокси-сервер и попытался перезапустить Docker.

Upd:

Обновление в интерактивном режиме не выполняется аналогичным образом.

docker exec -ti angry_goodall /bin/bash
apt-get update
#fails
ping google.com
#fails with "unknown host" message
ping 8.8.8.8 
# shows PING 8.8.8.8 (8.8.8.8): 56 data bytes
# and than hangs indefinetly

sudo apt-get update успешно выполняется на хосте, т.е. на моем компьютере вне докера.

Upd Docker версия 1.12.1, сборка 23cf638

3 ответа3

9

Существует аналогичная проблема в StackOverflow, где другое решение решает эту проблему с помощью Docker 17.09 в Ubuntu 16.04:

Проверьте содержимое resolv.conf:

$ cat /etc/resolv.conf

Если он содержит строку, подобную nameserver 127.0.1.1 это означает, что контейнеры получают неправильный сервер имен. Чтобы исправить это, отредактируйте файл NetworkManager.conf :

$ sudo pico /etc/NetworkManager/NetworkManager.conf

И закомментируйте строку с помощью dns=dnsmasq ; файл должен выглядеть так:

[main]
plugins=ifupdown,keyfile,ofono
#dns=dnsmasq

[ifupdown]
managed=false

Наконец, перезапустите сетевой менеджер:

$ sudo systemctl restart network-manager

Проверьте снова контейнер:

$ docker run ubuntu:16.04 apt-get update
Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
5

В соответствии с предложением Creack по проблеме GitHub № 866 для Docker:

pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
docker -d

"Это заставит докер воссоздать мост и переустановить все сетевые правила"

3

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

Второе, что нужно проверить, это запустить cat /etc/resolv.conf на хост-компьютере. Docker в основном копирует /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

  • Теперь, когда вы запустите / запустите контейнер, 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

Б. Убунту 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 на хосте, чтобы докер мог скопировать его в контейнеры.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .