Я создал свой первый док-контейнер, на нем запущен сервер, использующий Go, но я не могу получить к нему доступ извне хост-компьютера. Я только начал работать с докером, так что я немного потерялся здесь.
Итак, у меня есть очень простой код Go, запускающий сервер, я создал образ докера, который устанавливает Go и собирает код в базовый образ Linux. Я запускаю сервер на порту 8080, поэтому я предоставляю этот порт хосту, на котором запущен контейнер, следующим образом:
docker run -p 8080:8080 dockertest
Это работает, и я получаю доступ к серверу через IP-адрес машины докера (тот, который появляется в терминале быстрого запуска Docker при запуске), проблема в том, что я не могу получить доступ к веб-сайту, который я размещаю за пределами хоста, поэтому, если я попытаюсь чтобы открыть тот же IP-адрес на моем телефоне, я получаю сообщение об ошибке: эта веб-страница недоступна (ERR_CONNECTION_TIMED_OUT).
Я также пробовал указать IP вот так:
docker run -p 192.168.0.157:8080:8080 dockertest
Но когда я это сделаю, я не могу получить доступ к веб-сайту ни через IP-адрес докера, ни через указанный IP-адрес в командной строке выше. Я также не уверен, какой IP-адрес я должен написать в этой команде. Я использовал IP-адрес своего компьютера, я также пробовал 127.0.0.1 (localhost), но это дало мне тот же результат: не удалось получить доступ к веб-сайту через любой IP вообще.
Я погуглил эту проблему и нашел много вопросов по StackOverflow, но ни один из них не помог мне решить мою проблему, большинство из них были ориентированы на Linux или Mac, поэтому решение не применимо к моей ситуации.
Кроме того, я могу запустить код Go на моем компьютере и получить доступ к веб-сайту с другого устройства в той же сети через IP-адрес моего компьютера. Я не понимаю, почему я не могу получить к нему доступ, когда я запускаю его на докере, мне пришло в голову, что это может иметь какое-то отношение к переадресации IP или чему-то еще, но я полный нуб в сети, я Я в основном веб-разработчик и почти не имею опыта работы с нативным языком.
источник
Ответы:
TL; DR Проверьте сетевой режим вашего хоста VirtualBox - он должен быть,
bridged
если вы хотите, чтобы виртуальная машина (и контейнер Docker, на котором она размещена) были доступны в вашей локальной сети.Похоже, ваша путаница заключается в том, к какому хосту подключиться, чтобы получить доступ к вашему приложению через HTTP. Вы на самом деле не объяснили, какая у вас конфигурация - я собираюсь сделать несколько предположений, основываясь на том факте, что у вас есть «Windows» и «VirtualBox» в ваших тегах.
Я предполагаю, что у вас есть Docker, работающий на какой-то разновидности Linux, работающей в VirtualBox на хосте Windows. Я собираюсь обозначить IP-адреса следующим образом:
D
= IP-адрес контейнера DockerL
= IP-адрес хоста Linux, работающего в VirtualBoxW
= IP-адрес хоста WindowsКогда вы запускаете приложение Go на хосте Windows, вы можете подключиться к нему
http://W:8080/
из любой точки локальной сети. Это работает, потому что приложение Go связывает порт 8080 на машине с Windows, и любой, кто пытается получить доступ к порту 8080 по IP-адресу,W
будет подключен.И вот здесь все усложняется:
VirtualBox, когда он устанавливает виртуальную машину (ВМ), может настроить сеть в одном из нескольких различных режимов. Я не помню, какие есть разные варианты, но тот, который вам нужен, есть
bridged
. В этом режиме VirtualBox подключает виртуальную машину к вашей локальной сети, как если бы это была отдельная машина в сети, как и любая другая машина, подключенная к вашей сети. Вbridged
режиме виртуальная машина появляется в вашей сети, как и любая другая машина. В других режимах все настроено иначе, и машина не будет видна в вашей сети.Итак, если вы правильно настроили сеть для хоста Linux (
bridged
), хост Linux будет иметь IP-адрес в вашей локальной сети (что-то вроде 192.168.0.x), и вы сможете получить доступ к своему контейнеру Docker по адресуhttp://L:8080/
.Если хост Linux установлен в какой-либо режим, отличный от
bridged
, вы можете получить доступ с хоста Windows, но это будет зависеть от того, в каком именно режиме он находится.РЕДАКТИРОВАТЬ - судя по комментариям ниже, похоже, что описанная выше ситуация верна.
Давайте сделаем резервную копию: вот как Docker работает на моем компьютере (Ubuntu Linux).
Представьте себе , я запускаю ту же команду , вы должны:
docker run -p 8080:8080 dockertest
. Это запускает новый контейнер на основеdockertest
образа и перенаправляет (подключает) порт 8080 на хосте Linux (мой компьютер) на порт 8080 на контейнере. Docker настраивает собственную внутреннюю сеть (со своим собственным набором IP-адресов), чтобы демон Docker мог взаимодействовать, а контейнеры - друг с другом. Итак, в основном то, что вы делаете с этим,-p 8080:8080
- это соединение внутренней сети Docker с «внешней» сетью, т.е. сетевой адаптер хоста - на конкретный порт.Со мной так далеко? Хорошо, теперь давайте сделаем шаг назад и посмотрим на вашу систему. На вашем компьютере работает Windows - Docker (в настоящее время) не работает в Windows, поэтому используемый вами инструмент настроил хост Linux на виртуальной машине VirtualBox. Когда вы делаете это
docker run
в своей среде, происходит то же самое - порт 8080 на хосте Linux соединяется с портом 8080 на контейнере. Большая разница здесь в том, что ваш хост Windows не является хостом Linux, на котором работает контейнер, поэтому здесь есть еще один уровень, и это связь через этот уровень, на котором вы сталкиваетесь с проблемами.Вам нужно одно из двух:
для подключения порта 8080 на виртуальной машине VirtualBox к порту 8080 на хосте Windows, точно так же, как вы подключаете контейнер Docker к порту хоста.
чтобы подключить виртуальную машину VirtualBox напрямую к вашей локальной сети в
bridged
описанном выше сетевом режиме.Если вы выберете первый вариант, вы сможете получить доступ к контейнеру,
http://W:8080
гдеW
находится IP-адрес или имя хоста Windows. Если вы выберете второй вариант, вы сможете получить доступ к контейнеру, вhttp://L:8080
которомL
находится IP-адрес или имя хоста виртуальной машины Linux.Итак, это все объяснение более высокого уровня - теперь вам нужно выяснить, как изменить конфигурацию виртуальной машины VirtualBox. И вот здесь я не могу вам помочь - я не знаю, какой инструмент вы используете для всего этого на своем компьютере с Windows, и я совсем не знаком с использованием Docker в Windows.
Если вы можете перейти в окно конфигурации VirtualBox, вы можете внести изменения, описанные ниже. Существует также клиент командной строки, который изменяет виртуальные машины, но я с этим не знаком.
Для
bridged
режима (и это действительно самый простой выбор) выключите виртуальную машину, нажмите кнопку «Настройки» вверху и измените сетевой режим наbridged
, затем перезапустите виртуальную машину, и все готово. Виртуальная машина должна получать IP-адрес в вашей локальной сети через DHCP и должна быть видна другим компьютерам в сети по этому IP-адресу.источник
docker run -p 8080:8080 dockertest
я могу получить доступ к своему веб-сайту, используя,http://192.168.99.100:8080
но только с моего компьютера Windows ( host), а не с моего телефона. Если я использую,docker run -p 192.168.0.157:8080:8080 dockertest
я не могу получить доступ к веб-сайту с любого IP-адреса из любого места. Я не уверен, как настроить сеть, я пробовал использовать,--net=bridge
но это тоже не сработало. Могу ли я открыть VirtualBox? Разве я не могу это сделать с помощью терминала Docker?bridged
Virtual Box, и теперь он творит чудеса, большое вам спасибо.Теперь вы можете перейти к своему контейнеру через localhost: 8080 и your-internal-ip: 8080.
источник
Попробовав несколько вещей, это сработало для меня:
С адресами, отличными от
0.0.0.0
меня, успеха не имел.источник
TL; DR: если у вас включен брандмауэр Windows, убедитесь, что есть исключение для «vpnkit» в частных сетях.
В моем конкретном случае я обнаружил, что брандмауэр Windows блокирует мое соединение, когда я пытался посетить опубликованный порт моего контейнера с другого компьютера в моей локальной сети, потому что его отключение заставляло все работать.
Однако я не хотел полностью отключать брандмауэр только для того, чтобы получить доступ к службе моего контейнера. Это вызвало вопрос о том, какое «приложение» слушает от имени службы моего контейнера. Обнаружив еще один поток SO, который научил меня использовать
netstat -a -b
для обнаружения приложений, стоящих за сокетами для прослушивания на моем компьютере, я узнал, что это былиvpnkit.exe
, которые уже имели запись в моих настройках брандмауэра Windows: но «частные сети» были отключены на нем, и как только я его включил, я смог посетить службу моего контейнера с другого компьютера без необходимости полностью отключать брандмауэр.источник
Это наиболее частая проблема, с которой сталкиваются пользователи Windows при запуске контейнеров Docker. ИМО, это «вопрос на миллион долларов по Docker»; @ "Rocco Smit" справедливо указал, что "входящий трафик был отключен по умолчанию на брандмауэре моей хост-машины"; в моем случае - программа McAfee Anti Virus. Я добавил дополнительные порты для входящего трафика с других компьютеров в той же сети Wi-Fi в настройках брандмауэра McAfee; тогда это было волшебство. Более недели я боролся за просмотр по всему Интернету, документацию SO, Docker, учебники за учебниками, связанные с сетью Docker, и множество иллюстраций «не поддерживается в Windows» для «macvlan», «ipvlan», «пользователя» определил мост "и даже пару раз тот же тред SO. Я даже начал просматривать Google со словами «кто-нибудь, кто использует Docker в производственной среде?» (Да, я знаю, что Linux более популярен для рабочих нагрузок Prod по сравнению с серверами Windows), поскольку я не мог получить доступ (со своего мобильного телефона в том же домашнем Wi-Fi) к nginx приложение, развернутое в контейнере Docker в Windows. В конце концов, что в этом хорошего, если вы не можете получить доступ к приложению (развернутому в контейнере Docker) с других компьютеров / устройств, по крайней мере, в той же локальной сети; В конечном итоге в моем случае проблема заключалась только в том, что брандмауэр блокировал входящий трафик; если вы не можете получить доступ к приложению (развернутому в контейнере Docker) с других компьютеров / устройств, по крайней мере, в той же локальной сети; В конечном итоге в моем случае проблема заключалась только в том, что брандмауэр блокировал входящий трафик; если вы не можете получить доступ к приложению (развернутому в контейнере Docker) с других компьютеров / устройств, по крайней мере, в той же локальной сети; В конечном итоге в моем случае проблема заключалась только в том, что брандмауэр блокировал входящий трафик;
источник
Я обнаружил, что наряду с установкой значений порта -p Docker для Windows использует vpnkit, и входящий трафик, поскольку он был отключен по умолчанию на брандмауэре моего хост-компьютера. После включения правил входящего TCP для vpnkit я смог получить доступ к своим контейнерам с других машин в локальной сети.
источник