DNS servers in docker container
Some interesting understandings after playing with docker container DNS setting.
Let start with a simple docker container: docker run --rm --name container1 -it busybox /bin/sh
.
In this container1 terminal, run cat /etc/resolv.conf
.
/ # cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 192.168.10.1
In the host machine, run cat /etc/resolv.conf
.
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "systemd-resolve --status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 127.0.0.53
options edns0
Problem 1: the DNS IP in the host machine is 127.0.0.53 while in the container1
docker container, it is 192.168.10.1
.
This is due to systemd-resolve
service, a DNS proxy service, which caches DNS data to speed up DNS reverse lookup in the host machine.
To reveal information about this service, use systemd-resolve
command: sudo systemd-resolve --status
. Result:
Global
DNSSEC NTA: 10.in-addr.arpa
16.172.in-addr.arpa
168.192.in-addr.arpa
17.172.in-addr.arpa
18.172.in-addr.arpa
19.172.in-addr.arpa
20.172.in-addr.arpa
21.172.in-addr.arpa
22.172.in-addr.arpa
23.172.in-addr.arpa
24.172.in-addr.arpa
25.172.in-addr.arpa
26.172.in-addr.arpa
27.172.in-addr.arpa
28.172.in-addr.arpa
29.172.in-addr.arpa
30.172.in-addr.arpa
31.172.in-addr.arpa
corp
d.f.ip6.arpa
home
internal
intranet
lan
local
private
test
Link 143 (vetha8e6e15)
Current Scopes: none
LLMNR setting: yes
MulticastDNS setting: no
DNSSEC setting: no
DNSSEC supported: no
Link 97 (br-8751bfcd84e3)
Current Scopes: none
LLMNR setting: yes
MulticastDNS setting: no
DNSSEC setting: no
DNSSEC supported: no
Link 96 (veth4b35504)
Current Scopes: none
LLMNR setting: yes
MulticastDNS setting: no
DNSSEC setting: no
DNSSEC supported: no
Link 94 (vethbedcec0)
Current Scopes: none
Not found 192.168.10.1
entry from the result. Try more with sudo /run/systemd/resolve/resolv.conf
. The result sounds very interesting. Run sudo cat /run/systemd/resolve/resolv.conf
.
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 192.168.10.1
Now 192.168.10.1
is exactly what we want. Docker finds this IP address and assigns it to the docker machine while creating.
How does the dynamic network connect/disconnect work?
Now, please keep the container1
container run before continue.
Create a new network named my-net
with docker network create my-net
.
Connect container1
with my-net
via docker network connect my-net container1
.
Switch back to the container1
terminal, and re-run cat /etc/resolv.conf
. The result changes:
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 192.168.10.1
/ # cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
The reason is simple and mentioned carefully in docker official docs.
Note: The DNS server is always at 127.0.0.11.
Docker maintains an embedded DNS server when a user-defined network is in use.
Test the embedded DNS server
Start another docker container with docker run --rm -it --network my-net ubuntu /bin/bash
.
In this ubuntu
image container terminal, run apt update && apt install -yq dnsutils whois
.
Now, in this ubuntu
image container terminal, run the following commands to test the embedded DNS server.
root@0b0b0c18adaf:/# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
root@0b0b0c18adaf:/# dig @127.0.0.11 container1
; <<>> DiG 9.11.3-1ubuntu1.10-Ubuntu <<>> @127.0.0.11 container1
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 8179
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;container1. IN A
;; AUTHORITY SECTION:
. 10800 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019111800 1800 900 604800 86400
;; Query time: 54 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Nov 18 09:55:05 UTC 2019
;; MSG SIZE rcvd: 114
root@0b0b0c18adaf:/# dig container1
; <<>> DiG 9.11.3-1ubuntu1.10-Ubuntu <<>> container1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 62239
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;container1. IN A
;; AUTHORITY SECTION:
. 10774 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019111800 1800 900 604800 86400
;; Query time: 43 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Nov 18 09:55:31 UTC 2019
;; MSG SIZE rcvd: 114
root@0b0b0c18adaf:/# whois 127.0.0.11
getaddrinfo(whois.arin.net): Servname not supported for ai_socktype
Happy coding!