loading...

Resolve docker hostnames from host with DNS Proxy Server

karlredman profile image Karl N. Redman Originally published at github.com ・4 min read
  • Last updated: 3/Mar/2019

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 [your host name]
ping -c 4 [some system on your network]

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"

That's It!!

Discussion

pic
Editor guide