Docker端口映射在主机网络模式下失败

时间:2018-03-22 06:18:37

标签: macos docker

Mac在这里运行Docker版本17.12.0-ce-mac55(23011)。

我对Docker有一个非常离奇的情况,我绝对无法解释!

  • 我有一个Dockerized Web服务,在Docker之外运行完全正常,运行端口9200(所以:http://localhost:9200
  • 我也可以在本地运行其他几个图像(nginx,Oracle DB),我可以分别通过localhost:80localhost:1521访问它们
  • 当我为Dockerized服务运行容器时,我看到(通过docker logs <containerId>)服务启动没有任何错误
  • 尽管容器正在运行且没有任何错误,但我绝对无法通过localhost:9200
  • 从我的Mac主机连接到它

要重现的具体步骤是:

  1. Clone this repo
  2. 通过./gradlew clean build && docker build -t locationservice .
  3. 构建图片
  4. 通过docker run -it -p 9200:9200 -d --net="host" --name locationservice locationservice
  5. 运行容器
  6. 如果您使用docker ps获取<containerId>,那么您可以继续点击docker logs <containerId>,直到您看到它已启动且没有错误
  7. 在我的计算机上,当我尝试卷曲localhost:9200时,我收到“连接拒绝”错误(见下文)
  8. 卷曲错误是:

    curl -X GET http://localhost:9200/bupo
    curl: (7) Failed to connect to localhost port 9200: Connection refused
    

    我排除了一些事情:

    • localhost绝对可以从主机解析,因为我们在host网络模式下运行,连接到nginx(端口80)和Oracle(端口1521)容器没有问题
    • 应用程序正在启动,如果您查看日志,您会看到它正在开始收听9200

    任何想法可能是什么问题?!

2 个答案:

答案 0 :(得分:2)

Docker for Mac在VM中运行。 --net=host是指Linux VM托管网络堆栈而不是OSX。除了映射端口之外,没有从OSX到Docker VM的直接网络路径。

Docker for Mac中的映射端口(docker run -p Y:N)有点特别,除了用户space proxy that runs on the Docker host之外,Docker for Mac还会在OSX上启动用户空间代理以侦听同一端口并转发到VM的连接。使用--net=host时没有启动OSX进程(当然Linux也不是。)

→ docker run --name nc --rm --net=host -dp 9200:9200 busybox nc -lk -p 9201 -e echo hey
→ docker inspect nc --format '{{ json .NetworkSettings.Ports }}'
{}  
→ sudo lsof -Pni | grep 9200
→ 

然后没有--net=host

→ docker run --name nc --rm -dp 9200:9200 busybox nc -lk -p 9201 -e echo hey
→ docker inspect nc --format '{{ json .NetworkSettings.Ports }}'
{"9200/tcp":[{"HostIp":"0.0.0.0","HostPort":"9200"}]}
→ sudo lsof -Pni | grep 9200
vpnkit    42658           matt   28u  IPv4 0x57f79853269b81bf      0t0  TCP *:9200 (LISTEN)
vpnkit    42658           matt   29u  IPv6 0x57f798532765ca9f      0t0  TCP [::1]:9200 (LISTEN)

如果您的应用需要--net=host,那么我会使用Vagrant / Virtualbox来启动具有“仅限主机”适配器的VM。这意味着您可以从VM上的OSX访问直接网络路径。这是我使用的Vagrantfile

答案 1 :(得分:1)

Docker for Mac不能很好地支持主机网络模式:https://github.com/docker/for-mac/issues/1031

所以此时解决方案是使用默认桥接模式。