moby / libnetwork

networking for containers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use .local suffix for containers on user-defined networks to avoid proxy issues.

richard-bain opened this issue · comments

When a container is attached to a user-defined bridge network, it can be reached by other containers on that same network via both <network-alias> or its <network-alias>.<network-name>.

However when using docker with a proxy you will typically need to set http/s_proxy which will interfere with this lookup:

docker create network test-network
docker run -d --network=test-network --network-alias=nginx nginx

docker run --network=test-network -e http_proxy="http://some-proxy" curlimages/curl nginx
docker run --network=test-network -e http_proxy="http://some-proxy" curlimages/curl nginx.test-network
# These both fail to resolve because request to `nginx` and `nginx.test-network` are sent to the proxy
# instead of being resolved by the built in DNS.

This can be solved per network by passing in -e no_proxy=test-network to the container, but there is not way to do this in a way that will work for all network.

For example, it is typical to provide proxy settings in the daemon config. But as the noProxy value is dynamic there is no value that will work for all networks.

Suggested Fix

Extend the container name resolution to use .local: container-name.network-name.local and container-name.local so the following daemon config will work for most container processes:

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://some-proxy:3128",
     "httpsProxy": "http://some-proxy:3128",
     "noProxy": "local"
   }
 }
}

All of the following would be equivalent and should now work

docker run curlimages/curl nginx.local  # if set in daemon config
docker run -e no_proxy=local curlimages/curl nginx.local
docker run -e no_proxy=local curlimages/curl nginx.test-network.local

There would be a possibility of collision with other services providing .local addresses on the host's network but the internal DNS should resolve locally first.

This shouldn't be considered a problem as the following works by resolving internally first (assume no proxy in use):

docker create network test-network
docker run -d --network=test-network --network-alias="google.com" nginx

docker run curlimages/curl google.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

According to RFC 6762: Multicast DNS : “Any DNS query for a name ending with ".local." MUST be sent to the mDNS IPv4 link-local multicast address 224.0.0.251 (or its IPv6 equivalent FF02::FB).”. Also in there: “Using ".local" as a private top-level domain conflicts with Multicast DNS and may cause problems for users. … we recommend against using ".local" as a private Unicast DNS top-level domain. We do not recommend use of unregistered top-level domains at all …“