简体   繁体   中英

Docker port mapping is failing for host network mode

Mac running Docker Version 17.12.0-ce-mac55 (23011) here.

I have a very bizarre situation with Docker that I absolutely cannot explain!

  • I have a Dockerized web service that runs perfectly fine outside of Docker, running off of port 9200 (so: 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
  • When I run the container for my Dockerized service, I see (via docker logs <containerId> ) the service startup without any errors whatsoever
  • Despite the fact that the container is running without any errors, I absolutely cannot connect to it from my Mac host via localhost:9200

The exact steps to reproduce are:

  1. Clone this repo
  2. Build the image via ./gradlew clean build && docker build -t locationservice .
  3. Run the container via 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
  5. On my machine, when I try to curl against localhost:9200 , I get " connection refused " errors (see below)

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
  • The app is starting up and if you look at the logs you'll see it is starting up listening on 9200

Any ideas what the problem could be?!

Docker for Mac runs in a VM. --net=host refers to the Linux VM hosts network stack not OSX. There is no direct network path from OSX to the Docker VM other than mapped ports.

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. The OSX process isn't started when using --net=host (and the Linux one isn't either of course).

→ 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

→ 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. This means there is a direct network path that you can access from OSX on the VM. Here's the Vagrantfile I use.

Docker for Mac does not support host network mode very well: https://github.com/docker/for-mac/issues/1031

So at this moment the solution is to use default bridge mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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