external to docker-compose, add a dns entry that is resolved within docker-compose

 continuing from the previous article.

Problem

In a scenario where you are debugging external to your docker compose stack, how do you support the ability to inject a dns entry that resolves to your debugging instance?

Assumptions

Using the same docker compose from the previous article - recreated here without changes.

services:
  container1:
    container_name: container1
    image: ...  
    ports:
      - "100:100"
      
  container2:
    container_name: containerA 
    image: containerA
    ports:
      - "200"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.container1.loadbalancer.healthCheck.path=/"
      - "traefik.http.services.container1.loadbalancer.server.port=200"
    
  container2A:
    image: containerA
    ports:
      - "200"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.container1.loadbalancer.healthCheck.path=/"
      - "traefik.http.services.container1.loadbalancer.server.port=200"
      
  traefik:
    container_name: traefiklb
    image: ...
    ports:
      - "8180:8080"
      - "200:200"
    command:
      - "--entrypoints.web.address=:200"
      

Details

Our scenario is debugging a service named container3.  I am interesting in having container1 make a REST call to container3

Building on this article, DNS is a tree of servers which have entries.  In order to solve this problem, we need to inject an entry into one of of the DNS servers that we have control over.

If we use the image from the article, but focus on one server, it looks like there is one that we have control over.

Docker DNS on Windows

In Windows, our ability to add dns entries is through a file located at C:\Windows\System32\drivers\etc\hosts.  You will need Administrator rights to edit this file.

This is how my file looks:

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	::1             localhost

The # is a comment - and therefore there are no special dns entries configured.  To configure a new dns entry, add a new line that looks like

127.0.0.1  container3

when you save this file, Windows sees this change and adds the dns entry to its local list of authoritative entries in which it responds to.  For instance, after this change, if you were to run nslookup container3, the windows DNS will respond. 

But how does that help from within the docker compose environment?  Remember that DNS is a hierarchy of DNS servers.  That is, if one server does not know the requested name, it will forward to its parent for resolution.  I believe that is what is called an Iterative Query in DNS speak.  In our case tho, the DNS inside Docker does _not_ know where container3 is, and therefore forwards the request to the host system (in our case Windows).  Windows responds with 127.0.0.1 (which is our host machine), and then returns that to our DNS client (container1).

By using the hierarchical nature of DNS, we can resolve a container from within a docker compose network to any IP address by using our host (Windows) DNS mechanism.

In the next article, we will start a new segment: How does all of this apply to a ubuntu and docker environment?

Comments

Popular Posts