Docker Desktop для Windows: не удается получить доступ к службе на открытом порту в режиме контейнера Windows

Я использую следующие Dockerfiles для создания контейнера с Jenkins в контейнере Windows на рабочем столе Windows 10 с Docker Desktop для Windows версии 17.03.

FROM microsoft/windowsservercore

RUN powershell -Command wget 'http://javadl.oracle.com/webapps/download/AutoDL?BundleId=210185' -Outfile 'C:\jreinstaller.exe' ; Start-Process -filepath C:\jreinstaller.exe -passthru -wait -argumentlist "/s,INSTALLDIR=c:\Java\jre1.8.0_91" ; del C:\jreinstaller.exe

ENV JAVA_HOME c:\\Java\\jre1.8.0_91  
RUN setx PATH %PATH%;%JAVA_HOME%\bin

CMD [ "java.exe" ]

Я создаю образ из этого файла докера:

docker build -t windows-java:jre1.8.0_91 .

Второй Dockerfile, который я использую для установки Jenkins поверх этого:

FROM windows-java:jre1.8.0_91

ENV HOME /jenkins  
ENV JENKINS_VERSION 2.58  
RUN mkdir \jenkins  
RUN powershell -Command "wget -Uri https://updates.jenkins-ci.org/latest/jenkins.war -UseBasicParsing -OutFile /jenkins/jenkins.war"

EXPOSE 8080  
EXPOSE 50000  

CMD java -jar C:\\jenkins\\jenkins.war


docker build -t jenkins-windows:2.0 .

Затем я запускаю контейнер следующим образом:

docker run --name jenkinsci -p 8080:8080 -p 50000:50000  jenkins-windows:2.0

Я вижу, что контейнер работает нормально, и журналы отображаются все хорошо

PS C:\Users\mandeep\ringba\ringba-jenkins-setup-windows\jenkins-master> docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                              NAMES
85ba2ef525a1        jenkins-windows:2.0   "cmd /S /C 'java -..."   8 hours ago         Up 8 hours          0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   jenkinsci

Однако я не могу получить доступ к серверу jenkins, работающему на http://localhost:8080, в веб-браузере хост-компьютера.

Не уверен, поможет ли это, но когда я запускал докер в режиме Linux container на той же машине, я смог получить доступ к серверу jenkins на http://localhost:8080, используя их официальный образ докера.


person Mandeep Singh    schedule 03.05.2017    source источник


Ответы (4)


В настоящее время это известная проблема в Windows. Невозможно получить доступ к конечной точке контейнера с его собственного хоста, используя localhost/127.0.0.1. Сегодня можно использовать контейнеры Linux, потому что Docker включил специальный обходной путь, уникальный для их реализации Moby/Linux для запуска контейнеров Linux в Windows.

Мы работаем над исправлением для этого, но сегодня мы рекомендуем обойти это одним из следующих способов:

  • Доступ к конечным точкам контейнера с отдельного хоста с использованием IP-адреса хоста, на котором запущен контейнер, и открытого порта для контейнера на его хосте.
  • ИЛИ путем доступа к контейнеру на тот же хост, используя внутренний IP-адрес контейнера и опубликованный порт (вы можете использовать docker network inspect <network name> или docker exec <container ID> ipconfig>, чтобы получить IP-адрес самой конечной точки контейнера )
