The None Network Driver | Networking in Docker #4

Learn what the None driver is, how it enables network isolation, how to use it, and possible use cases


What is the none network driver in Docker and how can it help me run secure, network-isolated containers?

This blog will try to answer that as simply as possible.

Introduction

This blog is the fourth 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 none network driver?
  • How to use it?
  • When to use it? - possible use cases

Let’s start with a quick refresher: what are network drivers?

Network drivers enable us to easily use multiple types of networks for containers and hide the complexity required for network implementations.

So…

What is the none network driver?

The none driver simply disables networking for a container, making it isolated from other containers.

none driver

Within the container, only the loopback interface is created to enable inter-process-communication, by using the IP address 127.0.0.1 mapping to the name localhost.

But the absence of other network interfaces like eth0 means, neither can it reach external networks nor can external networks reach it.

This makes the none network driver very secure. But it also limits its usability, as we usually wish to enable communication between containers.

We’ll later look at some possible use cases for none.

For now, let’s learn…

How to use the none network driver?

First, we’ll run an interactive shell (sh) within an alpine Linux container named app1, without specifying a network:

docker run -it --name app1 alpine sh

NOTE: the -it flags connect your terminal’s input to the container’s one, giving you direct access to the shell running inside the container.

Docker uses the default bridge network driver if no driver is stated, which we will learn more about in an upcoming post.

But the important thing to note is that this container has access to the internet.

We can check that by pinging a web address like google.com:

ping google.com

or by running the apk update command:

apk update

They should work.

We can check the network interfaces and IP addresses by using:

ip addr

This shows detailed configurations for each network interface.

The two primary interfaces of interest are the loopback (having the familiar 127.0.0.1 address), and the ethernet interface (named eth0 or similar). The loopback allows processes within the container to communicate with each other, whereas, the ethernet interface within IP/inet address connects the container to a network.

NOTE: On some systems, additional tunnel interfaces (like tunl0) might show up; we can ignore them for now.

We can also check the presence of a route table that has a default route to a gateway:

route

All this was a way to confirm the presence of network connectivity. Don’t worry if you didn’t understand every single detail.

Okay.

Now let’s see how a container with the none driver behaves.

Let’s open up a new terminal tab/window and run a very similar container like before. This time we will specify the network to be none and name it app2.

docker run -it --name app2 --network none alpine sh

Trying to access the internet now shall fail - like pinging the google URL:

ping google.com

or apk update

apk update

If we try to ping localhost, it will surprisingly work:

ping localhost

This is because the loopback interface is present, as you can check with:

ip addr

But you will notice that there are no ethernet interfaces.

As well as no routes:

route

Thus, neither can app2 be reached from the outside nor vice versa.

The only way we can connect to app2 is by using the docker exec command, which is used to run a command inside a running container.

Open up a third terminal tab/window and run the following:

docker exec app2 ip addr

This will show the list of interfaces and IP addresses of app2 we had seen earlier.

If you want to start another interactive session, you can run another shell (sh) and use -it with exec:

docker exec -it app2 sh

To exit the shell, use ctrl+d or (control+d).

Once we are done playing around, we can clean up the containers using:

docker rm -f app1 app2

When to use the none network driver? - possible use cases

While I personally haven’t used the none driver in production much during the several years that I have been exposed to containers, it might still be useful for cases that require strict network isolation.

I could think of two niche use cases:

  1. To run network-isolated applications that only perform file operations

    This could be done by mounting volumes to the container, which then, in turn, could perform operations after certain intervals or by detecting file change events. Some examples include using a container for generating database backups, processing log files, etc.

  2. To run a one-off command which requires network-isolation

    Sometimes it might be required to just perform computations and print logs in a secure, network-isolated environment. Examples include running ci/cd jobs that export produced artifact files or testing suspicious scripts that could contain malware, etc.

According to the documentation, none may also be used in conjunction with a custom network driver.

Do you know of any other important use cases that I am missing? Please let me know as I’d love to add them here.

Conclusion

In this blog, we learnt about the none network driver in docker - what it is, how to use it, and some possible use cases.

By enabling network isolation, the none driver offers a secure environment for running processes. But it also limits its usability.

In the next blog, we will learn about the host driver - which provides the best network performance out of all 4 drivers! ⚡️

Thanks for making it so far! 👏

See you at the next one.

Till then…

Be bold and keep learning.

But most importantly,

Tech care!


See also