Networking has always been a crucial part of operating systems. When virtualization gained momentum the networking stack was one of the most important aspect that Engineers needed to get right. Docker is no exception, when we containerize the application, one of the important constraints we have is that the app itself shouldn't care about the fact that it is running inside a container. Everything from storage stack to system calls should work as if it is a full-fledged operating system. Everything including Networking.
Docker offers various ways to provide networking to its containers. Each container can get its own networking stack including an IP Address. The containers themselves can interact with each other as if they are talking to different nodes on the network. But before we delve into the details about networking let's clear up a few basic details.
Docker for Windows or Mac vs Docker on Linux
Docker on Windows or Mac doesn't run on the operating system itself. What Docker does, instead, is to run a virtual machine on top of Hyper-V Windows or HyperKit on Mac OS.
This VM is connected via its own virtual network interface which complicates the matter. To keep things simple we want to start with Docker on Linux which is the state of Docker that you are most likely to encounter in production. Also this is the state where you have to be concerned about making your application available to the outside world in a secure way.
So to observe Docker networking in its natural habitat takes us to an SSDNodes VPS running Linux (Ubuntu 18.04 LTS) with Docker installed on top of it. The VPS has Docker installed in it.
Pre-requisites
Here's the setup I will be using for this post, in case you want to follow along:
- Ubuntu 18.04 LTS server with a public IP on SSDNodes. Let's call this variable,
Public_IP
which would be different for different users.
Initial Networking Setup
Let\'s set a baseline by looking at the networking interfaces we have on our VPS before and after Docker was installed. Use the command ip addr
to list them.
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:f3:e8:f7:c7 brd ff:ff:ff:ff:ff:ff
inet 63.250.55.61/24 brd 63.250.55.255 scope global enp3s0
valid_lft forever preferred_lft forever
inet6 fe80::5054:f3ff:fee8:f7c7/64 scope link
valid_lft forever preferred_lft forever
We have two interfaces one with the main public IP, called ens3
,and another is a loopback interface lo
used for debugging and other purposes. Now you can go ahead and install Docker. This is what your system has by default.
After installing Docker, if you have not started any new container you will see one new entry.
$ ip addr
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:1e:3f:71:13 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:1eff:fe3f:7113/64 scope link
valid_lft forever preferred_lft forever
This new interface docker0
is added to the VPS and the VPS has an IP 172.17.0.1
on this new interface. Let's create a Ubuntu container and see what we can
by subscribing to our newsletter.