DNS Resolution in Docker Containers

Networks in Docker are a powerful and only recently I learned about the embedded DNS server. So if you maintain containers for which DNS resolution is important but which might not have the most reliable connection to the common DNS servers (e.g. Google’s 8.8.8.8 and CloudFlare’s 1.1.1.1) this might be a feature to look into.

In my situation a Openresty / nginx container runs in multiple regions (EU, US, China) and its main purpose is to distribute requests to other upstream services. To do so it’s necessary to set the resolver directive and tell nginx which DNS server to use. First decision: 8.8.8.8 and 1.1.1.1. This worked fine until the container in China started to get timeouts while attempting to connect to those DNS servers. Essentially bringing down the whole service.

To get around this I toyed with different approaches:

  • Switch from hostnames to IP addresses for routing — didn’t work directly because of SSL certificates.
  • Adding a local DNS service in the container (dnsmasq) — didn’t really want to add any more complexity to the container itself.
  • Adding a separate container to handle DNS resolution.

Only then I stumbled across the embedded DNS server. If the container runs in a custom network, it’s always available at 127.0.0.11 and will adhere to the host’s DNS resolution configuration. While all other host machines already had a robust enough DNS config, I manually added the most crucial IP addresses to the /ets/hosts file on the Chinese host. Bingo, no more DNS issues ever since.

I guess the lesson here for me is to dig a bit deeper in the tools already at hand before going down the rabbithole and constructing overly complex systems.