Using the Weave network plugin

One of the things that sets Weave apart is that it can be operated in several different manners. As we've seen in the previous recipes of this chapter, Weave has its own CLI which we can use to provision containers directly onto the Weave network. While this is certainly a tight integration that works well, it requires that you leverage the Weave CLI or Weave API proxy to integrate with Docker. In addition to these options, Weave has also written a native Docker network plugin. This plugin allows you to work with Weave directly from Docker. That is, once the plugin is registered, you no longer need to use the Weave CLI to provision containers into Weave. In this recipe, we'll review how to install and work with the Weave network plugin.

Getting ready

It is assumed that you're building off the lab we created in the first recipe of this chapter. It is also assumed that the hosts have Docker and Weave installed. Docker should be in its default configuration, Weave should be installed, with all four hosts successfully peered together, as we did in the first recipe of this chapter.

How to do it…

Like the other components of Weave, leveraging the Docker plugin couldn't be easier. All you need to do is to tell Weave to launch it. For instance, if I decided to use the Docker plugin on the host docker1, I could launch the plugin like this:

user@docker1:~$ weave launch-plugin
3ef9ee01cc26173f2208b667fddc216e655795fd0438ef4af63dfa11d27e2546
user@docker1:~$ 

Much like the other services, the plugin comes in the form of a container. After running the preceding command, you should see the plugin running as a container named weaveplugin:

How to do it…

Once running, you should also see it registered as a network plugin:

user@docker1:~$ docker info
…<Additional output removed for brevity>… 
Plugins:
 Volume: local
 Network: host weavemesh overlay bridge null 
…<Additional output removed for brevity>… 
user@docker1:~$ 

We can also see it as a defined network type using the docker network subcommand:

user@docker1:~$ docker network ls
NETWORK ID        NAME              DRIVER            SCOPE
79105142fbf0      bridge            bridge            local
bb090c21339c      host              host              local
9ae306e2af0a      none              null              local
20864e3185f5      weave             weavemesh         local
user@docker1:~$ 

At this point, connecting containers to the Weave network can be done directly through Docker. All you need to do is specify the network name of weave when you start a container. For instance, we can run:

user@docker1:~$ docker run -dP --name=web1 --net=weave 
jonlangemak/web_server_1
4d84cb472379757ae4dac5bf6659ec66c9ae6df200811d56f65ffc957b10f748
user@docker1:~$

If we look at the container interfaces we should see the two interfaces we're accustomed to seeing with Weave connected containers:

user@docker1:~$ docker exec web1 ip addr
…<loopback interface removed for brevity>…
83: ethwe0@if84: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UP
    link/ether 9e:b2:99:c4:ac:c4 brd ff:ff:ff:ff:ff:ff
    inet 10.32.0.1/12 scope global ethwe0
       valid_lft forever preferred_lft forever
    inet6 fe80::9cb2:99ff:fec4:acc4/64 scope link
       valid_lft forever preferred_lft forever
86: eth1@if87: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:2/64 scope link
       valid_lft forever preferred_lft forever
user@docker1:~$

However, you might note that the IP address for eth1 is not on the docker0 bridge, but rather on docker_gwbridge we saw used in earlier chapters when we showed the Docker overlay driver. The benefit of using the gateway bridge rather than the docker0 bridge is that the gateway bridge has ICC disabled by default. This prevents Weave connected containers that are supposed to be isolated from accidentally cross talking across the docker0 bridge if you had ICC mode enabled.

A downside to the plugin approach is that Weave isn't in the middle to tell Docker about the DNS-related configurations, which means that the containers aren't registering their names. Even if they were, they also aren't receiving the proper name resolution settings required to resolve WeaveDNS. There are two ways we can specify the proper settings to the container. In either case, we need to manually specify the parameters at container runtime. The first method involves manually specifying all the required parameters yourself. Manually, it's done as follows:

