Разрешить IP-адрес контейнера докеров из ОС хоста, используя имя контейнера

У меня есть неконтейнерный экземпляр nginx, который служит обратным прокси-сервером как для контейнерных, так и для неконтейнерных сервисов.

Поскольку IP-адреса контейнеров могут меняться при перезагрузке, я не хочу использовать их в файле конфигурации nginx. Я искал простой способ сослаться на контейнеры. Контейнеры Docker могут ссылаться друг на друга по имени контейнера, т. е. DNS-поиск имен контейнеров дает IP-адрес контейнера. Я искал что-то подобное, но имена должны быть разрешены из хост-ОС.

Ограничения:

Решение должно работать с существующими контейнерами. Так что никаких docker run ... команд

Я пробовал mageddo/dns-proxy-server. Предполагается, что он разрешает имена контейнеров, но это не так даже после установки правильных переменных среды.

sudo docker run -d \
--restart unless-stopped \
--name dns-proxy-server \
-p 5380:5380 \
-e MG_REGISTER_CONTAINER_NAMES=true \
--hostname dns.mageddo \
-v /opt/dns-proxy-server/conf:/app/conf \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc/resolv.conf:/etc/resolv.conf defreitas/dns-proxy-server

PS: Хотя в качестве примера взят nginx, функция поиска DNS полезна во многих других сценариях. Поэтому я ищу решение для поиска DNS, а не просто исправление проблемы с nginx.


person Dojo    schedule 25.05.2020    source источник


Ответы (2)


Есть решение, которое вы можете реализовать. Сначала запустите DNS-сервер.

docker run --rm --hostname dns.mageddo --name dns-proxy-server -p 5380:5380 \
  -v /opt/dns-proxy-server/conf:/app/conf \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /etc/resolv.conf:/etc/resolv.conf \
  defreitas/dns-proxy-server

Затем запустите тестовый контейнер, чтобы проверить имя хоста.

docker run --hostname test.intranet nginx

Тестирование

ping test.intranet
PING test.intranet (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=2 ttl=64 time=0.050 ms
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 172.18.0.3 (172.18.0.3): icmp_seq=4 ttl=64 time=0.046 ms
person nischay goyal    schedule 25.05.2020
comment
Это не сработает, если я не создам контейнер с параметром --hostname. Я не хочу изменять настройку работающих контейнеров. Он должен работать с именем хоста по умолчанию, то есть с именем контейнера, как это происходит внутри контейнеров. - person Dojo; 25.05.2020
comment
Dojo, Docker не предоставляет это из коробки. Я столкнулся с этой проблемой, и это было лучшее решение, которое я нашел, потому что, в конце концов, вам нужно указать полное имя против IP-адреса, и это то, что этот DNS-сервер следит за изменением IP-адреса. - person nischay goyal; 25.05.2020

Процессы вне Docker не могут получить доступ к системе Docker DNS; за исключением одной конкретной конфигурации, они также не могут получить доступ к частным IP-адресам контейнера.

Вместо этого вы можете публиковать порты из ваших контейнеров, используя опцию docker run -p или опцию Compose ports:. Указанный вами номер порта будет стабильным и сохранится при перезапуске контейнера. Если вы не хотите, чтобы порт был напрямую доступен за пределами хоста, вы можете ограничить его доступом только через петлевой интерфейс хоста.

docker run -d --name backend \
  -p 127.0.0.1:8001:3000 \      # port 8001 reaches this container, only on lo0
  ...
match /backend/ {
  proxy_pass http://localhost:8001/
}

Если для вашей конфигурации nginx важно использовать внутренний DNS Docker, вы также можете запустить прокси-сервер nginx внутри Docker.

person David Maze    schedule 25.05.2020
comment
Да, вам потребуется перезапустить контейнер, чтобы добавить параметр -p. Вам нужно удалять и воссоздавать контейнеры для самых разных рутинных операций (включая изменение базового образа на более новый код приложения или получение обновления безопасности), и это не должно быть препятствием. - person David Maze; 25.05.2020