Docker Networking
Container DNS and Service Discovery in Docker
How container name resolution works out-of-the-box.
Interview: Crucial for understanding how microservices wire together, how DNS queries route through the host, and how Docker manages internal resolution layers.
Introduction
Hardcoding IP addresses in microservices configurations breaks system elasticity. When a container crashes, the orchestrator replaces it, assigning a new IP address.
Docker handles this challenge using an **embedded DNS server** that runs locally inside every container namespace. This server dynamically tracks container lifecycles, resolving hostnames to dynamic container IPs.
Why It Matters
Understanding Docker's embedded DNS resolution mechanism is key to troubleshooting service lookup timeouts, routing custom external domain names, and preventing DNS lookup loops.
The Embedded DNS Server (127.0.0.11)
When a container starts on a user-defined network, Docker intercepts standard DNS configuration:
1. **DNS Redirection:** Docker configures the container's internal /etc/resolv.conf file to point exclusively to nameserver 127.0.0.11.
2. **The Resolver Hook:** 127.0.0.11 is a virtual loopback IP managed by the Docker engine daemon. Any DNS query sent by the application is intercepted by the daemon's DNS resolver.
3. **Internal vs External Lookup:**
• If the query matches a container name or service alias on the same network, the resolver returns the local container IP immediately.
• If the query is an external address (e.g., google.com), the resolver forwards the query to the host's configured upstream DNS servers (read from host's resolv.conf).
Network Aliasing
You can assign custom DNS aliases to containers, allowing them to respond to multiple hostnames. This is useful for migrating legacy services or running round-robin load balancing:
docker run --network my-net --network-alias api-service ...
Practical Example
Let's start a container and inspect its local resolver configuration:
What just happened? We verified that Docker overrides the standard nameserver configuration inside the container namespace, routing all lookups to 127.0.0.11 for dynamic resolution.
Quick Quiz
Q1: What IP address represents the Docker embedded DNS server inside container namespaces?
A) 127.0.0.1
B) 8.8.8.8
C) 127.0.0.11
D) 10.0.0.1
Answer: C — 127.0.0.11 is the loopback IP set aside by Docker daemon to capture namespace DNS queries.
Scenario-Based Challenge
Production Scenario:
Your company runs a containerized service that needs to query an external, legacy corporate DNS database server located at 10.20.30.40. By default, the container resolves public domains but cannot locate internal corporate domains. How do you resolve this without editing host files?
You can specify custom DNS forwarders for individual containers using the --dns option:
docker run --dns 10.20.30.40 --dns 8.8.8.8 my-app
This instructs the Docker embedded resolver to route queries that fail internal namespace checks to 10.20.30.40 first, falling back to Google's public DNS (8.8.8.8) for standard internet queries.
Interview Questions
1. How does Docker DNS handle round-robin load balancing?
If you start multiple containers with the same network alias (e.g., three containers named api-web), the DNS server returns the list of all three container IPs. The resolver randomizes the return order on each lookup, creating basic round-robin DNS load balancing.
2. What is the ndots option inside container resolv.conf?
The ndots option controls search domains behavior. By default, Docker sets options ndots:0 to prevent the container resolver from appending search suffixes to absolute external lookups, accelerating public name lookups.
Production Considerations
Be careful with DNS cache settings inside your applications. Many runtime engines (like Java Virtual Machines by default) cache DNS lookups indefinitely. In highly elastic container environments where containers scale up and down, this caching can cause applications to attempt connecting to obsolete container IPs, triggering network connection errors. Configure JVM caching limits: networkaddress.cache.ttl=10.