[Home] Karl N. Redman:

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 and docker-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 for dnsmasq 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

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

That’s It!!