Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query docker embedded dns from host

Does anybody know a way to query the embedded dns server that the docker daemon uses. I'm experimenting with packetbeats and it would be useful if I could replace docker ip addresses with the container names.

The only way I can currently think of to achieve this is to create a dns server in a container that can be configured as the dns server for the host to ensure container names can be resolved by the host. Hope that makes sense?

Is this the only way or are there other options ?

The containers I'm trying to query were created using docker-compose.

like image 333
K2J Avatar asked Sep 27 '16 16:09

K2J


3 Answers

Consul

I like using Hashicorp's Consul for this. It can run as an installed client or container, and provides a DNS Interface that you can query external of Docker. It also has features like service discovery & monitoring, and is open source.

https://www.consul.io/docs/agent/dns.html

One of the primary query interfaces for Consul is DNS. The DNS interface allows applications to make use of service discovery without any high-touch integration with Consul.

For example, instead of making HTTP API requests to Consul, a host can use the DNS server directly via name lookups like "redis.service.east-aws.consul". This query automatically translates to a lookup of nodes that provide the redis service, are located in the "east-aws" datacenter, and have no failing health checks. It's that simple!

It might be overkill for what you're looking for, but should do the job.

DNSMasq

A simpler alternative might be DNSMasq. I'm not as familiar with it, but for a really small scale setting it would allow your host to be DNS aware of running containers.

http://www.thekelleys.org.uk/dnsmasq/doc.html

https://hub.docker.com/r/andyshinn/dnsmasq/

like image 168
DevOps Dan Avatar answered Oct 16 '22 11:10

DevOps Dan


You can use socat to expose the Docker network's resolver at 127.0.0.11:53 like cirocosta/expose-edns image does, which is essentially:

socat UDP4-RECVFROM:53,fork,bind="0.0.0.0" UDP4-SENDTO:127.0.0.11:53

Then use it like:

host container_name_to_resolve `docker inspect --format \
  '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' socat_container_name`

Also note that the socat container must be in the same Docker network as target containers.

Update

To overcome the limitation of the same Docker network, phensley/docker-dns can be used (which uses Docker API). On an OS with NetworkManager and Dnsmasq enabled (otherwise can be enabled like described in this answer) you can run:

docker run -d --name docker-dns -v /var/run/docker.sock:/docker.sock \
  phensley/docker-dns --domain docker --no-recursion     

Then inspect its IP address with:

docker inspect --format \
   '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-dns

And put it into /etc/NetworkManager/dnsmasq.d/docker.conf like:

server=/docker/1.2.3.4

After systemctl restart NetworkManager you should be able to address your Docker containers from host like ping CONTAINER_NAME.docker which is quite handy for dockerised development environments.

like image 4
saaj Avatar answered Oct 16 '22 11:10

saaj


Another way would be to use docker-dns. It's a docker container that exposes a dns server that resolves the docker containers.

Running it is as simple as

docker run -d --name dns -v /var/run/docker.sock:/docker.sock phensley/docker-dns
like image 2
Veda Avatar answered Oct 16 '22 10:10

Veda