нет интернета внутри службы docker-compose

Я не могу подключиться к внешней сети из контейнеров docker-compose.

Рассмотрим следующий файл docker-compose:

version: '2'
services:
    nginx:
      image: nginx

Используя простой docker run -it nginx bash, мне удается подключиться к внешним IP-адресам или IP-адресам в Интернете (ping www.google.com).

С другой стороны, если я использую docker-compose и присоединяюсь к контейнеру, я не могу получить доступ к внешним IP-адресам / DNS.

информация о докере:

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 1
Server Version: 1.12.1
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 7
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge null host overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: apparmor seccomp
Kernel Version: 4.4.0-38-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.859 GiB
Name: ***
ID: ****
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
Insecure Registries:
 127.0.0.0/8

docker-compose 1.8.1, сборка 878cff1

файл daemon.json:

{
  "iptables" : false,
  "dns" : ["8.8.8.8","8.8.4.4"]
}

person orshachar    schedule 05.10.2016    source источник
comment
Вы используете docker exec -it <container-name> ping google.com? Это должно сработать.   -  person Bernard    schedule 05.10.2016
comment
Это именно то, что я сделал   -  person orshachar    schedule 05.10.2016
comment
Ты в сети заглядывал? Что показывает docker network inspect bridge? Предполагая, что «мост» - это сеть по умолчанию.   -  person aholbreich    schedule 03.03.2017
comment
не могли бы вы показать docker inspect <container-id> для обоих контейнеров?   -  person Robert    schedule 11.07.2017


Ответы (6)


В последний раз, когда у меня была такая проблема, я решил ее так:

https://github.com/docker/docker/issues/866#issuecomment-19218300

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

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

Что касается причин, по которым это происходит, у меня нет хороших ответов. Но я недавно отследил проблему до journald. Когда я перезапускаю journald (например, потому что я изменил его конфигурацию), разрешение DNS внутри контейнеров docker-compose постоянно / воспроизводимо прерывается. Не знаю почему, могу только сказать, что для меня это надежный способ воспроизвести его на RHEL.

ИЗМЕНИТЬ Команда docker -d может не работать для вас в зависимости от используемой вами версии докера, но не беспокойтесь об этом, вы можете пропустить эту команду.

person peedee    schedule 04.05.2017
comment
ip link del docker0, если вы не используете ifconfig, чего, вероятно, не будет в 2020 году. - person Chaim Eliyah; 08.09.2020

Отметьте /etc/default/docker, чтобы убедиться, что в нем нет следующей строки:

DOCKER_OPTS="--iptables=false"

Также проверьте /etc/docker/daemon.json, чтобы убедиться, что у него нет следующего ключа:

{
"iptables":false
}

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

person cornernote    schedule 25.04.2018
comment
Спасибо, это помогло мне. Некоторое время назад я заметил, что докер оставлял порты на хосте открытыми и переопределял ufw. Я отключил iptables следующим образом: ссылка Снова измените эту включенную сеть контейнеров. - person Giablo; 05.03.2019

Контейнеры Docker по умолчанию имеют возможность доступа в Интернет. Вот как я решил проблему на прошлой неделе: контейнер докеров может только доступ в Интернет с помощью сетевого хоста

Или вы просто позволяете контейнеру работать в режиме хоста:

version: '2'
service:
  nginx:
    image: nginx
    network_mode: host

Но, как отметил @peedee в комментарии, это решение потеряет разделение сети между хостом и контейнерами.

person Gao Shenghan    schedule 03.05.2017
comment
Делая это, вы теряете всякое разделение между хостом и контейнером. - person peedee; 04.05.2017
comment
@peedee Да, я должен это признать. Я проверил файл набора для проекта [faas] (get-faas.com), он просто использует оверлейную сеть и, похоже, должен иметь доступ к Интернету. Но я не мог сделать это на своем компьютере. - person Gao Shenghan; 05.05.2017
comment
Из документации Docker: Примечание: --network = host дает контейнеру полный доступ к локальным системным службам, таким как D-bus, и поэтому считается небезопасным. - person kewne; 12.07.2017

Образ nginx, который вы загружаете, по умолчанию не установлен ping. Поэтому, если вы действительно используете ping для проверки своего соединения, вы должны сначала установить его.

Я создал собственный Dockerfile для его установки:

FROM nginx:latest
RUN apt update && apt -y install iputils-ping

Затем я построил его локально и пометил как mynginx.

Затем я изменил docker-compose.yml, чтобы использовать пользовательское изображение mynginx:

version: '2'
services:
  nginx:
    image: mynginx

Наконец, я запустил docker-compose up, выполнил для него docker exec и протестировал ping. Все работало нормально. Я тоже сделал docker run -ti ..., и это сработало.

Что меня беспокоит в вашем вопросе, так это то, как docker run может дать вам контейнер с другим поведением, чем если бы он был создан docker-compose up.

Тем не менее, было бы полезно прояснить, как вы проверяете доступ в Интернет.

person Bruno Borges    schedule 10.07.2017

Я только что столкнулся с этим. Запустив любой контейнер с docker run -it <image> bash, я мог делать все, что было связано с сетью, что мне было нужно, но подключение к контейнеру, запущенному через docker-compose с docker exec -it <conatiner> bash, ничего не могло запустить. Даже apt-get выйдет из строя из-за временного сбоя в ошибке разрешения имен.

Я обнаружил, что добавление network_mode: "bridge" к каждой службе позволит включить внешнюю сеть в каждом контейнере за счет подключения всего к сети докеров по умолчанию. Однако я хотел сохранить стек изолированным, поэтому выбрал альтернативное решение.

Я запустил docker inspect network bridge, чтобы просмотреть сеть по умолчанию, и то же самое с моей сетью стека. Единственными существенными различиями, которые я обнаружил, была разница в подсети / шлюзе (что, я считаю, вполне ожидаемо, однако перечисленные IP-адреса различались значительно, 192. * против 172. *), и что сеть по умолчанию имел несколько опций, которых не было в стековой сети:

"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"

Мне удалось изолировать его от "com.docker.network.bridge.default_bridge": "true", однако это нарушило сеть для контейнеров вне стека, до такой степени, что мне в конечном итоге пришлось полностью удалить и переустановить докер. Я предполагаю, что демон докера путается с двумя сетями, отмеченными как стандартные, и не может разрешить его даже после удаления сети стека.

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

networks:
  default:
    driver: "bridge"
    ipam:
      driver: default
      config:
        - subnet: X.X.0.0/16

Где первое значение подсети было таким же, как у адаптера моста по умолчанию, а второе значение было плюс один. И это, по крайней мере, заставило все работать нормально, за исключением того, что адаптер по умолчанию все еще сломан.

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

sudo snap remove docker
sudo sysctl net.ipv4.conf.all.forwarding=1
sudo iptables -P FORWARD ACCEPT
sudo snap install docker

И последующий docker-compose up -d с удаленными сетевыми настройками привел к тому же IP-адресу подсети, который я определил ранее, без наличия для него конфигурации. Я считаю, что основная проблема заключается просто в том, что что-то мешало демону докера правильно найти доступную действительную подсеть, и как только это будет решено, все должно снова работать из коробки.

person shmeeps    schedule 22.06.2021

В моем случае докер был установлен через snap, после его удаления и установки, следуя инструкциям официального сайт заработал нормально.

person Dmitrij Kultasev    schedule 19.07.2021