44

How Docker container DNS works

 5 years ago
source link: https://www.tuicool.com/articles/hit/Uv6Vjm3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Learn about Docker DNS. How docker container DNS works? How to change nameserver in Docker container to use external DNS?

How-Docker-container-DNS-works.pngDocker DNS

Docker container has inbuilt DNS which automatically resolves IP to container names in user-defined networks.  But what if you want to use external DNS into the container for some project need. Or how to use external DNS in all the containers run on my host? In this article, we will walk you through below points :

  1. Docker native DNS
  2. Nameservers in Docker
  3. How to use external DNS in the container while starting it
  4. How to use external DNS in all the containers on docker host

Docker native DNS

In user-defineddocker network DNS resolution to container names happens automatically. You don’t have to do anything if your containers are using your defined docker network they can find each other withhostname automatically.

We have 2nginx containers running using my newly created docker network named kerneltalks. Both nginx containers are installed with ping utility.

 
$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
1b1bb99559ac        nginx               "nginx -g 'daemon of…"   27 minutes ago      Up 27 minutes       80/tcp              nginx2
239c662d3945        nginx               "nginx -g 'daemon of…"   27 minutes ago      Up 27 minutes       80/tcp              nginx1
 
$ docker network inspect kerneltalks
"Containers": {
"1b1bb99559ac21e29ae671c23d46f2338336203c96874ac592431f60a2e6a5de": {
"Name": "nginx2",
"EndpointID": "4141f56fe878275e322b9283476508d1135e813d12ea2b7d87a5c3d0db527f79",
"MacAddress": "02:42:ac:13:00:05",
"IPv4Address": "172.19.0.5/16",
"IPv6Address": ""
},
"239c662d3945031413e4c69b99e3ddde57832004bd6193bdbc30bd5e6ca6f4e2": {
"Name": "nginx1",
"EndpointID": "376da79e6746cc80d178f4363085e521a9d45c65df08248b77c1bc744b495ae4",
"MacAddress": "02:42:ac:13:00:04",
"IPv4Address": "172.19.0.4/16",
"IPv6Address": ""
},
 

And they can ping each other without any extra DNS efforts. Since user-defined networks have inbuilt DNS which resolves IP addresses from container names.

 
$ docker exec -it nginx1 ping nginx2
PING nginx2 (172.19.0.5) 56(84) bytes of data.
64 bytes from nginx2.kerneltalks (172.19.0.5): icmp_seq=1 ttl=64 time=0.151 ms
64 bytes from nginx2.kerneltalks (172.19.0.5): icmp_seq=2 ttl=64 time=0.053 ms
 
$ docker exec -it nginx2 ping nginx1
PING nginx1 (172.19.0.4) 56(84) bytes of data.
64 bytes from nginx1.kerneltalks (172.19.0.4): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from nginx1.kerneltalks (172.19.0.4): icmp_seq=2 ttl=64 time=0.054 ms
 

But in default docker bridge network (which installs with docker daemon) automatic DNS resolution is disabled to maintain container isolation. You can add container inter-comm just by using --link option while running container (when on default bridge network)

--link is a legacy feature and may be removed in upcoming features. So it is always advisable to use user customized networks rather than using default docker network.

DNS nameservers in Docker

Docker is coded in a smart way. When you run new container on the docker host without any DNS related option in command, it simply copies host’s /etc/resolv.conf into container. While copying it filter’s out all localhost IP addresses from the file. That’s pretty obvious since that wont be reachable from container network so no point in keeping them. During this filtering, if no nameserver left to add in container’s /etc/resolv.conf file then Docker daemon smartly adds Google’s public nameservers 8.8.8.8 and 8.8.4.4 in to file and use it within the container.

Also, host and container /etc/resolv.conf always be in sync. Docker daemon takes help from file change notifier and makes necessary changes in container’s resolve file when there are changes made in host’s file! The only catch is these changes will be done only if the container is not running. So to pick up changes you need to stop and start container again. All stopped containers will be updated immediately after host’s file changes.

How to use external DNS in container while starting it

If you want to use external DNS in the container other than docker native or other than what’s in host’s resolv.conf file, then you need to use --dns switch in docker container run command.

 
$ docker container run -d --dns 10.2.12.2 --name nginx5 nginx
fbe29f22bd5f78213163532f2529c5cd98bc04573a626d0e864e670f96c5dc7a
 
$ docker exec -it nginx5 cat /etc/resolv.conf
search 51ur3jppi0eupdptvsj42kdvgc.bx.internal.cloudapp.net
nameserver 10.2.12.2
options ndots:0
 

In above example we chose to have nameserver 10.2.12.2 in container we run. And you can see /etc/resolv.conf inside container saves this new nameserver in it. Make a note that whenever you are using --dns switch it will wipe out all existing nameserver entries within the container and keeps only the one you supply.

This is a way if you want to use custom DNS in a single container. But what if you want to use this custom DNS to all containers which will run on your docker host then you need to define it in the config file. We are going to see this in next point.

How to use external DNS in all the containers on docker host

You need to define the external DNS IP in docker daemon configuration file /etc/docker/daemon.json as below –

 
{
    "dns": ["10.2.12.2", "3.4.5.6"]
}
 

Once changes saved in file you need to restart docker daemon to pick up these new changes.

 
root@kerneltalks # systemctl docker restart
 

and its done! Now any container you run fresh on your docker host will have these two DNS nameservers by default in it.

 
$ docker container run -d --name nginx7 nginx
200d024ac8930c5bfe59fdbc90a1d4d0e8cd6d865f82096c985e23f1e022d548
 
$ docker exec -it nginx7 cat /etc/resolv.conf
search 51ur3jppi0eupdptvsj42kdvgc.bx.internal.cloudapp.net
options ndots:0
 
nameserver 10.2.12.2
nameserver 3.4.5.6
 

If you have any queries/feedback/corrections, let us know in comment box below.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK