简体   繁体   English

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

[英]Docker port mapping is failing for host network mode

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

I have a very bizarre situation with Docker that I absolutely cannot explain! 我有一个非常离奇的Docker情况,我绝对无法解释!

  • I have a Dockerized web service that runs perfectly fine outside of Docker, running off of port 9200 (so: http://localhost:9200 ) 我有一个Dockerized Web服务,在Docker之外运行完全正常,运行端口9200(所以: http://localhost:9200
  • I can also run several other images locally (nginx, Oracle DB) and I can access them via localhost:80 and localhost:1521 respectively 我也可以在本地运行其他几个图像(nginx,Oracle DB),我可以分别通过localhost:80localhost:1521访问它们。
  • When I run the container for my Dockerized service, I see (via docker logs <containerId> ) the service startup without any errors whatsoever 当我为我的Dockerized服务运行容器时,我看到(通过docker docker logs <containerId> )服务启动时没有任何错误
  • Despite the fact that the container is running without any errors, I absolutely cannot connect to it from my Mac host via localhost:9200 尽管容器运行没有任何错误,但我绝对无法通过localhost:9200从我的Mac主机连接到它

The exact steps to reproduce are: 重现的确切步骤是:

  1. Clone this repo 克隆这个回购
  2. Build the image via ./gradlew clean build && docker build -t locationservice . 通过./gradlew clean build && docker build -t locationservice .构建映像./gradlew clean build && docker build -t locationservice .
  3. Run the container via docker run -it -p 9200:9200 -d --net="host" --name locationservice locationservice 通过docker run -it -p 9200:9200 -d --net="host" --name locationservice locationservice运行容器docker run -it -p 9200:9200 -d --net="host" --name locationservice locationservice
  4. If you use docker ps to obtain the <containerId> , then you can keep hitting docker logs <containerId> until you see it has started up without errors 如果你使用docker ps来获取<containerId> ,那么你可以继续点击docker logs <containerId>直到看到它已经启动而没有错误
  5. On my machine, when I try to curl against localhost:9200 , I get " connection refused " errors (see below) 在我的机器上,当我尝试卷曲localhost:9200 ,我收到“ 连接被拒绝 ”错误(见下文)

curl error is: 卷曲错误是:

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

Some things I have ruled out: 我已经排除了一些事情:

  • localhost is absolutely resolveable from the host because we're running in host network mode and I have no problem connecting to nginx (port 80) and Oracle (port 1521) containers localhost绝对可以从主机解析,因为我们在host网络模式下运行,我连接到nginx(端口80)和Oracle(端口1521)容器没有问题
  • The app is starting up and if you look at the logs you'll see it is starting up listening on 9200 该应用程序正在启动,如果您查看日志,您将看到它正在开始收听9200

Any ideas what the problem could be?! 任何想法可能是什么问题?!

Docker for Mac runs in a VM. Docker for Mac在VM中运行。 --net=host refers to the Linux VM hosts network stack not OSX. --net=host是指Linux VM主机网络堆栈而不是OSX。 There is no direct network path from OSX to the Docker VM other than mapped ports. 除了映射端口之外,没有从OSX到Docker VM的直接网络路径。

Mapped ports ( docker run -p Y:N ) in Docker for Mac are a little special, in addition to the user space proxy that runs on the Docker host normally, Docker for Mac also launches a user space proxy on OSX to listen on the same port and forward connections into the VM. Docker for Mac中的映射端口( docker run -p Y:N )有点特别,除了正常运行在Docker主机上的用户空间代理之外,Docker for Mac还会在OSX上启动用户空间代理来监听与VM相同的端口和转发连接。 The OSX process isn't started when using --net=host (and the Linux one isn't either of course). 使用--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
→ 

Then without --net=host 然后没有--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)

If your app requires --net=host then I would use Vagrant/Virtualbox to spin up a VM with a "Host Only" adapter. 如果您的应用需要--net=host那么我会使用Vagrant / Virtualbox来启动具有“仅主机”适配器的VM。 This means there is a direct network path that you can access from OSX on the VM. 这意味着您可以从VM上的OSX访问直接网络路径。 Here's the Vagrantfile I use. 这是我使用的Vagrantfile

Docker for Mac does not support host network mode very well: https://github.com/docker/for-mac/issues/1031 Docker for Mac不能很好地支持主机网络模式: https//github.com/docker/for-mac/issues/1031

So at this moment the solution is to use default bridge mode. 所以此时解决方案是使用默认桥接模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM