Як підключитися до контейнера докера за межами хоста (тієї ж мережі) [Windows]


88

Я створив свій перший контейнер докера, на ньому працює сервер за допомогою 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-адреси, або щось інше, але я повний нуб у мережі, я Я в основному веб-розробник і майже не маю досвіду роботи з рідною мовою.


Ви використовували EXPOSE 8080 у своєму Dockerfile разом із опцією -p? Крім того, переконайтеся, що порт 8080 на коробці, де працює ваш контейнер, не заблокований вашими правилами безпеки.
Кеда,

@keda Так, файл Docker містить EXPOSE 8080. Я запускаю контейнер локально на своєму комп’ютері через термінал Quickstart Docker, я також спробував відключити брандмауер Windows, але це не спрацювало, я не знаю, чи є якісь налаштування
Мені не

Відповіді:


90

TL; DR Перевірте режим мережі вашого хосту VirtualBox - він повинен бути, bridgedякщо ви хочете, щоб віртуальна машина (і контейнер Docker, на якому вона розміщується) була доступною у вашій локальній мережі.


Схоже, ваша плутанина полягає в тому, до якого хосту підключитися, щоб отримати доступ до вашої програми через HTTP. Ви насправді не вказали, яка у вас конфігурація - я збираюся зробити деякі здогади, виходячи з того, що у вас є теги "Windows" і "VirtualBox".

Я здогадуюсь, що у вас Docker працює на якомусь смаку Linux, який працює у VirtualBox на хості Windows. Я збираюся позначити IP-адреси таким чином:

D = IP-адреса контейнера Docker

L = IP-адреса хосту Linux, запущеного у VirtualBox

W = IP-адреса хосту Windows

Коли ви запускаєте програму Go на хості Windows, ви можете підключитися до неї з http://W:8080/будь-якої точки вашої локальної мережі. Це працює, оскільки програма Go пов'язує порт 8080 на машині Windows, і кожен, хто намагається отримати доступ до порту 8080 за IP-адресою W, підключиться.

І ось де це ускладнюється:

VirtualBox, налаштовуючи віртуальну машину (VM), може налаштувати мережу в одному з декількох різних режимів. Я не пам’ятаю, які існують різні варіанти, але той, який ви хочете, - це bridged. У цьому режимі VirtualBox підключає віртуальну машину до вашої локальної мережі так, ніби це автономна машина в мережі, як і будь-яка інша машина, підключена до вашої мережі. У bridgedрежимі віртуальна машина з’являється у вашій мережі, як і будь-яка інша машина. Інші режими налаштовують інакше, і апарат не буде видно у вашій мережі.

Отже, якщо припустити, що ви правильно налаштували мережу для хосту Linux ( bridged), хост Linux матиме IP-адресу у вашій локальній мережі (щось на зразок 192.168.0.x), і ви зможете отримати доступ до свого контейнера Docker за адресою http://L:8080/.

Якщо для хоста Linux встановлено інший режим, ніж bridged, можливо , ви зможете отримати доступ із хосту Windows, але це буде залежати від того, в якому саме режимі він знаходиться.

EDIT - виходячи з коментарів нижче, схоже, ситуація, яку я описав вище, є правильною.

Давайте зробимо трохи резервної копії: ось як 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, на якому запущений контейнер, тому тут є ще один рівень, і це зв’язок через цей рівень, де у вас виникають проблеми.

Потрібна одна з двох речей:

  1. для підключення порту 8080 на VirtualBox VM до порту 8080 на хості Windows, подібно до того, як ви підключаєте контейнер Docker до порту хосту.

  2. для підключення VirtualBox VM безпосередньо до вашої локальної мережі за допомогою bridgedмережевого режиму, який я описав вище.

Якщо ви вибрали перший варіант, ви зможете отримати доступ до контейнера за адресою, http://W:8080де Wзнаходиться IP-адреса або ім’я хосту Windows. Якщо ви оберете другу, ви зможете отримати доступ до контейнера за адресою, http://L:8080де Lзнаходиться IP-адреса або ім'я хосту віртуальної машини Linux.

