The Host Network Driver | Networking in Docker #5

Learn what the Host driver is, how it provides the best performance, how to use it, possible use cases and limitations

What is the host network driver in Docker and how does it provide the best network performance?

This blog will try to answer that (and more) as simply as possible.

Introduction

This blog is the fifth one in a series for Docker Networking.

If you are looking to learn more about the basics of Docker, I’ll recommended checking out the Docker Made Easy series.

Here’s the agenda for this blog:

  • What is the host network driver?
  • How to use it?
  • When to use it? — possible use cases
  • its limitations

Here are some quick reminders:

  • A Docker host is the physical or virtual machine that runs the Docker daemon.
  • Docker Network drivers enable us to easily use multiple types of networks for containers and hide the complexity required for network implementations.

Alright, so…

What is the host driver?

When a container uses the host network driver, the container shares the network stack (namespace) of its host.

This means the network of the container is not virtualized, making the container appear as if it is the host itself, from a networking perspective.

A direct consequence of this is that — if a container using the host driver publishes a port, let’s say 8000, then that port will also be published on the host machine. If that port is already in use, then the container will not start successfully.

However, in all other ways — like storage, process, and user namespace, the container is isolated from the host.

NOTE: the host driver is only supported on Linux as of now i.e. host driver is not available on Mac or Windows platforms.

How to use the host driver?

Example without specifying any network — using default bridge driver

Let’s start off by running an nginx container named app1 in the background (-d) without specifying any network:

The nginx container by default maps onto port 80 inside the container. Docker uses the default bridge network driver if no driver is specified.

If we use curl localhost inside the container, we’ll see nginx the nginx index page successfully:

NOTE: Did you know port 80 is the default HTTP port? Therefore curl localhost automatically refers to curl http://localhost:80.

But if we try to curl localhost from the host machine, it will fail:

This is because we cannot reach the nginx container from the host, as the host and the container are using separate network namespaces (when using the default bridge network).

The solution is port mapping.

Let’s remove app1 and create it again using the port mapping -p option:

The port mapping option (-p 2000:80) instructs Docker to map port 2000 on the host to port 80 on the container.

Let’s check out results using curl:

We’ll learn more about bridge drivers in the next part of this series.

Example using host driver

As we’d learnt, when using the host driver, the network stack is the same for both the container and host, so there’s no need for port mapping. Let’s check it out.

NOTE: you need a Linux machine to use the host driver.

We’ll run a similar nginx container named app2 using the host driver:

Curling localhost will now work:

Can you guess why?

The answer will be clear if we…

Check differences in IP configuration

Let’s first look at IP addresses assigned to all network interfaces on the host machine:

Note the number of interfaces and the associated IPs.

What happens if we execute the same command inside the app1 container (the one using the default bridge driver)?

We should certainly see differences between the configuration in the host machine and app1, since they are using different network namespaces.

Now let’s try that for app2 container (the one using the host driver):

You’ll notice that the network configuration is exactly the same as for the host machine.

This is a clear indication that host driver makes the container share the host machines network.

One consequence of using the host driver is…

Port conflicts

You cannot run multiple containers that bind to the same port using host driver.

To demonstrate this, we’ll try to run a very similar nginx container to app2, but named as app3:

If we check the logs:

We’ll notice that nginx failed to start because the port it tried to bind to (80) was already in use.

We can confirm that app3 exited:

Cleanup

To end the hands-on lab, we’ll clean up the containers: