How Tos, OpenStack

Docker Networking

In the previous post I went through some very basic commands using Docker. In this blog post I’ll describe some hands-on experience with Docker networking.

Docker networking has been a subject for many articles lately. There’s been few proposals of how to make things better and enable multi-host Docker containers connectivity. You can find at more about the proposals at Weave’s blog, one of the groups that has submitted a proposal. That said, Docker has acquired recently SocketPlane in order to drive its networking effort forward.

Docker Networking Basics

After a successful installation of Docker Linux bridge is created on the host machine. Executing the ifconfig command will provide the following output:

ubuntu@docker-instance1:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::5484:7aff:fefe:9799/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1450  Metric:1
          RX packets:1 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:76 (76.0 B)  TX bytes:258 (258.0 B)

eth0      Link encap:Ethernet  HWaddr fa:16:3e:d5:3a:ee  
          inet addr:192.168.1.11  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fed5:3aee/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:47377 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12971 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:65798713 (65.7 MB)  TX bytes:1103464 (1.1 MB)
.....

The docker0 Linux bridge enables containers communication between one another and proxies traffic to the outside world. Thanks to MASQUERADE rule in the POSTROUTING chain traffic with source IP 172.17.x.x, the same subnet our containers are using, to the outside world is being masqueraded. Running iptables -t nat -L provides this output:

ubuntu@docker-instance1:~$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 anywhere

Chain DOCKER (2 references)
target prot opt source destination 

After starting two interactive containers using the following command:

ubuntu@docker-instance1:~$ sudo docker run -ti ubuntu:14.04 /bin/bash

We can see that running ifconfig indicates two new interfaces.

ubuntu@docker-instance1:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::5484:7aff:fefe:9799/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:47 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2724 (2.7 KB)  TX bytes:538 (538.0 B)
....
....
veth98daa6a Link encap:Ethernet  HWaddr c2:be:05:8f:7d:a0  
          inet6 addr: fe80::c0be:5ff:fe8f:7da0/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1450  Metric:1
          RX packets:19 errors:0 dropped:0 overruns:0 frame:0
          TX packets:24 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1334 (1.3 KB)  TX bytes:1856 (1.8 KB)

vethf8420d4 Link encap:Ethernet  HWaddr 7a:27:ed:1c:7d:45  
          inet6 addr: fe80::7827:edff:fe1c:7d45/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1450  Metric:1
          RX packets:12 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:928 (928.0 B)  TX bytes:928 (928.0 B)

Those new interfaces are veth (virtual ethernet) pairs. In order for the containers to communicate with the docker0 Linux bridge from inside the container, which is also a network namespace and therefore isolated from the host network, they need a mechanism called veth pair. The easy way of thinking of it is as a virtual cable with two ends – one at the container and one at the host connected to the docker0 Linux bridge. Quick brctl show will show the two veth ends connected to the docker0 Linux bridge on the host machine.

ubuntu@docker-instance1:~$ sudo brctl show
bridge name	bridge id		STP enabled	interfaces
0?		8000.000000000000	no		
docker0		8000.56847afe9799	no		veth98daa6a
							vethf8420d4

Using ping between container1 to his same host neighbour, container2 we can see traffic going from container1 veth end toward its other end veth98daa6a. The docker0 Linux bridge will receive this traffic and send it to vethf8420d4 and the latter will forward it to its other end at container2.

Connecting Multi-Host Docker Containers

As said in the beginning of this post, there are few solution for multi-host Docker containers connectivity.

Weave

Weave solves multi-host Docker containers connectivity by creating vRouter in each host in order to facilitate a connection between containers running on different hosts. The communicating vRouters using both TCP and UDP on port 6783. TCP to communicate topology and UDP, using a proprietary tunnelling, to forward data between the containers. On top of that, Weave installation create also a weave bridge. Each container is connected to that bridge via a veth pair and this bridge is also connected to the vRouter. You can find more details of my hands-on experience with Weave here.

References and further reading:
Using Docker
Docker Networking

Advertisements

3 thoughts on “Docker Networking

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s