Communicate to Docker host from Docker container

2019-04-08 17:11发布

问题:

I’m experimenting with docker networking, and I can’t seem to find a way to accomplish the following:

Start a simple netcat server in the host:

nc -l -p 5555

and then communicate to this server from within a docker container, e.g.

# grab the docker network interface ip
hostip=$(ip route | awk '/docker0/ { print $NF }')
# pass in the docker network interface as a host and try a curl command
docker run --add-host=docker:"${hostip}" --rm -it hiromasaono/curl curl docker:5555

The curl request just hangs and the host netcat server does not receive a request.

If I instead start docker with --net=host option, it works:

docker run --net=host --rm -it hiromasaono/curl curl 127.0.0.1:5555

and the netcat server receives

GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 127.0.0.1:5555
Accept: */*

How can I communicate to the simple host netcat server from within the docker container without using --net=host (the default is --net=bridge)?

(fyi: I'm running docker server/client 1.11.2)

Potentailly Relevant Resources I've Studied in search of an answer:

  • Document how to connect to docker host from container (github issue)
  • How to connect to Docker host from container (github issue)
  • Allow Docker Container to Connect to a Local Postgres DB
  • Docker Container Networking Documentation

回答1:

There are a couple of things you need to look into, in order to solve this problem.

  1. Netcat must listen on all interfaces (or at least on the interface Docker clients can connect to). Not on localhost. After you run netcat -l -p 5555 if in another terminal you run netstat -a -l -n | grep 5555 you should see 0.0.0.0:5555 or *:5555. If instead you see 127.0.0.1:5555 then it won't work and you need to fix this problem first before looking into Docker.
  2. Docker must be able to ping the docker host and it must not resolve to 127.0.0.1 . Try docker run --net=host --rm -it hiromasaono/curl ping docker. If you see it's pinging 127.0.0.1 then your configuration is wrong and you need to fix this line: hostip=$(ip route | awk '/docker0/ { print $NF }') . If it's not 127.0.0.1 but the pings don't succeed then your network setup is wrong or the hostip is wrong.


回答2:

As far as I understand, based on two comments[1][2], the following unofficial hack seems to be working for me as of today (2016.10.27):

In the Dockerfile for the app which needs to connect to the Docker host, I added the following lines:

...
# netstat
RUN apt-get update && apt-get install net-tools -y
...
CMD (netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2" dockerhost"}' >> /etc/hosts) && \
        ...old CMD line...
...

This seems to make the Docker host available to me from within the container as dockerhost.


Note to future readers: see also https://github.com/docker/docker/issues/23177 — as of writing, this issue is still open, so there's a non-zero chance it may become official at some point in future and supersede any workarounds; though it may also become closed and dismissed as happened to its various predecessors.



标签: docker