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.
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.
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
:
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.
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/.