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 …“