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

я использую следующие Dockerfiles для создания контейнера под управлением Jenkins в контейнере windows на рабочем столе Windows 10 под управлением docker для 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:Javajre1.8.0_91" ; del C:jreinstaller.exe

ENV JAVA_HOME c:Javajre1.8.0_91  
RUN setx PATH %PATH%;%JAVA_HOME%bin

CMD [ "java.exe" ]

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

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

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

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:jenkinsjenkins.war


docker build -t jenkins-windows:2.0 .

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

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

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

PS C:Usersmandeepringbaringba-jenkins-setup-windowsjenkins-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

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

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

2 ответов


в настоящее время это известная проблема в 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-адрес самой конечной точки контейнера)

для завершения @Kallie-Microsoft post:

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


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 с некоторыми -- параметры формата и ID или название контейнера. В приведенном выше примере команда будет выглядеть следующим образом, используя имя, которое мы дали контейнер (веб-сервер) вместо идентификатора контейнера:

$ docker inspect \
  --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
  webserver