DNS Round Robin In Docker

DNS Round Robin In Docker

DNS Round Robin is the concept that you can have two different hosts with DNS Aliases that respond to the same DNS Name. Where might you find something like this? Consider a service like Instagram. They need more than one server to provide their service, yet users always go to the same Instagram.com domain to use the service. One name, many servers providing the service. In addition to load balancing and server scaling, DNS Round Robin is another technique big companies can use to ensure 24/7/365 uptime. In other words, there are several IP addresses and DNS Records supporting the one public-facing name end-users use(in this case Instagram.com). This same concept applies to containers and in this tutorial we’ll have a look at DNS Round Robin in Docker.


Creating A Custom Virtual Network

The first step for this exercise is to create a new virtual network in Docker. In this example, the custom virtual network name is dns_test.

> docker network create dns_test
0d64fe86c328dbcffe93cc631f720349c9fc840474dd63461b13ad4c75acefee

Add Two Containers

In this step we add two containers, while attaching them to our new dns_test network. You’ll notice the use of the –network-alias option which adds a network-scoped alias for the container you are starting. This example uses an alias name of “search”.

> docker container run -d --network dns_test --network-alias search elasticsearch:2
398ed3ce1c72128e08c97cce30a05aa2da5d85d3690bf997b25a04a13d880a13

Now we add the second container to the same dns_test network. This container will of course have its own unique ID, however it uses the same network alias of “search”. So our goal here is that requests to the “search” DNS name will get served by either of these two containers.

> docker container run -d --network dns_test --network-alias search elasticsearch:2
6886d224dc68fb2eaa43cc284d2a49a24ec605fbb61f2cfc199a1021c0798c33

Listing out the containers shows they are started successfully. Even though we did not manually publish any ports, we can see that these containers have some exposed ports. Those are part of the Dockerfile which allows communication on those ports for the same virtual network. We only need to use -p if we wanted to expose to the outside world, not just the virtual network itself.

> docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
6886d224dc68        elasticsearch:2     "/docker-entrypoint.…"   12 seconds ago      Up 12 seconds       9200/tcp, 9300/tcp   charming_keldysh
398ed3ce1c72        elasticsearch:2     "/docker-entrypoint.…"   22 seconds ago      Up 21 seconds       9200/tcp, 9300/tcp   flamboyant_hodgkin

Testing DNS Round Robin

At this stage we have the two containers using the same alias so how can we test that each is responding to requests to the “search” name? For this, we can temporarily launch an alpine container and simply run the nslookup command from within the container on the “search” name. Note we have used the –rm option here which means to simply remove the container once it does its job. In this case, that means once nslookup runs and does its job, the container disappears. It looks like DNS Round Robin is in fact working too because from the output of nslookup we can see that both 172.19.0.2 and 172.19.0.3 are associated with the same DNS name of “search”. Cool!

> docker container run --rm --network dns_test alpine nslookup search
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
df20fa9351a1: Pull complete
Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Status: Downloaded newer image for alpine:latest
Address:        127.0.0.11:53

Non-authoritative answer:
Name:   search
Address: 172.19.0.2
Name:   search
Address: 172.19.0.3

Non-authoritative answer:

As a final test of DNS Round Robin, we can temporarily run a centos container which has curl already installed. One the container launches, it makes a curl request to the “search” domain name via curl -s search:9200. By running this command a few times, you can see that one response is using the name “Asteroth” and the other is using “Blindspot”. So once again, round robin is working.

> docker container run --rm --network dns_test centos curl -s search:9200
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
3c72a8ed6814: Pull complete
Status: Downloaded newer image for centos:latest
{
  "name" : "Asteroth",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "2.4.6",
    "build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
    "build_timestamp" : "2017-07-18T12:17:44Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.4"
  },
  "tagline" : "You Know, for Search"
}
> docker container run --rm --network dns_test centos curl -s search:9200
{
  "name" : "Blindspot",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "S0DJCGPnS32txAEO8t9-Qw",
  "version" : {
    "number" : "2.4.6",
    "build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
    "build_timestamp" : "2017-07-18T12:17:44Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.4"
  },
  "tagline" : "You Know, for Search"
}

Once again, list the running containers so we can see their names in order to remove them.

> docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
6886d224dc68        elasticsearch:2     "/docker-entrypoint.…"   6 minutes ago       Up 6 minutes        9200/tcp, 9300/tcp   charming_keldysh
398ed3ce1c72        elasticsearch:2     "/docker-entrypoint.…"   6 minutes ago       Up 6 minutes        9200/tcp, 9300/tcp   flamboyant_hodgkin

Lastlym, remove the two containers we used for testing to clean up the Docker environment.

> docker container rm -f charming_keldysh flamboyant_hodgkin
charming_keldysh
flamboyant_hodgkin

Learn More

DNS Round Robin In Docker Summary

  • Docker can have multiple containers on a given network respond to the same DNS address.
  • This works on newly created custom virtual networks in Docker.
  • To configure DNS Round Robin In Docker, you can use the –network-alias option.
  • Use the nslookup command in a container to see what containers use a DNS Name
  • DNS Round Robin behaves like a “Poor Mans Load Balancer”