person Kallie-Microsoft    schedule 03.05.2017
comment
Спасибо, Калли. Это сработало отлично. Не могли бы вы исправить IP-адрес локального хоста в своем ответе с 172.0.0.1 на 127.0.0.1? - person Mandeep Singh; 04.05.2017
comment
Отлично, я рад, что это сработало для вас. И вообще - спасибо, что поймали это :) - person Kallie-Microsoft; 05.05.2017
comment
Ааа, я потратил часы, пытаясь это выяснить... Спасибо! - person White hawk; 12.05.2017
comment
Я думаю, это все еще работает только в Win10, а не в Win7 :( - person cst1992; 18.06.2019
comment
http://localhost:{port} теперь работает правильно (Windows 10.0.19041, с установленным и включенным WSL2). - person JohnLBevan; 30.05.2020
comment
@JohnLBevan Я пробовал с WSL 2, но все еще не могу получить доступ к порту для весеннего загрузочного приложения. - person abitcode; 23.06.2020
comment
Решил это, при использовании docker run у меня был параметр -p в конце, который не работал. Изменение порядка сработало. docker run -p 8081:8081 <image> - person abitcode; 23.06.2020

Чтобы завершить сообщение @Kallie-Microsoft:

docs.docker.com был обновлен разделом Ограничения контейнеров Windows для локальных и опубликованных портов


Docker для Windows предоставляет возможность переключения между контейнерами Windows и Linux. Если вы используете контейнеры Windows, имейте в виду, что существуют некоторые ограничения в отношении сети из-за текущей реализации Windows NAT (WinNAT). Эти ограничения потенциально могут быть устранены по мере развития проекта контейнеров Windows.

С одной вещью, с которой вы можете столкнуться довольно быстро, является то, что опубликованные порты в контейнерах Windows не выполняют обратную связь с локальным хостом. Вместо этого конечные точки контейнера доступны только с хоста с использованием IP-адреса и порта контейнера.

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

docker run -d -p 80:80 --name webserver nginx

Используя curl http://localhost, или указав в веб-браузере адрес http://localhost не будет отображать веб-страницу nginx (как это было бы с контейнерами Linux).

Чтобы получить доступ к контейнеру Windows с локального хоста, вам необходимо указать IP-адрес и порт для контейнера, на котором запущена служба.

Вы можете получить IP-адрес контейнера, используя docker inspect с некоторыми параметрами --format и идентификатором или именем контейнера. Для приведенного выше примера команда будет выглядеть так, используя имя, которое мы дали контейнеру (веб-серверу), вместо идентификатора контейнера:

$ docker inspect \
  --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
  webserver
person Alexandre Roux    schedule 30.08.2017
comment
Спасибо. это полезно, но даже после получения IP-адреса. Например 172.17.0.2. Как сделать это доступным для Интернета? Это вопрос настройки маршрутизатора не только для 192.168.0.что угодно, но и для 172.17.0.2? - person Steve Tomlin; 15.11.2019

Я столкнулся с той же проблемой, порядок выполнения команды запуска докера имеет значение.

docker run -p <host port>:<container port> <image> Работает

docker run <image> -p <host port>:<container port> Не работает

Моя установка -

Использование Windows 10 версии 2004 (сборка ОС 19041.329) WSL 2 включен — https://docs.microsoft.com/en-us/windows/wsl/wsl2-index Ubuntu 18.04, установленная из магазина Microsoft и включенная в докере.

image

person abitcode    schedule 23.06.2020

Похоже, этот выпуск уже не кажется таким скучным, как был. Документы для подписчиков на https://docs.docker.com/engine/reference/run/#expose-incoming-ports вы можете указать IP-адрес на хост-компьютере, где вы хотите, чтобы были открыты порты контейнера.

-p=[] : Publish a container's port or a range of ports to the host
               format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
               Both hostPort and containerPort can be specified as a
               range of ports. When specifying ranges for both, the
               number of container ports in the range must match the
               number of host ports in the range, for example:
                   -p 1234-1236:1234-1236/tcp
               When specifying a range for hostPort only, the
               containerPort must not be a range.  In this case, the container port is published somewhere within the specified hostPort range. (e.g., `-p 1234-1236:1234/tcp`)
               (use 'docker port' to see the actual mapping)

Вероятно, это 127.0.0.1, и он решает проблему с доступом к открытому порту контейнера Docker в системе Windows. Просто используйте переключатель -p с IP-адресом при запуске контейнера.

docker run --rm -it -p 127.0.0.1:3000:3000 ubuntu:latest
person Egeshi    schedule 30.01.2020