User-Defined Networks and Embedded DNS Resolution in Docker
Understanding embedded DNS servers, service discovery by container name, and custom bridge isolation.
Part 14 in Series — Catch up on the previous article: Port Publishing Under the Hood: iptables DNAT, Userland Proxies, and Host Routing (Part 13) before diving into this post.
A backend engineering team deploys a web application consisting of a Node.js API service and a PostgreSQL database on a single server using default Docker flags:
docker run -d --name db-server postgres:15
docker run -d --name api-service my-node-api
In the API configuration file, the developer hardcodes the database connection string using the container’s IP address: postgres://172.17.0.2:5432/appdb.
During a routine host kernel update, the server reboots.
When the Docker daemon starts up, api-service initializes faster than db-server. The daemon assigns 172.17.0.2 to api-service and 172.17.0.3 to db-server.
The API server crashes continuously with ECONNREFUSED because container IP addresses are ephemeral and non-deterministic across restarts.
When the team creates a User-Defined Bridge Network:
docker network create app-net
docker run -d --name db-server --network app-net postgres:15
docker run -d --name api-service --network app-net my-node-api
The connection string becomes postgres://db-server:5432/appdb, and the service connects reliably across restarts.
How does Docker resolve container names like db-server into dynamic IP addresses without external DNS servers?
1. Why Default Bridge Networks Lack Automatic DNS
On the default bridge network (docker0), automatic DNS resolution by container name is disabled.
If container_A attempts to resolve container_B by name on the default bridge, the query fails:
# Inside container_A on default bridge:
ping container_B
ping: bad address 'container_B'
Legacy Docker installations relied on --link container_B, which injected static IP entries into the container’s /etc/hosts file at startup. However, --link is deprecated because /etc/hosts cannot update dynamically when target containers restart with new IP addresses.
2. User-Defined Bridge Networks
When you execute docker network create app-net, Docker creates a brand new, isolated virtual bridge interface (e.g., br-a1b2c3d4e5f6) in the host network namespace.
HOST NETWORK NAMESPACE
+-------------------------------------------------------------------------+
| DEFAULT BRIDGE (docker0) USER-DEFINED BRIDGE (br-a1b2c3d4) |
| Subnet: 172.17.0.0/16 Subnet: 172.18.0.0/16 |
| No Container DNS Resolution Embedded DNS Enabled! |
+-------------------------------------------------------------------------+
| |
v v
[ Legacy Containers ] [ Service: api-service ] <---> [ Service: db-server ]
(Resolves "db-server" -> 172.18.0.3 via DNS!)
Key Advantages of User-Defined Networks:
- Automatic Service Discovery: Containers resolve each other automatically using container names or network aliases (
http://db-server:5432). - Network Isolation: Containers attached to
app-netcannot communicate with containers ondocker0orother-net, preventing unauthorized cross-service snooping. - Dynamic Attachment: You can connect or disconnect running containers from networks on the fly using
docker network connect.
3. The Embedded DNS Server Engine (127.0.0.11)
How does Docker perform DNS lookups inside containers attached to user-defined networks?
When a container joins a user-defined network, Docker modifies the container’s /etc/resolv.conf file to point to a special loopback address:
# Inside container /etc/resolv.conf:
nameserver 127.0.0.11
options ndots:0
127.0.0.11 is the Docker Embedded DNS Server.
[ Application Code in Container ]
|
| Sends DNS Query: "db-server"
v
[ UDP 127.0.0.11:53 (Embedded DNS Proxy inside Container NetNS) ]
|
+--- Is query a container name in local network?
| |
| +---> YES: Resolves IP from Docker Daemon Internal Table (172.18.0.3)
| |
| +---> NO: Forwards DNS query to Host's Upstream DNS (8.8.8.8)
Step-by-Step DNS Resolution Trace:
- Application code executes a database client connection request to host
db-server. - The OS C library issues a UDP DNS query for
db-serveron port 53. - The query is intercepted by the local Embedded DNS Server listening on
127.0.0.11:53. - The DNS engine checks Docker’s internal container name resolution table:
- If
db-servermatches an active container attached to the same network, it returns172.18.0.3instantly. - If the query is an external internet domain (e.g.,
api.stripe.com), it forwards the request to the upstream DNS nameservers configured on the host host machine.
- If
Default Bridge vs User-Defined Bridge Comparison
| Feature / Behavior | Default bridge (docker0) | User-Defined Network (docker network create) |
|---|---|---|
| DNS Resolution by Name | ❌ Disabled (Fails unless using deprecated --link) | ✅ Enabled automatically via 127.0.0.11 |
| Network Subnet | Shared 172.17.0.0/16 | Dedicated isolated subnet (e.g., 172.18.0.0/16) |
| Cross-Container Isolation | Low (All default containers share docker0) | High (Strict network boundary isolation) |
| Hot-Plugging Interfaces | ❌ Requires container recreation | ✅ Supported (docker network connect/disconnect) |
| Custom IP Address Rules | Managed automatically | Supports explicit --ip static assignment |
Summary & Next Steps
User-Defined Networks provide reliable service discovery and security isolation for containerized architectures:
- Ephemeral Container IPs make hardcoding IP addresses in application code brittle and prone to outages.
- User-Defined Networks (
docker network create) isolate microservice subnets and enable automatic container name resolution. - The Embedded DNS Server (
127.0.0.11) intercepts UDP port 53 queries inside container network namespaces, resolving container names to dynamic IPs.
In the next article, we transition to Module 5 and explore Storage Drivers Deep Dive: OverlayFS Layering and Copy-On-Write (CoW) Performance Overhead.
References & Further Reading
- QEMU Project. QEMU User Space Emulation (
qemu-user-static). QEMU Docs. - Open Container Initiative. OCI Image Format Specification — Image Index and Manifest Lists. OCI Standard.
- Docker Inc. Leverage Multi-CPU Architecture Images with
docker buildx. Docker Docs.
Part 15: Storage Drivers Deep Dive: OverlayFS Layering and Copy-On-Write (CoW) Performance Overhead
Continue to Part 15 →