docker: контейнеры в стеках в экземпляре EC2 не наследуют DNS-сервер имен

Я установил экземпляр EC2 на AWS.

Правильно настроили мои группы безопасности, чтобы экземпляр мог подключаться к Интернету, например

ubuntu@ip-10-17-0-78:/data$ ping www.google.com
PING www.google.com (216.58.211.164) 56(84) bytes of data.
64 bytes from dub08s01-in-f4.1e100.net (216.58.211.164): icmp_seq=1 ttl=46 time=1.02 ms
64 bytes from dub08s01-in-f4.1e100.net (216.58.211.164): icmp_seq=2 ttl=46 time=1.00 ms

Однако, когда я выполняю запуск в контейнере, это невозможно:

root@d1ca5ce50d3b:/app# ping www.google.com
ping: www.google.com: Temporary failure in name resolution

update_1: проблема с подключением связана с тем, что контейнеры инициируются с помощью docker stack deploy в определенных стеках;

Когда я просто запускаю автономный контейнер, подключение к Интернету есть:

ubuntu@ip-10-17-0-78:/data$ docker run -it alpine:latest /bin/ash
/ # ping www.google.gr
PING www.google.gr (209.85.203.94): 56 data bytes
64 bytes from 209.85.203.94: seq=0 ttl=38 time=1.148 ms
64 bytes from 209.85.203.94: seq=1 ttl=38 time=1.071 ms

update_2: после некоторого расследования выясняется, что:

  • автономный контейнер, действительно наследует dns-nameserver экземпляра EC2;
  • контейнеры, запущенные через docker stack deploy, нет;

т.е. это из docker swarm-инициированного контейнера:

ubuntu@ip-10-17-0-78:~$ docker exec -it d1ca5ce50d3b bash
root@d1ca5ce50d3b:/app# cat /etc/resolv.conf 
search eu-west-1.compute.internal
nameserver 127.0.0.11
options ndots:0

update_3: та же проблема, когда я начинаю стек с docker-compose вместо docker stack deploy; похоже, не является swarm специфической проблемой;

update_4: я явно добавил gfile /etc/docker/daemon.json со следующим содержимым:

{
    "dns": ["10.0.0.2", "8.8.8.8"]
}

ubuntu @ ip-10-17-0-78: / data $ docker run busybox nslookup google.com Сервер: 8.8.8.8 Адрес: 8.8.8.8:53

Неавторизованный ответ: Имя: google.com Адрес: 216.58.211.174

*** Не могу найти google.com: нет ответа

но поиск по-прежнему не работает:

Есть предложения, почему это может происходить?


person pkaramol    schedule 18.07.2018    source источник
comment
Попробуйте curl вместо ping.   -  person Shiva    schedule 18.07.2018


Ответы (3)


Я столкнулся с похожей проблемой. Я понимаю, что ему 11 месяцев, но найти информацию по этой теме довольно сложно, поэтому я размещу информацию здесь.

Моя проблема заключалась в том, что подсеть по умолчанию для оверлейной сети docker swarm перекрывалась с моей подсетью vpcs, поэтому DNS-сервер amazon ec2 по умолчанию (10.0.0.2) в моем случае сбивал с толку маршрутизацию ip-адреса демона докеров, заставляя думать, что это было местный сервис наложения роя (я думаю). В любом случае, я решил свою проблему, изменив подсеть оверлея по умолчанию через мой стек файлов network: раздел, и мой демон docker снова начал разрешать сервер 10.0.0.2 vpc dns.

Если вы поместите демон docker вашего узла в модуль отладки (в linux /etc/docker/daemon.json добавьте "debug": true в json), вы можете отслеживать вывод отладки, отслеживая журнал для демона в вашей конкретной системе. Если демон работает через systemd, journalctl -u docker предоставит вам журналы. -f будет следить за журналами.

Там я нашел информацию о проблемах с подключением (демон docker не смог связаться с DNS-сервером 10.0.0.2:54 - порт udp dns). Тем не менее, nslookup нормально работал на хост-ОС, /etc/resolve.conf выглядело подходящим. Проблема была очевидна, если вы использовали docker exec для получения интерактивного /bin/sh в одной из запущенных служб. nslookup не работает для любого внешнего домена, а журналы отладки демона докеров выдают больше сообщений типа «отказано в соединении», касающихся 10.0.0.2. Осмотрев проблемы поддержки докеров для разрешения DNS в течение часа или двух, я нашел комментарий, в котором говорится, что виртуальным сетям docker swarm назначаются адреса на основе некоторых значений по умолчанию, и что иногда эти значения по умолчанию перекрываются с тем, как вы настроили свои локальные подсети. . Я рассудил, что если они перекрываются по отношению к DNS-серверу на моем vpc, он может пытаться маршрутизировать dns-пакеты внутри роя вместо того, чтобы разрешать маршрутизацию подсети vpc.

person Josh    schedule 18.06.2019
comment
Не могли бы вы воспроизвести части того networking: раздела, из-за которого ваш демон docker снова начал разрешать 10.0.0.2 vpc dns-сервер? Я думаю, что столкнулся с той же проблемой, но считаю, что документы о том, как реализовать ваше предложение, неубедительны ... - person cueedee; 29.01.2020
comment
Копаем глубже ... может показаться, что добавление этого: networks: default: ipam: driver: default config: - subnet: '192.168.0.0/24' ... к docker-compose.yml заставляет его делать то, что нужно, но я бы хотел увидеть какое-то подтверждение, действительно ли это - правильное - stuff ™ - person cueedee; 29.01.2020
comment
Оказалось, что и мой случай тоже. CIDR перекрываются - person pkaramol; 31.01.2020