user@docker1:~$ docker run -dP --name=web1 
--hostname=web1.weave.local --net=weave --dns=172.17.0.1 
--dns-search=weave.local jonlangemak/web_server_1
6a907ee64c129d36e112d0199eb2184663f5cf90522ff151aa10c2a1e6320e16
user@docker1:~$

In order to register with DNS, you need the four bolded settings shown in the preceding code:

  • --hostname=web1.weave.local: If you don't set the hostname of the container to a name within weave.local, the DNS server won't register the name.
  • --net=weave: It has to be on the Weave network for any of this to work.
  • --dns=172.17.0.1: We need to tell it to use the Weave DNS server listening on the docker0 bridge IP address. However, you might have noticed that this container doesn't actually have an IP address on the docker0 bridge. Rather, since we're connected to the docker-gwbridge, we have an IP address in the 172.18.0.0/16 network. In either case, since both bridges have IP interfaces the container can route through the docker_gwbridge to get to the IP interface on the docker0 bridge.
  • --dns-search=weave.local: This allows the container to resolve names without specifying the Fully Qualified Domain Name (FQDN).

Once a container is started with these settings, you should see records registering in WeaveDNS:

user@docker1:~$ weave status dns
web1         10.32.0.1       7b02c0262786 12:d2:fe:7a:c1:f2
user@docker1:~$

The second solution is still manual but involves pulling the DNS information from Weave itself. Rather than specifying the DNS server and the search domain, you can inject it right from Weave. Weave has a command named dns-args that will return the relevant information for you. So rather than specifying it, we can simply inject that command as part of the container parameters like this:

user@docker2:~$ docker run --hostname=web2.weave.local 
--net=weave $(weave dns-args) --name=web2 -dP 
jonlangemak/web_server_2
597ffde17581b7203204594dca84c9461c83cb7a9076ed3d1ed3fcb598c2b77d
user@docker2:~$

Granted, this doesn't prevent the need to specify the network or the FQDN of the container, but it does trim down some of the typing. At this point, you should see all of the records defined in WeaveDNS and be able to access services across the Weave network by name:

user@docker1:~$ weave status dns
web1         10.32.0.1       7b02c0262786 12:d2:fe:7a:c1:f2
web2         10.32.0.2       b154e3671feb 12:d2:fe:7a:c1:f2
user@docker1:~$
user@docker2:~$ docker exec -it web2 ping web1 -c 2
PING web1 (10.32.0.1): 48 data bytes
56 bytes from 10.32.0.1: icmp_seq=0 ttl=64 time=0.139 ms
56 bytes from 10.32.0.1: icmp_seq=1 ttl=64 time=0.130 ms
--- web1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.130/0.135/0.139/0.000 ms
user@docker1:~$

You might note that these container's DNS configuration isn't exactly as you expected. For instance, the resolv.conf file does not show the DNS server we specified at container runtime:

user@docker1:~$ docker exec web1 more /etc/resolv.conf
::::::::::::::
/etc/resolv.conf
::::::::::::::
search weave.local
nameserver 127.0.0.11
options ndots:0
user@docker1:~$

However, if you inspect the container's configuration, you'll see that the correct DNS server is properly defined:

user@docker1:~$ docker inspect web1
…<Additional output removed for brevity>…
            "Dns": [
                "172.17.0.1"
            ],
…<Additional output removed for brevity>…
user@docker1:~$

Recall that user-defined networks require the use of Docker's embedded DNS system. The IP address we saw in the containers resolv.conf file references Docker's embedded DNS server. In turn, when we specify a DNS server for a container, the embedded DNS server adds that server as a forwarder in embedded DNS. This means that, although the request is still hitting the embedded DNS server first, the request is being forwarded on to WeaveDNS for resolution.

Note

The Weave plugin also allows you to create additional user-defined networks using the Weave driver. However, since Docker sees those as global in scope, they require the use of an external key store. If you're interested in using Weave in that fashion, please refer to the Weave documentation at https://www.weave.works/docs/net/latest/plugin/.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset