Should docker run --net=host work?

Expected behavior

docker run --net=host ...
should connect to local ports/services

Actual behavior

It doesn’t.

Information

OS X: version 10.11.5 (build: 15F34)
Docker.app: version v1.11.1-beta13.1
Running diagnostic tests:
[OK] Moby booted
[OK] driver.amd64-linux
[OK] vmnetd
[OK] osxfs
[OK] db
[OK] slirp
[OK] menubar
[OK] environment
[OK] Docker
[OK] VT-x

Steps to reproduce the behavior

  1. $ python3 -m http.server --bind localhost
  2. $ curl localhost:8000
  3. $ docker run -it --rm --net=host buildpack-deps:curl curl localhost:8000

Run steps 1 & 2 locally outside docker.
For step 3, this works on Linux.

On OSX, the output is simply

curl: (7) Failed to connect to 127.0.0.1 port 8000: Connection refused

I also tried every address known to the container:

$ docker run -it --rm --net=host buildpack-deps:curl sh -c 'for ip in $(ip addr | grep "inet " | cut -d " " -f 6 | cut -d "/" -f 1); do curl ${ip}:8000; done'
curl: (7) Failed to connect to 127.0.0.1 port 8000: Connection refused
curl: (7) Failed to connect to 192.168.65.2 port 8000: Connection refused
curl: (7) Failed to connect to 172.19.0.1 port 8000: Connection refused
curl: (7) Failed to connect to 172.18.0.1 port 8000: Connection refused
curl: (7) Failed to connect to 172.17.0.1 port 8000: Connection refused

The service doesn’t need to be python3-- any native app that binds to localhost will work.

I also tried this with pinata set network nat and pinata set network hostnet– neither works.

7 Likes

Same here, see my started topic

I’m waiting for a long time to get this running.

same here. Did not work and I was disappointed no notice was given :confused:

You’re on a Mac, so, remember that your docker daemon is actually running in a virtual machine, not your actual machine. Thus, it’s not connecting to host ports for your Mac, but rather it’s connecting to host ports for that specific virtual machine.

You can get the IP of the machine it is connecting to the ports of with echo $DOCKER_HOST

2 Likes

Yes, the docker daemon is running in xhyve. I understand that.

But this is application is a native OS X implementation of docker. Hence the question… Should docker run –net=host work?

If it should work, it doesn’t work currently and should be fixed.
If it shouldn’t work, not expected to work, not going to be feasible, not on the roadmap, or whatever… it would be nice to know this, and maybe have it documented somewhere. Also, if this is the case, the docker network host probably shouldn’t even be created in the first place.

3 Likes

xhyve is still not an actual real native in-OSX implementation. It’s virtualization software. It is just the native virtualization software (thus no need to bundle vbox).

But docker is still running a linux virtual machine in the background.

Getting an actual real native container requires writing a compatibility syscall interface in the native OS that implements the Linux syscalls. (This is what Windows Services for Linux is doing.)

Yes, I understand that docker running in xhyve is not native-- it’s similar to Docker Toolbox with a VirtualBox image running docker natively.

So, for a third time… the question still remains…
Should docker run –net=host work or not?

1 Like

To explain again: docker run --net=host should work. It does work. It attaches to the ports on the host machine which is the virtual machine inside xhyve.

If you expect it to connect to your Mac’s host ports, then no. It will not do that, because it’s running on a virtual machine.

“… it’s similar to Docker Toolbox with a VirtualBox image running docker natively.” which didn’t support --net=host except insofar as using the host ports on the vbox machine, and not the OSX machine.

Why would one ever think changing virtualization engines would change that?

1 Like

Because the overall direction of the Mac Beta has been to try to make it act more like native Linux Docker. To give one specific concrete change, docker run -p 8888:8888 opens a port on the (Mac) host, not the xhyve VM, and if that was a Web-based service, I’d connect to http://localhost:8888/ and not (as in the Docker Machine setup) http://192.168.99.100:8888/.

In fact, since docker run -p opens a real-host port but docker run --net=host only uses the VM ports, there are combinations of these (I use a Consul health checker that depends on --net=host, for instance) that work on Linux but not Mac. I find it merely frustrating and not a show-stopper, but it is an actual issue.

1 Like

Yes, a -p works so well, because it’s opening a localport that is actually a redirect to an address that is NATed behind the docker bridged networking.

It is not docker running on the Linux machine that is instigating this port opening. The invoking agent on the Mac knows exactly which port needs to be redirected and how.

How could this work with --net=host? Docker in this case even the docker daemon running on the virtualized Linux machine doesn’t even actually know which port the container opened, because the container has done an “end run” around docker straight to the namespaced kernel.

So, now, considering that the docker daemon doesn’t even know what port was eventually opened by the container, how would you expect the OSX invoker to even know?

