The Docker container accesses the host network

  • 2020-12-16 06:14:10
  • OfStack

Recently, I have deployed a set of systems using nginx as the reverse proxy, in which nginx runs in docker mode:


$ docker run -d --name nginx $PWD:/etc/nginx -p 80:80 -p 443:443 nginx:1.15

The API service that requires the proxy runs on port 1234 of the host. The nginx.conf configuration is as follows:


server {
 ...

 location /api {
  proxy_pass http://localhost:1234
 }
 ...
}

When accessing the result, it is found that 502 Bad Gateway error is always reported. The error log shows that you cannot connect to upstream.

On second thought, there seems to be something wrong with localhost as in ES18en. conf. Since nginx is running in the docker container, this localhost is the localhost of the container, not the localhost of the host.

This brings us to the question this article addresses: How do you access the host's network from the container? There are several ways to search the Internet:

Use the host IP

When installing Docker, a virtual gateway docker0 is installed on the host, and we can use the host's IP address on docker0 instead of localhost.

First, query the host IP address using the following command:


$ ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  link/ether 02:42:d5:4c:f2:1e brd ff:ff:ff:ff:ff:ff
  inet 172.17.0.1/16 scope global docker0
    valid_lft forever preferred_lft forever
  inet6 fe80::42:d5ff:fe4c:f21e/64 scope link
    valid_lft forever preferred_lft forever

It can be found that the host IP is 172.17.0.1, so change proxy_pass http://localhost http://172.17.0.1:1234 to proxy_pass http://172.17.0.1:1234 to solve the error 502 Bad Gateway.

However, the host IP is different on different systems. For example, the host IP is 172.17.0.1 under Linux and 192.168.65.1 under macOS, and this IP can be changed. So using IP to configure ES62en.conf is not common across environments.

Use host network

When the Docker container runs, host, bridge and none are available for configuration. The default is bridge, which Bridges the network and connects to the host in bridging mode. host is the host network, that is, the network shared with the host machine; none means that without a network, the container will not be able to network.

When a container is using the host network, the container shares the network with the host so that the host network can be accessed from within the container, then the container's localhost is the host's localhost.

In docker, use --network host to configure the host network for containers:


$ docker run -d --name nginx --network host nginx

In the above command, it is not necessary to map ports using -p 80:80-ES92en 443:443 as in the previous one, because the network itself is shared with the host, and the exposed port in the container is equivalent to the exposed port of the host.

Using host network does not need to modify ES96en. conf, localhost can still be used, so the generality is better than the above method. However, host network is not as isolated as bridge network, so host network is not as secure as bridge.

conclusion

In this paper, two methods, IP and host, are proposed to access the host network from the container. The two methods have their own advantages and disadvantages. The host IP has better isolation but less generality. Using host network has good universality, but it brings the risk of exposing the host network.


Related articles: