Нет подключения к интернету внутри контейнеров Docker

24

Я не могу выполнить команду, требующую подключения к Интернету, внутри любого контейнера 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

Сашка Лыхенко
источник
Можете ли вы пропинговать домен с хоста? Можете ли вы работать apt-get updateв док-режиме в интерактивном режиме?
Adampski
в выходных данных отображается сообщение об ошибке: временная ошибка при разрешении «archive.ubuntu.com» ... попробуйте .. ping www.google.com .. посмотрите, получите ли вы тот же ответ .. затем попробуйте ... ping 8.8.8.8 .. если IP работает, а имя хоста не работает, значит ваш DNS сломан (больше /etc/resolv.conf, чтобы узнать, какой DNS-сервер используется)
TG2
@adampski, я обновил вопрос, основываясь на твоих предложениях.
Сашка Лыхенко
@ TG2, я тоже обновил вопрос, основываясь на твоих предложениях.
Сашка Лыхенко
Какую версию движка Docker вы используете?
adampski

Ответы:

13

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

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

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

adampski
источник
1
Я попробовал это, и это убивает сеть на моем компьютере.
Петерсон
Это полезно и решило проблему для меня. Спасибо.
Рао
10
-dФлаг не выходит.
Луис де Соуза
2
Привет @ LuísdeSousa. Обидно, что вы проголосовали за это, но подумайте о том, что, возможно, некоторые ключи были удалены или изменены в более новых версиях. Тем более, что это было больше года назад.
adampski
3
вместо того, чтобы просто скопировать / пропустить команду, вы можете объяснить, что они означают :)
Adelin
12

Существует аналогичная проблема в 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]
Луис де Соуза
источник
Моя установка соответствовала описанию, и вышеуказанный подход решил проблему для меня.
krcools
обновленный ответ для Ubuntu 18.04: superuser.com/a/1335054
wisbucky
7

Первое, что нужно проверить, - запустить 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

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

wisbucky
источник