Is the behavior inconsistent? Yes, it is. Is there really anything they can do without essentially setting up a bridged NAT in the first place, and just replicating -p? No, there really isn’t.

Docker was designed with the intent that -p is the way things will work. (Otherwise, it can’t track the opened ports.)

You might find it frustrating, but it is not a show-stopper, it is in fact, something that they cannot make work without instrumenting up the open TCP socket syscall in the Linux virtual guest, AND setting up a bridged network in the first place, and even then, ok, the container opens port 0, which is “random unprivileged port”, the Linux machine opens up port 64435 on it’s virtual linux host, but a different process running on the machine’s OSX host already has port 64435 (like, say a web-browser) open. Now, the Linux machine is stuck telling the host “hey, open up port 64435 and redirect it to me” and the host saying “no can do, it’s already open for a different program”.

What then? Crash your container or return a “port already open” syscall error? Now the behavior is still different from Linux, because sometimes the OSX-housed container will barf at start up claiming “port already open” when you’re opening port 0, which is supposed to assign an unused port before opening it, and thus should never barf up “port already open” unless the machine has already exhausted all available ports.

This is a complex problem, and many of the steps in the way are better solved with using pre-allocated ports on the invoking docker command-line with -p which is kind of why they designed its common-use-case to use that method in the first place.

Also being discussed here (since April). Is it really that hard for someone to just clarify the current situation around this (is it a known issue?) and what the plans are?

2 Likes

I would expect that because I’ve been “sold” docker for mac not “docker under a different virtualization engine.” FitNesse tests that run under docker on mac in a virtual box work, but do not work “natively” because FitNesse can not connect to the exposed web interfaces running in the docker container.

Documentation on how to use --net=host under OSX would be great. What documentation I’ve found so far leads me to believe that --net=host should work on mac the way it works on Linux.

What’s the advantage of “docker for mac” if it behaves differently than “docker for Linux?”

2 Likes

-p doesn’t work like it does in Linux. For example:

%>docker run -p 8765:8765 ua-cloud
%>curl localhost:8765/start
Cloud OK

%>docker run -p 8765:8765 --net=host ua-cloud
%>curl localhost:8765/start
curl: (7) Failed to connect to localhost port 8765: Connection refused

Under linux, I can get docker containers to talk to each other and allow me to access exposed URLs. Under docker for mac, it seams I can not.

In the Dockerfile for cloud, we have

EXPOSE 8765 9090 61666

I’m not sure if that’s equivalent to -p 8765:8765 …

“Faster and more reliable: no more VirtualBox! The Docker engine is running in an Alpine Linux distribution on top of an xhyve Virtual Machine on Mac OS X or on a Hyper-V VM on Windows, and that VM is managed by the Docker application. You don’t need docker-machine to run Docker for Mac and Windows.”

I’m having difficulty finding any documentation from Docker that states that Docker for Mac is anything other than docker with a different VM…

Well, I guess since this issue isn’t going to be accepted as an issue or fixed, then Docker for make is a non-starter for me.

I assumed “Docker for mac” meant my Docker images that work out of the box in Linux would work in Mac. They don’t and when I report they don’t, I’m told “that’s not the goal”. If that’s not the goal, then it’s not a solution for me.

Thanks anyways.

I’m sorry that Docker for Mac doesn’t fit your needs. I hope in the future, that OSes can, similar to FreeBSD provide a syscall interface that is Linux compatible, allowing for docker to run actually native, instead of just through a VM.

Windows has been working towards this with Windows Subsystems for Linux, but obviously for people who need Docker “NAO!” on Windows, a VM is the only option.

Sadly, I don’t know of any projects to do something similar for OSX. :frowning:

I assumed “Docker for mac” meant my Docker images that work out of the box in Linux would work in Mac.

If you need Linux on your Mac, run VirtualBox (using Vagrant?) and run Docker inside those VMs. You should do this especially if you need to test your apps on a multi-host setup.

You can also run “Docker in Docker” in Docker for Mac, so you can run a swarm of Docker daemons which might be enough of a test environment for your multi-host apps. Within the swarm, you can use Docker networks to isolate your services to only certain user defined networks.

I’ve been using Docker for Mac since the public beta has come out, and while it is still beta, it has been a huge improvement over Docker Toolbox using VirtualBox VMs. I don’t think Docker for Mac is intended for deployment of your apps, only so you can test them on your laptop during development. For this purpose, Docker for Mac is a huge step in the right direction.

How exactly could I found this $DOCKER_HOST ?

I don’t think docker for mac set any additional environment variable.

At least I would like to have a way to access my service through vm’s ip address

2 Likes

The latest update seems to work, or what I was trying earlier didn’t. Mapping ports with -p now works flawlessly, now I can use docker for mac in the same manner as other developers do using VirtualBox and a linux distro.

This is what I had hoped it would be. Thanks.

@curtisrcooley What does mapping ports with -p have to do with the subject of this thread?