Docker Windows 的桌面:无法在 windows 容器模式下访问公开端口上的服务
Docker Desktop for Windows: cannot access service on exposed port in windows container mode
我正在使用以下 Docker 文件 在 Windows 上的 windows 容器中创建容器 运行 Jenkins 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:\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 文件创建图像:
docker build -t windows-java:jre1.8.0_91 .
我用来安装 Jenkins 的第二个 Docker 文件:
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
但是,我无法在主机的网络浏览器上 http://localhost:8080
上访问 jenkins 服务器 运行。
不确定是否有帮助,但是当我在同一台机器上 运行 docker 处于 Linux container
模式时,我能够在 http://localhost:8080
上访问 jenkins 服务器
使用他们的官方 docker 图片。
这是 Windows 上的一个当前已知问题。无法使用 localhost/127.0.0.1 从其自己的主机访问容器端点。今天可以使用 Linux 容器,因为 Docker 包含一个特殊的解决方法,该解决方法是 运行 Linux 容器在 Windows 上的 Moby/Linux 实施所独有的].
我们正在努力解决此问题,但今天我们建议您通过以下任一方式解决此问题:
- 从单独的主机访问容器端点,使用作为运行容器的主机的IP地址,以及容器在其主机上的公开端口
- 或者通过访问同一主机上的容器,使用容器的内部IP地址和发布的端口(您可以使用
docker network inspect <network name>
或 docker exec <container ID> ipconfig>
获取容器端点本身的 IP 地址)
完成@Kallie-Microsoft post:
docs.docker.com 已更新为 Limitations of Windows containers for localhost and published ports
Docker for Windows provides the option to switch Windows and Linux
containers. If you are using Windows containers, keep in mind that
there are some limitations with regard to networking due to the
current implementation of Windows NAT (WinNAT). These limitations may
potentially resolve as the Windows containers project evolves.
One thing you may encounter rather immediately is that published ports
on Windows containers do not do loopback to the local host. Instead,
container endpoints are only reachable from the host using the
container’s IP and port.
So, in a scenario where you use Docker to pull an image and run a
webserver with a command like this:
docker run -d -p 80:80 --name webserver nginx
Using curl http://localhost, or pointing your web browser at
http://localhost will not display the nginx web page (as it would do
with Linux containers).
In order to reach a Windows container from the local host, you need to
specify the IP address and port for the container that is running the
service.
You can get the container IP address by using docker inspect with some
--format options and the ID or name of the container. For the example above, the command would look like this, using the name we gave to the
container (webserver) instead of the container ID:
$ docker inspect \
--format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
webserver
看来这个问题似乎没有以前那么无聊了。以下文档位于 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,它解决了访问 Windows 系统上公开的 Docker 容器端口的问题。当 运行 容器时,只需使用带 IP 地址的 -p 开关。
docker run --rm -it -p 127.0.0.1:3000:3000 ubuntu:latest
我遇到了同样的问题,docker 运行 命令的顺序很重要。
docker run -p <host port>:<container port> <image>
作品
docker run <image> -p <host port>:<container port>
不起作用
我的设置 -
使用 Windows 10,版本 2004(OS 内部版本 19041.329)
启用 WSL 2 - https://docs.microsoft.com/en-us/windows/wsl/wsl2-index
Ubuntu 18.04 从 Microsoft 商店安装并在 docker 中启用。
这里的问题是“localhost”无法解析为您的容器 IP 地址,因为它不是 运行 直接位于 Windows 上,而是位于 Linux 虚拟机上世界语言联盟。这是一个 known issue with Docker Desktop.
您必须做的是将您的本地端口(在 Windows 上)绑定到 WSL 上的端口。
在Windows终端/Powershell中:
获取 Linux 虚拟机的 IP 地址(Docker Desktop 在 WSL2 中创建了一个名为“docker-desktop”的发行版)
$wsl_ip = (wsl -d "docker-desktop" -- "ifconfig" "eth0" "|" "grep" "inet addr:").trim("").split(":").split()[2]
将您的本地端口绑定到 Linux 上的相同端口(参见 Netsh)
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=$wsl_ip
我正在使用以下 Docker 文件 在 Windows 上的 windows 容器中创建容器 运行 Jenkins 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:\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 文件创建图像:
docker build -t windows-java:jre1.8.0_91 .
我用来安装 Jenkins 的第二个 Docker 文件:
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
但是,我无法在主机的网络浏览器上 http://localhost:8080
上访问 jenkins 服务器 运行。
不确定是否有帮助,但是当我在同一台机器上 运行 docker 处于 Linux container
模式时,我能够在 http://localhost:8080
上访问 jenkins 服务器
使用他们的官方 docker 图片。
这是 Windows 上的一个当前已知问题。无法使用 localhost/127.0.0.1 从其自己的主机访问容器端点。今天可以使用 Linux 容器,因为 Docker 包含一个特殊的解决方法,该解决方法是 运行 Linux 容器在 Windows 上的 Moby/Linux 实施所独有的].
我们正在努力解决此问题,但今天我们建议您通过以下任一方式解决此问题:
- 从单独的主机访问容器端点,使用作为运行容器的主机的IP地址,以及容器在其主机上的公开端口
- 或者通过访问同一主机上的容器,使用容器的内部IP地址和发布的端口(您可以使用
docker network inspect <network name>
或docker exec <container ID> ipconfig>
获取容器端点本身的 IP 地址)
完成@Kallie-Microsoft post:
docs.docker.com 已更新为 Limitations of Windows containers for localhost and published ports
Docker for Windows provides the option to switch Windows and Linux containers. If you are using Windows containers, keep in mind that there are some limitations with regard to networking due to the current implementation of Windows NAT (WinNAT). These limitations may potentially resolve as the Windows containers project evolves.
One thing you may encounter rather immediately is that published ports on Windows containers do not do loopback to the local host. Instead, container endpoints are only reachable from the host using the container’s IP and port.
So, in a scenario where you use Docker to pull an image and run a webserver with a command like this:
docker run -d -p 80:80 --name webserver nginx
Using curl http://localhost, or pointing your web browser at http://localhost will not display the nginx web page (as it would do with Linux containers).
In order to reach a Windows container from the local host, you need to specify the IP address and port for the container that is running the service.
You can get the container IP address by using docker inspect with some --format options and the ID or name of the container. For the example above, the command would look like this, using the name we gave to the container (webserver) instead of the container ID:
$ docker inspect \ --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \ webserver
看来这个问题似乎没有以前那么无聊了。以下文档位于 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,它解决了访问 Windows 系统上公开的 Docker 容器端口的问题。当 运行 容器时,只需使用带 IP 地址的 -p 开关。
docker run --rm -it -p 127.0.0.1:3000:3000 ubuntu:latest
我遇到了同样的问题,docker 运行 命令的顺序很重要。
docker run -p <host port>:<container port> <image>
作品
docker run <image> -p <host port>:<container port>
不起作用
我的设置 -
使用 Windows 10,版本 2004(OS 内部版本 19041.329) 启用 WSL 2 - https://docs.microsoft.com/en-us/windows/wsl/wsl2-index Ubuntu 18.04 从 Microsoft 商店安装并在 docker 中启用。
这里的问题是“localhost”无法解析为您的容器 IP 地址,因为它不是 运行 直接位于 Windows 上,而是位于 Linux 虚拟机上世界语言联盟。这是一个 known issue with Docker Desktop.
您必须做的是将您的本地端口(在 Windows 上)绑定到 WSL 上的端口。
在Windows终端/Powershell中:
获取 Linux 虚拟机的 IP 地址(Docker Desktop 在 WSL2 中创建了一个名为“docker-desktop”的发行版)
$wsl_ip = (wsl -d "docker-desktop" -- "ifconfig" "eth0" "|" "grep" "inet addr:").trim("").split(":").split()[2]
将您的本地端口绑定到 Linux 上的相同端口(参见 Netsh)
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=$wsl_ip