Docker networking: Weave

By | 02/01/2017

Introduction

Launching some hosts

We have done this many times before, so it should not be a surprise. Launch two hosts (we’ll call then node-01 and node-02) using docker-machine:

WAUTERW-M-G007:Vagrant wauterw$ docker-machine create -d virtualbox node-01
Running pre-create checks...
Creating machine...
(node-01) Copying /Users/wauterw/.docker/machine/cache/boot2docker.iso to /Users/wauterw/.docker/machine/machines/node-01/boot2docker.iso...
(node-01) Creating VirtualBox VM...
(node-01) Creating SSH key...
(node-01) Starting the VM...
(node-01) Check network to re-create if needed...
(node-01) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env node-01
WAUTERW-M-G007:Vagrant wauterw$ docker-machine env node-01
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/wauterw/.docker/machine/machines/node-01"
export DOCKER_MACHINE_NAME="node-01"
# Run this command to configure your shell:
# eval $(docker-machine env node-01)

As we want to understand the networking concepts of Weave a bit better, let’s first have a look at the current ip configuration, even before Weave has been installed and configured. To do so, ssh into the hosts using docker-machine ssh node-01 and docker-machine ssh node-02.

For node-01:

root@node-01:/home/docker# ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:51:5F:55:27
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth0      Link encap:Ethernet  HWaddr 08:00:27:E4:E8:93
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fee4:e893/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:716 errors:0 dropped:0 overruns:0 frame:0
          TX packets:438 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:114969 (112.2 KiB)  TX bytes:122220 (119.3 KiB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:26:04:19
          inet addr:192.168.99.100  Bcast:192.168.99.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe26:419/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:60 errors:0 dropped:0 overruns:0 frame:0
          TX packets:48 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:11299 (11.0 KiB)  TX bytes:7852 (7.6 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:2752 (2.6 KiB)

For node-02:

root@node-02:/home/docker# ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:FD:35:BE:8B
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth0      Link encap:Ethernet  HWaddr 08:00:27:B5:DC:C2
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:feb5:dcc2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:730 errors:0 dropped:0 overruns:0 frame:0
          TX packets:445 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:115656 (112.9 KiB)  TX bytes:122696 (119.8 KiB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:7F:AF:56
          inet addr:192.168.99.101  Bcast:192.168.99.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe7f:af56/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:54 errors:0 dropped:0 overruns:0 frame:0
          TX packets:48 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:9034 (8.8 KiB)  TX bytes:7852 (7.6 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:2752 (2.6 KiB)  TX bytes:2752 (2.6 KiB)

Install Weave

Installing Weave is easy. Just execute a simple curl command.

root@node-01:/home/docker# sudo curl -L git.io/weave -o /usr/local/bin/weave
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   578    0   578    0     0    404      0 --:--:--  0:00:01 --:--:--  2028
100 76651  100 76651    0     0  32694      0  0:00:02  0:00:02 --:--:--  265k
root@node-01:/home/docker# sudo chmod a+x /usr/local/bin/weave

Next, we will start Weave on the first node:

root@node-01:/home/docker# weave launch
Unable to find image 'weaveworks/weaveexec:1.8.0' locally
1.8.0: Pulling from weaveworks/weaveexec
3690ec4760f9: Pull complete
accb7dea6980: Pull complete
...
Digest: sha256:57b511cd5ccbd030c611fa86c4213dd680fd2968991f5492daf53a342115bbda
Status: Downloaded newer image for weaveworks/weaveexec:1.8.0
Unable to find image 'weaveworks/weavedb:latest' locally
latest: Pulling from weaveworks/weavedb
1266eb846caf: Pulling fs layer
1266eb846caf: Verifying Checksum
1266eb846caf: Download complete
1266eb846caf: Pull complete
Digest: sha256:c43f5767a1644196e97edce6208b0c43780c81a2279e3421791b06806ca41e5f
Status: Downloaded newer image for weaveworks/weavedb:latest
Unable to find image 'weaveworks/weave:1.8.0' locally
1.8.0: Pulling from weaveworks/weave
3690ec4760f9: Already exists
accb7dea6980: Already exists
cca7ac164849: Already exists
7dfd26ccd2f1: Already exists
978f41e96bea: Already exists
....
Digest: sha256:041f69b0522123a8cc9a535d32d3117a9384a28047adb7b53c691625c253bee6
Status: Downloaded newer image for weaveworks/weave:1.8.0
Unable to find image 'weaveworks/plugin:1.8.0' locally
1.8.0: Pulling from weaveworks/plugin
3690ec4760f9: Already exists
...
995f67a0b01a: Pulling fs layer
995f67a0b01a: Verifying Checksum
995f67a0b01a: Download complete
995f67a0b01a: Pull complete
Digest: sha256:b017170d6206a10ade7677e6c75fb119940ad1e8e4e7ab8bdf09a6af33e61328
Status: Downloaded newer image for weaveworks/plugin:1.8.0

You’ll see that upon starting Weave, you immediately see that some Docker containers are pulled. In fact, Weave will create three containers

root@node-01:/home/docker# docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
9dab815f8b57        weaveworks/plugin:1.8.0      "/home/weave/plugin"     19 seconds ago      Up 18 seconds                           weaveplugin
ca15e373e9d6        weaveworks/weaveexec:1.8.0   "/home/weave/weavepro"   30 seconds ago      Up 29 seconds                           weaveproxy
3afb2aeab572        weaveworks/weave:1.8.0       "/home/weave/weaver -"   31 seconds ago      Up 30 seconds                           weave

Next, we will also start Weave on the second host and create a peer connection by passing the IP of the first host. Our two hosts are now connected to each other, and any subsequent containers you launch with Weave are visible to any other containers that the Weave network is aware of.

root@node-02:/home/docker# weave launch 192.168.99.100
root@node-02:/home/docker# docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
567501310f6e        weaveworks/plugin:1.8.0      "/home/weave/plugin"     3 seconds ago       Up 2 seconds                            weaveplugin
3ab819a01d2a        weaveworks/weaveexec:1.8.0   "/home/weave/weavepro"   3 seconds ago       Up 2 seconds                            weaveproxy
647d2c19d6c8        weaveworks/weave:1.8.0       "/home/weave/weaver -"   3 seconds ago       Up 3 seconds                            weave

Have a look here to ensure the connection is established successfully:

root@node-01:/home/docker# weave status connections
<- 192.168.99.101:39111  established fastdp 86:c8:5a:41:9c:90(node-02)

root@node-02:/home/docker# weave status connections
-> 192.168.99.100:6783   established fastdp ca:a7:ba:55:a6:ab(node-01)

Look at the IP configuration

It’s interesting to have a look at the networking side. When you perform a ‘docker network ls’, you can see that the usual three docker networks (bridge, host, none) are accompanied by a ‘weave’ overlay network. This is (obviously) the case for both hosts.

root@node-01:/home/docker# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a3f6e589effa        bridge              bridge              local
e68e58c40fb7        host                host                local
efd7ba48a368        none                null                local
33fd31bc9800        weave               weavemesh           local

root@node-02:/home/docker# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
8f788d8e2198        bridge              bridge              local
83e79aa0e938        host                host                local
587bfcacbe66        none                null                local
3f06b0b6238b        weave               weavemesh           local

Let’s have a bit of a deeper look into this weave overlay network:

root@node-01:/home/docker# docker network inspect weave
[
    {
        "Name": "weave",
        "Id": "33fd31bc9800fc34f02fa329fd2f056a0eb5475edaf7ac163ec8dd695e7ac074",
        "Scope": "local",
        "Driver": "weavemesh",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "weavemesh",
            "Options": null,
            "Config": [
                {
                    "Subnet": "10.32.0.0/12"
                }
            ]
        },
        "Internal": false,
        "Containers": {},
        "Options": {
            "works.weave.multicast": "true"
        },
        "Labels": {}
    }
]

Here you can see that a subnet of 10.32.0.0/12 is associated with this overlay network (a /12 mask will give us 1048576 IP addresses).

Create containers

Next, let’s create some containers. For testing the connectivity, we will create container-01 on node-01 and container-02 on node-02:
Node-01:

root@node-01:/home/docker# weave run -itd --name container-01 ubuntu:14.04
fe16d96f19e9d2698160ab9dbe000a3396f4ee651bee38481d78b45e5c3aed5f

Node-02:

root@node-02:/home/docker# weave run -itd --name container-02 ubuntu:14.04
07199d811f21602cd476e31eb08fd409758530ce03f0885c14e135eb8dbbfb3d

Let’s have a look at the IP configuration:

On node-01:

root@node-01:/home/docker# docker exec container-01 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)

ethwe     Link encap:Ethernet  HWaddr 5e:17:e1:79:b3:25
          inet addr:10.32.0.1  Bcast:0.0.0.0  Mask:255.240.0.0
          inet6 addr: fe80::5c17:e1ff:fe79:b325/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1410  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1338 (1.3 KB)  TX bytes:690 (690.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

On node-02:

root@node-02:/home/docker# docker exec container-02 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)

ethwe     Link encap:Ethernet  HWaddr 02:3f:60:cd:b9:2b
          inet addr:10.44.0.0  Bcast:0.0.0.0  Mask:255.240.0.0
          inet6 addr: fe80::3f:60ff:fecd:b92b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1410  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:690 (690.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

As you can see from the above output, an ethernet interface called ‘ethwe’ has been created with IP addresses associated to the 10.0.0.0/8 network.

Note: you will see that we used ‘weave run’ instead of ‘docker run’. This is basically a wrapper script which runs docker run and then attaches the weave bridge to the container. In case you wonder: just running ‘docker run’ will not work as it will not link to the weave bridge. To summarize: both below snippets do exactly the same

Using weave run:

root@node-01:/home/docker# weave run -itd --name container-01 ubuntu:14.04

Using docker run:

root@node-01:/home/docker# docker run -itd --name container-01 --net weave ubuntu:14.04

Testing connectivity

Let’s go ahead and test the IP connectivity. From the container on node-01 we will ping the continer on node-02 and vice versa:

Ping from Container-01 on node-01 to container-02 on node-02:

root@node-01:/home/docker# docker exec container-01 ping -c4 10.44.0.0
PING 10.44.0.0 (10.44.0.0) 56(84) bytes of data.
64 bytes from 10.44.0.0: icmp_seq=1 ttl=64 time=0.986 ms
64 bytes from 10.44.0.0: icmp_seq=2 ttl=64 time=0.561 ms
64 bytes from 10.44.0.0: icmp_seq=3 ttl=64 time=0.495 ms
64 bytes from 10.44.0.0: icmp_seq=4 ttl=64 time=0.637 ms

--- 10.44.0.0 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 0.495/0.669/0.986/0.192 ms

Ping from Container-02 on node-02 to container-01 on node-01:

root@node-02:/home/docker# docker exec container-02 ping -c4 10.32.0.1
PING 10.32.0.1 (10.32.0.1) 56(84) bytes of data.
64 bytes from 10.32.0.1: icmp_seq=1 ttl=64 time=0.447 ms
64 bytes from 10.32.0.1: icmp_seq=2 ttl=64 time=0.529 ms
64 bytes from 10.32.0.1: icmp_seq=3 ttl=64 time=0.368 ms
64 bytes from 10.32.0.1: icmp_seq=4 ttl=64 time=0.646 ms

--- 10.32.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2998ms
rtt min/avg/max/mdev = 0.368/0.497/0.646/0.105 ms

That’s it folks. Weave has a lot of potential and we will explore it further in next posts I’m sure.

Leave a Reply

Your email address will not be published. Required fields are marked *