Give Codeship’s CI/CD Platform a Try

Want to learn more?

In a previous article about the docker run command, one of my final thoughts was the following:

In this article, we covered quite a few options for the docker run command. However, while these options are key, they only scratch the surface of the available options to docker run. Some of the options are complex enough to deserve an article unto themselves.

In today’s article, we are going to do just that: explore a single docker run command option. Specifically, we will explore an option that allows us to change DNS within a container.

What Does Add-Host Do?

The --add-host flag is used to add a single host to IP mapping within a Docker container. This flag can be useful when you need to connect a service within a container to an external host.

To get an understanding of how this works, let’s use the --add-host flag to map testing.example.com to 10.0.0.1.

We will be testing with a container named curl. This container has the curl command preinstalled and set as the entrypoint. With this container, we can use the curl command to connect to our test host.

Before we start adding the --add-host flag, let’s see what happens if we use this curl container to connect to the testing.example.com domain.

Great! Now when our container reaches out to testing.example.com, it is able to connect to our example host. This means our internal DNS resolution works; but how exactly does it work?

Understanding How Add-Host Works

To understand how the --add-host flag works, let’s spin up a simple Ubuntu container and take a look around. We can do this by using the -i (Interactive) and -t (Pseudo-TTY) flags.

These flags will start the container in a mode that allows us to interact with the running process. The process in this case will be /bin/bash; this gives us a shell within the container. With this shell, we can explore within the container itself.

With our shell startup successful, let’s start looking at this container’s configuration files. Specifically, let’s look at the configurations that drive DNS resolution. The first file we will look at is the /etc/nsswitch.conf file.

The nsswitch.conf file in Unix and Linux is used to define where and how the system will perform name service-related lookups. The specific setting we are interested in is the hosts setting. The hosts setting is used to define the sources and order used for hostname resolution.

In the above, we can see that the hosts setting is set to files dns. This setting means that for hostname resolution, the system will first consult files, then dns.

When our system is performing a DNS lookup, it will first reference local configuration files, such as /etc/hosts. If the host is not found within /etc/hosts, the system will then query the name servers defined within the /etc/resolv.conf configuration file.

Something important to remember is that this methodology is the standard Linux setup. These steps are common for most Linux systems, not just containers.

What does this mean for the --add-host flag? Well, it means that there are only two places Docker could change DNS resolution: either the /etc/hosts file or the name servers referenced in /etc/resolv.conf.

It appears that the --add-host flag places an entry into the /etc/hosts file. What is interesting about this is that editing the /etc/hosts file is a time-honored sysadmin trick. It has been used for many years to perform just this task: taking an unresolvable hostname and mapping it to a static IP.

!Sign up for a free Codeship Account

Using Add-Host to Override DNS Resolution

Another common use of the /etc/hosts file is overriding normal DNS. Since files is listed first within the /etc/nsswitch.conf configuration file, the /etc/hosts file is consulted before any traditional DNS name servers.

This means that it is possible to place an entry into the /etc/hosts file that overrides an existing name. To experiment a little, let’s do this with Google’s domain.

To start our experiment, lLet’s take a look at what normally happens when we use our curl container to connect to google.com.

From the above, we can see that our --add-host addition resulted in our curl command to connect to our example host. What this shows is that the --add-host flag can be used for more than mapping an unresolved hostname. It can be used to override traditional DNS as well.

This can be a useful method to force a container to connect to a specific host address.

Adding Multiple Entries

Another nice feature of this flag is that it can be specified multiple times.

In the above example, we can see that specifying the --add-host multiple times resulted in multiple entries within the /etc/hosts file. This is true whether multiple hosts are specified (as shown) or if the same host is specified.

This is useful in cases where you may want to specify multiple manual host to IP mappings.

Summary

In this article, we explored the --add-host flag available with the docker run command. We also learned that Docker uses a time-honored sysadmin trick for the heavy lifting behind the --add-host flag.

At this point though, you might be thinking, “This flag is interesting but how can it be used in the real world?”

When creating an application that uses another service, like Redis for example, I tend to have my application configured to reach out to the host of redis. I then link a Redis container with that name to my application container. This means my container’s configuration is simple — it just references redis. This works great when I can simply link the Redis container to my application container.

But what happens when the Redis instance can’t be “linked” or is even outside of your control? We would then have to configure the application to reach out to a specific host, somewhat complicating the application’s configuration.

The --add-host flag can be a simple way to keep a simplistic application configuration while still enabling the application to connect to the remote instance.

Subscribe via Email

Over 60,000 people from companies like Netflix, Apple, Spotify and O'Reilly are reading our articles. Subscribe to receive a weekly newsletter with articles around Continuous Integration, Docker, and software development best practices.

We promise that we won't spam you. You can unsubscribe any time.

Join the Discussion

Leave us some comments on what you think about this topic or if you like to add something.