Отже, це все пояснення вищого рівня - тепер вам потрібно з’ясувати, як змінити конфігурацію VirtualBox VM. І ось тут я не можу вам дійсно допомогти - я не знаю, за допомогою якого інструменту ви все це робите на своїй машині Windows, і я зовсім не знайомий з використанням Docker в Windows.

Якщо ви можете перейти до вікна конфігурації VirtualBox, ви можете внести зміни, описані нижче. Існує також клієнт командного рядка, який буде модифікувати віртуальні машини, але я з цим не знайомий.

Для bridgedрежиму (і це насправді найпростіший вибір) вимкніть ВМ, натисніть кнопку «Налаштування» вгорі та змініть режим мережі на bridged, а потім перезапустіть ВМ, і все готово. Віртуальна машина повинна підібрати IP-адресу у вашій локальній мережі через DHCP і бути видимою для інших комп'ютерів у мережі за цією IP-адресою.


1
Я можу знайти лише 2 IP-адреси, той, який Docker показує, коли я відкриваю термінал швидкого запуску (192.168.99.100), і той, який є на моєму комп'ютері (192.168.0.157), використовуючи docker run -p 8080:8080 dockertestЯ можу отримати доступ до свого веб-сайту за допомогою, http://192.168.99.100:8080але лише з мого комп'ютера Windows ( хост), а не з мого телефону. Якщо я використовую, docker run -p 192.168.0.157:8080:8080 dockertestя не можу отримати доступ до веб-сайту з будь-яким IP-адресою з будь-якого місця. Я не знаю, як налаштувати мережу, я намагався використовувати, --net=bridgeале це не спрацювало. Чи повинен я відкрити VirtualBox? Чи не можу я це зробити за допомогою терміналу Docker?
redsalt

Проблема не в Docker, тому ні, Docker не може вам допомогти. Я збираюся додати деякі правки, щоб проілюструвати, що, на мою думку, відбувається.
Kryten

Добре, дякую! Тепер я розумію, мене бентежила вся частина віртуальної машини Linux. У мене склалося враження, що Докер використовує Virtual Box для внутрішніх речей, до яких я не мав стосуватися. Насправді це було дуже просто, мені просто довелося перейти на bridgedVirtual Box, і тепер це творить чудеса, велике спасибі.
redsalt

Чи не існує жодного способу мати вікна та контейнери докерів в одній мережі, щоб ми могли отримати доступ до контейнерів безпосередньо без переадресації портів?
Vituel

Натрапив на це під час пошуку запущеного сервера Jupyter у докері та спроби отримати до нього доступ через локальну мережу. Чи можу я все-таки дізнатися, що таке L, після того, як переключити режим на мостовий?
PaulDong

121
  1. Відкрийте Oracle VM VirtualBox Manager
  2. Виберіть ВМ, що використовується Docker
  3. Клацніть Налаштування -> Мережа
  4. Адаптер 1 повинен (за замовчуванням?) Бути "Приєднаний до: NAT"
  5. Клацніть Додатково -> Переадресація портів
  6. Додати правило: протокол TCP, хост-порт 8080, гостьовий порт 8080 (залишити IP-адресу хоста та IP-адресу гостя порожніми)
  7. Гість - це ваш контейнер докера, а Хост - ваша машина

Тепер ви зможете переглядати свій контейнер через localhost: 8080 та your-internal-ip: 8080.


10
Підтверджено, приємно і просто.
Дірк

2
найкраща відповідь, жодного величезного опису, як вибраний
Амір Каюм Хан

2
для користувачів-бродяг додайте це у файл vagrant: config.vm.network "forwarded_port", гість: 8080, хост: 8080, протокол: "tcp"
Вінс Верховен