Ключ к более надежному решению - не требующему какой-либо docker-compose.yml настройки - можно найти в выходных данных ...

docker info
Server:
    …
    Swarm: active
        …
        Default Address Pool: 10.0.0.0/8  
        SubnetSize: 24
        …

Затем эта документация находится по адресу https://docs.docker.com/engine/swarm/swarm-mode/#configuring-default-address-pools:

По умолчанию Docker Swarm использует пул адресов по умолчанию 10.0.0.0/8 для сетей с глобальным охватом (наложения). Каждая сеть, в которой не указана подсеть, будет иметь подсеть, последовательно выделенную из этого пула. В некоторых случаях может быть желательно использовать для сетей другой пул IP-адресов по умолчанию.

Например, если диапазон 10.0.0.0/8 по умолчанию конфликтует с уже выделенным адресным пространством в вашей сети, тогда желательно убедиться, что сети используют другой диапазон, не требуя от пользователей Swarm указывать каждой подсети с помощью команды --subnet.

... убеждает, что это также место, где можно избежать подобных конфликтов.

Мы обнаружили, что пул адресов по умолчанию можно (только) определить в docker swarm init время:

$ docker swarm init --default-addr-pool <IP range in CIDR> ...

(--default-addr-pool можно повторить, чтобы расширить пул на большее количество диапазонов).

И действительно, после, например,

docker swarm init --default-addr-pool 192.168.0.0/16

... на этот раз - без изменения docker-compose.yml для настройки конкретной, другой подсети только для сети по умолчанию < / a> - оказывается, что теперь докер выбирает подсети из этого пула адресов по умолчанию, больше не перекрываясь с каким-либо адресом в сети, в которой находится сам экземпляр хоста докера.

docker info
Server:
    Swarm: active
        …
        Default Address Pool: 192.168.0.0/16
        SubnetSize: 24
    …
docker network inspect myapp_default
[
    {
        "Name": "myapp_default",
        …
        "Containers": {
            "…": {
                …
                "IPv4Address": "192.168.1.12/24",
            },
            …
        },
…
person cueedee    schedule 09.02.2020

[edit @ 2020-02-10] хотя я думаю, что приведенный ниже материал все еще может быть интересным, я бы больше не считал его лучшим решением проблемы. Это не означает, что он не работает, но для этого требуется адаптировать docker-compose.yml к среде, в которой он будет запущен, в то время как хотелось бы правильно подготовьте среду, вместо этого docker-compose.yml должен быть запущен в.


Заявление об ограничении ответственности: этот «ответ» является гораздо менее авторизованным решением, чем записью того, что заставило его казаться работающим для меня, и как они возникли.

Данный:

  • Наличие экземпляра хоста докера AWS EC2 с частным IP-адресом в диапазоне 10.0.0.0/16;
  • Это было docker swarm initialized;
  • У этого есть приложение, скажем myapp, развернутое как docker stack deploy -c docker-compose.yml myapp;

Можно обнаружить, что:

  • Docker будет - для сети myapp_default - назначать каждому контейнеру IP-адреса из 10.0.x.0/24 частного диапазона;
    Это можно вывести из вывода docker network inspect myapp_default | less -p '10\.0(\.[0-9]+){2}';
  • Сам экземпляр EC2 может обращаться к 10.0.0.2 (предоставлен AWS) за своим DNS;
  • Однако поиск DNS из контейнеров докеров завершается ошибкой - если демон dockerd не был дополнительно настроен для обращения к общедоступному DNS-серверу (например, dockerd --dns 8.8.8.8 ...) - и группа безопасности экземпляра (s) разрешить такой трафик;
    OP тоже это обнаружил.
  • Явное выполнение dockerd -dns 10.0.0.2 ..., похоже, ничуть не помогает;

Действительно, возникает вопрос, почему dockerd не может выполнять поиск в DNS между частным 10.0.x.0/24 диапазоном своей myapp_default сети и тем, в котором находится его экземпляр узла EC2; в конце концов, это все еще две полностью разъединенные сети, которые случайно выбрали перекрывающиеся IP-диапазоны, но очевидно - как уже отмечал @Josh - это так;

Кроме того, учитывая какое-либо ограничение, лежащее в основе этого, нельзя не задаться вопросом, почему «докер» не обнаруживает эту ситуацию автоматически, а затем вместо этого просто выбирает неперекрывающийся диапазон для сети myapp_default;

Казалось бы, мы просто должны сами явно исправить это; так как мы можем это сделать? Как заставить «докер» выбрать другой диапазон для своей myapp_default сети?

@Josh намекает на ответ и вместе с фрагментами информации, собранной из:

... Я придумал этот раздел верхнего уровня для добавления в docker-compose.yml:

networks:
    default:
        ipam:
            config:
                -
                    subnet: '192.168.0.0/24'
            driver: 'default'

После повторного развертывания myapp вывод docker network inspect myapp_default предоставляет свидетельство того, что контейнерам больше не выдаются IP-адреса из диапазона 10.0.x.0/24, а вместо 192.168.0.0/24 - и мы обнаруживаем, что их поиск в DNS теперь работает !

Я не (пока) знаю, является ли вышеперечисленное необходимым и достаточным решением проблемы, а не открытием какой-то другой банки с червями ...

person cueedee    schedule 31.01.2020
comment
см. также: github.com/docker/swarmkit/issues/1429#issuecomment-280522121 - person cueedee; 06.02.2020