Giter Site home page Giter Site logo

devdns's Introduction

devdns

Make docker containers discoverable via DNS for development environments, like when running a bunch of containers on your laptop. Useful for container to container communication, or just an easy way of reaching containers from the host machine.

Image Size Docker Pulls Lint

Running

docker run -d --name devdns -p 53:53/udp \
      -v /var/run/docker.sock:/var/run/docker.sock:ro ruudud/devdns

devdns requires access to the Docker socket to be able to query for container names and IP addresses, in addition to listen to start/stop events.

Binding port 53 on the host machine is optional, but will make it easier when configuring local resolving.

The DNS server running in devdns is set to proxy requests for unknown hosts to the configured fallback DNS (default Google's DNS server 8.8.8.8). It also adds a wildcard record (normally *.test, see DNS_DOMAIN below) pointing back at the host machine (bridge IP in Linux), to facilitate communication when running a combination of services "inside" and "outside" of Docker.

Using

Container ↔ Container

When running other containers, specify the devdns container IP as the DNS to use:

$ docker run -d --name devdns -p 53:53/udp \
  -v /var/run/docker.sock:/var/run/docker.sock:ro ruudud/devdns
$ docker run -d --name redis redis:alpine
$ docker run -it --rm \
  --dns=`docker inspect -f "{{ range.NetworkSettings.Networks }}{{ .IPAddress }}{{ end }}" devdns | head -n1` alpine \
  ping redis.test

Please note that the --dns flag will prepend the given DNS server to the Docker default, so lookups for external addresses will still work.

Docker Daemon Configuration

If you want devdns to be added by default to all new containers, you need to add some custom Docker daemon options as per the dockerd reference.

The exact process to set these options varies by the way you launch the Docker daemon and/or the underlying OS:

  • systemd (Ubuntu, Debian, RHEL 7, CentOS 7, Fedora, Archlinux) — sudo systemctl edit docker.service, change the ExecStart line
  • Ubuntu 12.04 — set DOCKER_OPTS in /etc/default/docker
  • OS/X — select Preferences -> Daemon -> Advanced

The extra flags you'll have to add are

--dns 172.17.0.1 --dns-search test

Replace test with whatever you set as config for DNS_DOMAIN.

172.17.0.1 is the default IP of the Docker bridge, and port 53 on this host should be reachable from within all started containers given that you've included -p 53:53/udp when starting the devdns container.

Note: There are some caveats with Docker and how it manages a container's /etc/resolv.conf file. Unless you do something exotic, like parsing this file, you should be fine. See Docker DNS docs for more information.

Host Machine → Containers

You will need to add some configuration to your OS DNS resolving mechanism to make it query devdns.

NOTE: This is only practical if you added -p 53:53/udp when starting devdns.

Linux

Nowadays, direct edits of /etc/resolv.conf will often be removed at reboot. Thus, the best place to add extra resolvers in Linux, is to use your network configurator. YMMV. This means NetworkManager (see section below), WICD, or manually using /etc/network/interfaces:

auto p3p1
iface p3p1 inet dhcp
dns-search test
dns-nameservers 127.0.0.1
Managed resolv.conf

Another solution is mounting the host machine's /etc/resolv.conf at /mnt/resolv.conf and have devdns automatically add configuration on startup:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock:ro \
      -v /etc/resolv.conf:/mnt/resolv.conf \
      ruudud/devdns

Example config prepended to /etc/resolv.conf:

nameserver 192.168.16.2 # added by devdns

The configuration will be automatically removed when container is stopped or killed.

⚠️ It's common that /etc/resolv.conf becomes overwritten as many operating systems now manage the creation of that file, and in some cases not even rely on it at all.

OSX

Create a file /etc/resolver/test containing

nameserver 127.0.0.1

In OSX and Docker for Mac, port binding should work directly on the host machine. Please note that the name of the file created in /etc/resolver has to match the value of the DNS_DOMAIN setting (default "test").

Configuration

  • DNS_DOMAIN: set the local domain used. (default: test)
  • FALLBACK_DNS: set the DNS used for unknown hosts. (default: 8.8.8.8)
  • HOSTMACHINE_IP: IP address of non-matching queries (default: 172.17.0.1)
  • EXTRA_HOSTS: list of extra records to create, space-separated string of host=ip pairs. (default: '')
  • NAMING: set to "full" to convert _ to - (default: up to first _ of container name)
  • NETWORK: set the network to use. Set to "auto" to automatically use the first network interface (e.g. when using docker-compose) (default: bridge)

Example:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock \
  -e DNS_DOMAIN=docker \
  -e HOSTMACHINE_IP=192.168.1.1 \
  -e NAMING=full \
  -e NETWORK=mynetwork \
  -e EXTRA_HOSTS="dockerhost=172.17.0.1 doubleclick.net=127.0.0.1" \
  ruudud/devdns

Caveats

Container name to DNS record conversion

RFC 1123 states that _ are not allowed in DNS records, but Docker allows it in container names. devdns ignores _ and whatever follows, allowing multiple simultaneous containers with matching names to run at the same time.

The DNS will resolve to the lastly added container, and try to re-toggle the previous matching container when stopping the currently active one.

Example:

# (devdns already running)
$ docker run -d --name redis_local-V1 redis
$ dig redis.test     # resolves to the IP of redis_local-V1

$ docker run -d --name redis_test redis
$ dig redis.test     # resolves to the IP of redis_test

$ docker stop redis_test
$ dig redis.test     # resolves to the IP of redis_local-V1

$ docker stop redis_local-V1
$ dig redis.test     # resolves to the IP of the host machine (default)

NetworkManager on Ubuntu

If you're using NetworkManager, you should disable the built-in DNSMasq to get the port binding of port 53 to work.

Edit /etc/NetworkManager/NetworkManager.conf and comment out the line dns=dnsmasq so it looks like this:

# dns=dnsmasq

Restart using sudo service network-manager restart.

Now you should be able to do

docker run -d -v /var/run/docker.sock:/var/run/docker.sock:ro \
    -p 53:53/udp ruudud/devdns

devdns's People

Contributors

aloyr avatar andrewmackrodt avatar arkan avatar daaru00 avatar gianlucaficarelli avatar jonashelgemo avatar larsw avatar lopezator avatar ruudud avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

devdns's Issues

Double network interface on container fails

When a container has two network interfaces the devdns container generates an error in the corresponding .conf file under /etc/dnsmasq.d

For example I have traefik running with an local and an external network.

Devdns generates the following:

bash-4.3# cat traefik.docker.conf
address=/.traefik.docker/172.17.0.2172.24.0.2
bash-4.3#

And dnsmasq does not accept this.

bash-4.3# dnsmasq --test

dnsmasq: bad address at line 1 of /etc/dnsmasq.d/traefik.docker.conf

How should I fix this?

Dont start

  1. i add
    • FALLBACK_DNS=1.1.1.1
  2. dc pull
  3. dc up -d

Cycle restart:
image

on Arch

I use it on Arch Linux, the proper parameter is :

-v /run/docker.sock:/var/run/docker.sock

2 remarks regarding --dns option:

  • on Arch it is in /etc/conf.d/docker
  • you should add in the README that The --dns IP addresses are managed by the embedded docker DNS server and will not be updated in the container's /etc/resolv.conf file (from the docker doc). I spent a fair amount of time trying to figuring out why it was not updating that file ;-) until I read the doc.

The --dns IP addresses are managed by the embedded DNS server and will not be updated in the container's /etc/resolv.conf file.
The IP addresses passed via the --dns option is used by the embedded DNS server to forward the DNS query if embedded DNS server is unable to resolve a name resolution request from the containers.

wont work with compose

I have a bunch of containers that I start using docker-compose but it wont register the names and when I kill the stack I see in the logs it removes the names but it never registers them, only if I launch a container on its own

dnsmasq: failed to create listening socket for port 53: Address in use

Centos

sudo netstat -pna | grep 53
udp        0      0 127.0.0.53:53           0.0.0.0:*                           877/systemd-resolve
  dns:
    image: ruudud/devdns
    hostname: dns
    container_name: dns
    restart: always
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - /etc/resolv.conf:/mnt/resolv.conf
    network_mode: bridge
    environment:
      - DNS_DOMAIN=pomazan
      - NETWORK=auto
      - FALLBACK_DNS=1.1.1.1
      - HOSTMACHINE_IP=172.17.0.2
    labels:
      - "traefik.enable=false"
nameserver 172.17.0.2 # added by devdns
# Generated by NetworkManager
search pomazan.xyz
nameserver 1.1.1.1
nameserver 8.8.8.8

This error will appear when a new container starts:

image


+ Replaced misto-php-apache-platforma.pomazan → 172.18.0.28
dnsmasq: failed to create listening socket for port 53: Address in use
/run.sh: line 28: kill: (1012) - No such process,

Allow unsafe DNS names

From #11 @GianlucaFicarelli

dnsmasq can resolve names containing the underscore, and in some dev environment could be handy to enforce an unsafe option to keep the original name of the container.

Error response from daemon

latest: Pulling from ruudud/devdns
31603596830f: Pull complete
737796594f78: Pull complete
0d157d191099: Pull complete
52895126f428: Pull complete
1fc72bae0e24: Pull complete
Digest: sha256:3a9cfcc17961d86dc5489b00907adea88a26dbcbc5d97b0a685726e4acb1cd8d
Status: Downloaded newer image for ruudud/devdns:latest
4a1920f7e6366a47331ae7125f60ad5d0a722dba4329d8f38088b0360e0e5a68
docker: Error response from daemon: driver failed programming external connectivity on endpoint devdns (25e56c032df7ad496c3db37cedf675b07f5b1ab6ef30d2fedf0ffd9e03a787d1): Error starting userland proxy: listen udp4 0.0.0.0:53: bind: address already in use.

im trying to ping ip address for another section of network
pls help me to solve this

set_record doesn't respect <no value> from inspect

When starting the devdns container with a custom NETWORK, it might happen that some running containers are not at that specified network. In those cases the output of
docker inspect -f "{{.NetworkSettings.Networks.${cnetwork}.IPAddress}}" "$cid"
is not an empty value, but the value <no value>.

Therefore the check of set_record [[ -z "$ip" ]] && return 1 doesn't become true and generates a wrong dnsmasq entry. Finally the service will not start anymore.

You should either check explicitly for that value as well or change the way you retrieve the container ip address.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.