3
Йо! Це спрацювало як шарм! Дякую!!!! Я годинами намагаюся це зрозуміти.
Джозеф Фрімен,

2
Це фантастичне рішення для тих, хто запускає Docker через VBox!
Mirodinho

7

Спробувавши кілька речей, це спрацювало для мене:

  • використовуйте --publish = 0.0.0.0: 8080: 8080 прапор докера
  • встановіть мережевий режим virtualbox на NAT і не використовуйте переадресацію портів

З іншими адресами 0.0.0.0я не мав успіху.


4

TLDR: Якщо у вас увімкнено брандмауер Windows, переконайтеся, що існує виняток для "vpnkit" у приватних мережах.

В моєму конкретному випадку я виявив, що брандмауер Windows блокував моє з’єднання, коли я намагався відвідати опублікований порт мого контейнера з іншої машини в моїй локальній мережі, оскільки його відключення змусило все працювати.

Однак я не хотів повністю вимикати брандмауер лише для того, щоб отримати доступ до служби мого контейнера. Це породило питання про те, який «додаток» слухає від імені служби мого контейнера. Знайшовши інший SO-потік, який навчив мене використовувати netstat -a -bпрограми для розпізнавання сокетів на моїй машині, я дізнався, що це було vpnkit.exe, що вже входило в налаштування мого брандмауера Windows: але "приватні мережі" в ньому було відключено, і Після того, як я його ввімкнув, я зміг відвідати службу мого контейнера з іншої машини без необхідності повністю вимикати брандмауер.


Пане, ви врятували мене від годин і годин розчарувань. Дякую.
Бехдад,

2

Це найпоширеніша проблема, з якою стикаються користувачі Windows під час запуску контейнерів Docker. ІМО - це "питання щодо мільйонів доларів щодо Docker"; @ "Rocco Smit" справедливо зазначив, що "вхідний трафік за замовчуванням відключений на брандмауері моєї хост-машини"; у моєму випадку - моє антивірусне програмне забезпечення McAfee. Я додав додаткові порти для дозволу на вхідний трафік з інших комп’ютерів у тій же локальній мережі Wi-Fi у налаштуваннях брандмауера McAfee; тоді це була магія. Я боровся більше тижня, переглядаючи Інтернет, SO, документацію Docker, підручники після підручників, пов’язаних з мережею Docker, і безліч ілюстрацій "не підтримується в Windows" для "macvlan", "ipvlan", "user визначений міст "і навіть цей самий потік SO кілька разів. Я навіть почав переглядати google з "хтось використовує Docker у виробництві?" (Так, я знаю, що Linux більш популярний для робочих навантажень Prod порівняно із серверами Windows), оскільки я не мав доступу (зі свого мобільного в тому ж домашньому wifi) до nginx додаток, розгорнутий у контейнері Docker у Windows. Зрештою, яка це користь, якщо ви не можете отримати доступ до програми (розгорнутої на контейнері Docker) з принаймні інших комп'ютерів / пристроїв у тій самій локальній мережі; Зрештою, у моєму випадку проблема полягала лише у брандмауері, який блокував вхідний трафік; якщо ви не можете отримати доступ до програми (розгорнутої на контейнері Docker) з принаймні інших комп’ютерів / пристроїв у тій самій локальній мережі; Зрештою, у моєму випадку проблема полягала лише у брандмауері, який блокував вхідний трафік; якщо ви не можете отримати доступ до програми (розгорнутої на контейнері Docker) з принаймні інших комп’ютерів / пристроїв у тій самій локальній мережі; Зрештою, у моєму випадку проблема полягала лише у брандмауері, який блокував вхідний трафік;


0

Я виявив, що поряд із встановленням значень порту -p, Docker для Windows використовує vpnkit та вхідний трафік, оскільки він за замовчуванням вимкнений на брандмауері моєї хост-машини. Після активації вхідних правил TCP для vpnkit я зміг отримати доступ до своїх контейнерів з інших машин у локальній мережі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.