Resolve docker hostnames from host with DNS Proxy Server
This article is a continuation of my previous HowTo: Dnsmasq + NetworkManager + Private Network Setup. With just a few configuration changes we will add the capability to interact with docker containers by their respective hostnames. Even though the dns-proxy-server project affords us this new functionality I recommend that dns-proxy-server
only be used for development purposes.
While it’s awesome to have the ability to reference individual containers by hostname during development efforts the concept doesn’t scale well. In addition the dns-proxy-server (DPS) suffers from some performance issues that should be taken into consideration before using it as a docker service.
Additional Features added to the previous HowTo:
- Reference FQDN-like container hostnames from the docker host
- Reference FQDN-like container hostnames from other containers
- Reference FQDN-like container hostnames via the browser without port specifications
- Consistent behavior whether your host system is online or offline
- Works with both
docker run
anddocker-compose
containers in a mixed environment - NetworkManager functionality remains viable and effective
- Set-it-and-forget-it configuration
Tested systems:
- MX Linux v18.1
- Ubuntu v18.10
- Debian v9.8
Disclaimer:
- I strongly urge that you initially test this procedure with a virtual machine. I am not responsible if you mess up your system, data, etc.. This information is provided as is -use at your own risk.
- This article assumes that you have configured your target system as outlined in the article Dnsmasq + NetworkManager + Private Network Setup.
- Note: The use of
all-servers
setting fordnsmasq
may produce undesirable behavior or could be considered a security risk -depending on your standards. See: Man page of DNSMASQ for more information if you are concerned.
How To:
Allow for async nameserver lookups
- directive
all-servers
to/etc/dnsmasq.conf
also sanity check the settings
all-servers # async call to all nameservers bind-dynamic # could use bind-interfaces instead listen-address=127.0.0.1 listen-address=10.127.127.1 address=/private.home/10.127.127.1 domain=private.home,10.127.127.0/24 domain=docker.devnet,172.17.0.0/24
Restart dnsmasq
sudo service dnsmasq restart
Add DPS configuration to NetworkManager
DPS will always bind to address
172.17.0.2
nmcli con modify 'Wired connection 1' ipv4.dns 172.17.0.2 nmcli con modify 'Wired connection 1 offline' ipv4.dns 172.17.0.2 # nmcli con up 'Wired connection 1'
Create DPS config file
Create directories and file
sudo mkdir -p /opt/dns-proxy-server/conf sudo touch /opt/dns-proxy-server/conf/config.json
reference for options: running dns-proxy-server
- fallback dns: 8.8.8.8
- become a secondary dns server
- set log level to: WARNING
- set logfile to
/opt/dns-proxy-server/dps.log
- allow command line ping for container names
add DPS settings to the config file
{ "remoteDnsServers": [ ["8.8.8.8"] ], "envs": [ { "name": "" } ], "activeEnv": "", "lastId": 0, "webServerPort": 0, "dnsServerPort": 0, "defaultDns": false, "logLevel": "WARNING", "logFile": "/opt/dns-proxy-server/dps.log", "registerContainerNames": true }
Obtain and build a docker image for testing
git clone https://github.com/karlredman/lighttpd-docker.git
#
cd lighttpd-docker
#
sudo docker build -t lighttpd .
Start DPS
docker run --rm --hostname dns.mageddo --name dns-proxy-server -p 5380:5380 -v /opt/dns-proxy-server/conf:/app/conf -v /var/run/docker.sock:/var/run/docker.sock -v /etc/resolv.conf:/etc/resolv.conf defreitas/dns-proxy-server
Start example containers
# start FQDN hostname docker container 1
sudo docker run -d -p 8081:80 -p 4441:443 --rm -t --name docker-container-1-name -h docker-container-1.docker.devnet --net docker.devnet lighttpd
# start container 2
sudo docker run -d -p 8082:80 -p 4442:443 --rm -t --name docker-container-2-name -h docker-container-2.docker.devnet --net docker.devnet lighttpd
# start container 3
sudo docker run -d -p 8083:80 -p 4443:443 --rm -t --name docker-container-3-name -h docker-container-3.docker.devnet --net docker.devnet lighttpd
Test pings
note pings in offline mode will be slow due to round robin dns resolution
ping -c 4 localhost ping -c 4 mxtest ping -c 4 mxacer ping -c 4 dns.mageddo ping -c 4 docker-container-1.docker.devnet ping -c 4 docker-container-3.docker.devnet ping -c 4 docker-container-2-name # fails offline mode sudo docker exec -ti docker-container-1-name sh -c "ping -c 4 host.docker" sudo docker exec -ti docker-container-1-name sh -c "ping -c 4 a-wildcard.private.home" sudo docker exec -ti docker-container-2-name sh -c "ping -c 4 docker-container-3-name" sudo docker exec -ti docker-container-3-name sh -c "ping -c 4 docker-container-1.docker.devnet"
View DPS web page (doesn’t seem to work for me)
http://localhost:5380
http://dns.mageddo:5380
Test addresses via browser
works
does not work
Test docker-compose instance
start the container
cd lighttpd-docker sudo docker-compose up -d
test ping to the compose container
ping -c 4 docker-container-4.docker.devnet sudo docker exec -ti docker-container-4-name sh -c "ping -c 4 a-wildcard.private.home" sudo docker exec -ti docker-container-4-name sh -c "ping -c 4 docker-container-3-name" sudo docker exec -ti docker-container-4-name sh -c "ping -c 4 docker-container-1.docker.devnet" # sudo docker exec -ti docker-container-1-name sh -c "ping -c 4 docker-container-4.docker.devnet"
test browser access to the container