Mac主机不喜欢Docker容器端口转发

时间:2016-08-26 12:11:39

标签: java macos docker portforwarding docker-networking

我第一次尝试使用Docker,并且正在尝试使用Spring Boot Web应用程序在Docker容器中运行。我正在构建应用程序(它打包成一个独立的jar)和然后将它添加到Docker镜像(这就是我想要的)。

您可以在此SSCCE找到我的Bootup repo on GitHub,其README具有重现我所看到的所有说明。但基本上是:

  • 我将网页应用构建成一个jar
  • 运行成功的docker build -t bootup .
  • 运行docker run -it -p 9200:9200 -d --name bootup bootup然后容器似乎启动就好了,下面docker ps输出的证据
  • 但是,当我将浏览器指向http://localhost:9200时,我什么都没得到

docker ps输出:

CONTAINER ID        IMAGE               COMMAND                  CREATED
a8c4ee64a1bc        bootup              "/bin/sh -c 'java -ja"   2 days ago

STATUS              PORTS                    NAMES
Up 12 seconds       0.0.0.0:9200->9200/tcp   bootup

网络应用程序为configured to run on port 9200 Java默认值为8080.您可以通过在docker之外运行应用程序来自行查看(因此,只在本地主机上)通过运行./gradlew clean build && java -jar build/libs/bootup.jar

据我所知,我的主机上没有运行阻止端口的防火墙(我在Mac 10.11.5上并验证System Preferences >> Security & Privacy >> Firewall已关闭)。

有人能找到我出错的地方吗?

更新

我在主机上投放了curlnetstatlsof

HOST:
curl http://localhost:9200
curl: (52) Empty reply from server

netstat -an | grep 9200
tcp6       0      0  ::1.9200               *.*                    LISTEN     
tcp4       0      0  *.9200                 *.*                    LISTEN 

lsof -n -i4TCP:9200 | grep LISTEN
com.docke 2578 myuser   19u  IPv4 <someHexNumber>      0t0  TCP *:wap-wsp (LISTEN)

然后docker exec进入容器并运行另一个netstat

CONTAINER:
netstat -an | grep 9200
bash: netstat: command not found

更新w /照片:

我的浏览器(Chrome)图片指向http://localhost:9200

enter image description here

http://localhost:9200的源代码图片:

enter image description here

Chrome Developer Tools检查http://localhost:9200页面的图片:

enter image description here

Chrome开发者工具中Network标签的图片:

enter image description here

这里到底发生了什么?!?!?根据消息来源,浏览器应该从Dockerland渲染我的好吧你好!消息就好了。根据实际的浏览器页面,看起来有网络错误。根据Chrome开发者工具,我的应用程序返回各种HTML / CSS / JS内容,甚至远程我的应用程序(查看源代码,自己查看)!

5 个答案:

答案 0 :(得分:2)

Dockerfile不会向守护进程公开9200。添加

reverseUint32(0xfc66feff)

EXPOSE 9200之前的Dockerfile

答案 1 :(得分:2)

假设您使用的是Docker Toolbox而不是beta ...

正确公开端口有三个步骤:

  • 使用EXPOSE 8080其中8080​​只是 Dockerfile
  • 中的端口号
  • 泊坞窗运行命令
  • 中使用-p 8080:8080
  • 确保在Oracle Virtual Box中设置端口转发,以便boot2docker计算机能够从端口8080接收请求。

这适用于使用Docker Toolbox的Windows和OSX。 Linux并不使用Oracle VirtualBox来运行docker,因此那些主机不需要执行第三点

答案 2 :(得分:2)

我在OSX上的Docker 1.12上按原样运行你的repo。

如果仔细查看容器启动:

2016-08-29 20:52:31.028  INFO 5 --- [           main] o.eclipse.jetty.server.ServerConnector   : Started ServerConnector@47949d1a{HTTP/1.1}{0.0.0.0:8080}
2016-08-29 20:52:31.033  INFO 5 --- [           main] .s.b.c.e.j.JettyEmbeddedServletContainer : Jetty started on port(s) 8080 (http/1.1)

虽然application.yml和Dockerfile都包含9200,但应用程序从8080开始

答案 3 :(得分:1)

要在这里添加另一个答案,因为我看到了与您发布的Github Repo相关的内容:

所以repo是一个带有application.yml文件的spring boot repo。

您的Dockerfile如下所示:

FROM openjdk:8

RUN mkdir /opt/bootup

ADD build/libs/bootup.jar /opt/bootup
WORKDIR /opt/bootup
EXPOSE 9200
ENTRYPOINT java -jar bootup.jar

将构建的jar添加到图像中。如果我的理解是正确的,那么jar 不包括application.yml ,因为:

  • 它不是构建的一部分(gradle只打包src / main)。它位于项目根文件夹
  • 未明确添加到Docker

因此,可以假设您的应用目前实际上是在8080(默认值)上运行吗?

可以尝试的几个选项:

  • 尝试暴露8080而不是9200(或暴露两者),看看是否有所作为?
  • entrypoint命令可以附加端口--server.port=9200
  • 应该将application.yml文件添加到图像中(您可能需要添加一个参数才能正确引用它)[ADD application.yml /opt/bootup,在第一个ADD命令之后
  • 在src / main / resources中包含application.yml文件,以便spring boot可以自动获取它。

<强>参考

here

答案 4 :(得分:1)

好消息!(对于MacOSx 10.15.7)

我发现了与您相同的问题,可以直接打开VirutalBox连接来解决此问题

先去这里

VirtualBox hosts Docker Images Network Controller setting 更改为桥接,然后登录VirtualBox中的虚拟机

并找到标有实际机器名称的适配器:

eth0

在我注意到该设置最初是NAT之后,所以我更改为桥接,然后

enter image description here

我能够使用它的地址与本地主机。

使用公共地址后,我使用了:

curl -i [bridged_ip_address_here]:9200

然后它可以正常工作。

但是我也注意到一些防火墙和可访问性选项也需要许可。

Accessibility fix

我祈祷这对您有帮助。