diff --git a/README.md b/README.md
index 93e1169b..b14f0f68 100644
--- a/README.md
+++ b/README.md
@@ -55,47 +55,41 @@ two containers, one on each host.
On `$HOST1` run
host1$ weave launch
- host1$ C=$(weave run 10.2.1.1/24 -t -i ubuntu)
+ host1$ weave launch-dns
+ host1$ weave run --name a1 -ti ubuntu
-The first line starts the weave router, in a container. This needs to
-be done once on each host. The required docker image for the weave
-router container is downloaded automatically. There is also a `weave
-setup` command for downloading this and other images required for
+The first two lines start the weave router and DNS, each inside their
+own container - this needs to be done once per host. Whilst the
+required docker images are downloaded automatically, there is also a
+`weave setup` command for downloading all the images required for
weave operation; this is a strictly optional step which is especially
useful for automated installation of weave and ensures that any
subsequent weave commands do not encounter delays due to image
downloading.
-The second line runs our application container. We give it an IP
-address and network, in
-[CIDR notation](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation).
-`weave run` invokes `docker run -d` with all the parameters following
-the IP address and network. So we could be launching any container
-this way; here we just take a stock ubuntu container and launch a
-shell in it. There's also a `weave start` command, which invokes
-`docker start` for starting existing containers.
+The third line runs our application container, allocating it an IP
+address on the weave network and registering it in DNS. `weave run`
+invokes `docker run -d` behind the scenes, so we could be launching
+any container this way; here we just take a stock ubuntu container and
+launch a shell in it. There's also a `weave start` command, which
+invokes `docker start` for starting existing containers.
If our application consists of more than one container on this host we
-simply launch them with a variation on that second line.
+simply launch them with a variation on third second line.
-The IP addresses and netmasks can be anything you like, but make sure
-they don't conflict with any IP ranges in use on the hosts or IP
-addresses of external services the hosts or containers need to connect
-to. The same IP range must be used everywhere, and the individual IP
-addresses must, of course, be unique.
-
-We repeat similar steps on `$HOST2`...
+Next we repeat similar steps on `$HOST2`...
host2$ weave launch $HOST1
- host2$ C=$(weave run 10.2.1.2/24 -t -i ubuntu)
+ host2$ weave launch-dns
+ host2$ weave run --name a2 -ti ubuntu
-The only difference, apart from the choice of IP address for the
-application container, is that we tell our weave that it should peer
-with the weave on `$HOST1` (specified as the IP address or hostname,
-and optional `:port`, by which `$HOST2` can reach it). NB: if there is
-a firewall between `$HOST1` and `$HOST2`, you must open the weave port
-(6783 by default; this can be overriden by setting `WEAVE_PORT`) for
-TCP and UDP.
+The only difference, apart from the name of the application container,
+is that we tell our weave that it should peer with the weave on
+`$HOST1` (specified as the IP address or hostname, and optional
+`:port`, by which `$HOST2` can reach it). NB: if there is a firewall
+between `$HOST1` and `$HOST2`, you must open the weave port (6783 by
+default; this can be overriden by setting `WEAVE_PORT`) for TCP and
+UDP.
Note that we could instead have told the weave on `$HOST1` to connect to
`$HOST2`, or told both about each other. Order does not matter here;
@@ -109,21 +103,21 @@ can talk to each other...
On `$HOST1`...
- host1$ docker attach $C
- root@28841bd02eff:/# ping -c 1 -q 10.2.1.2
- PING 10.2.1.2 (10.2.1.2): 48 data bytes
- --- 10.2.1.2 ping statistics ---
- 1 packets transmitted, 1 packets received, 0% packet loss
- round-trip min/avg/max/stddev = 1.048/1.048/1.048/0.000 ms
+ host1$ docker attach a1
+ root@a1:/# ping -c 1 -q a2
+ PING a2.weave.local (10.160.0.2) 56(84) bytes of data.
+ --- a2.weave.local ping statistics ---
+ 1 packets transmitted, 1 received, 0% packet loss, time 0ms
+ rtt min/avg/max/mdev = 0.341/0.341/0.341/0.000 ms
Similarly, on `$HOST2`...
- host2$ docker attach $C
- root@f76829496120:/# ping -c 1 -q 10.2.1.1
- PING 10.2.1.1 (10.2.1.1): 48 data bytes
- --- 10.2.1.1 ping statistics ---
- 1 packets transmitted, 1 packets received, 0% packet loss
- round-trip min/avg/max/stddev = 1.034/1.034/1.034/0.000 ms
+ host2$ docker attach a2
+ root@a2:/# ping -c 1 -q a1
+ PING a1.weave.local (10.128.0.2) 56(84) bytes of data.
+ --- a1.weave.local ping statistics ---
+ 1 packets transmitted, 1 received, 0% packet loss, time 0ms
+ rtt min/avg/max/mdev = 0.366/0.366/0.366/0.000 ms
So there we have it, two containers on separate hosts happily talking
to each other.
diff --git a/site/features.md b/site/features.md
index ecae8862..478968e0 100644
--- a/site/features.md
+++ b/site/features.md
@@ -9,6 +9,7 @@ Weave has a few more features beyond those illustrated by the [basic
example](https://github.com/weaveworks/weave#example):
* [Virtual ethernet switch](#virtual-ethernet-switch)
+ * [Manual addressing](#manual-addressing)
* [Application isolation](#application-isolation)
* [Dynamic network attachment](#dynamic-network-attachment)
* [Security](#security)
@@ -35,18 +36,18 @@ connected.
Containers can easily access services from each other; e.g. in the
container on `$HOST1` we can start a netcat "service" with
- root@28841bd02eff:/# nc -lk -p 4422
+ root@a1:/# nc -lk -p 4422
and then connect to it from the container on `$HOST2` with
- root@f76829496120:/# echo 'Hello, world.' | nc 10.2.1.1 4422
+ root@a2:/# echo 'Hello, world.' | nc a1 4422
Note that *any* protocol is supported. Doesn't even have to be over
TCP/IP, e.g. a netcat UDP service would be run with
- root@28841bd02eff:/# nc -lu -p 5533
+ root@a1:/# nc -lu -p 5533
- root@f76829496120:/# echo 'Hello, world.' | nc -u 10.2.1.1 5533
+ root@a2:/# echo 'Hello, world.' | nc -u a1 5533
We can deploy the entire arsenal of standard network tools and
applications, developed over decades, to configure, secure, monitor,
@@ -55,47 +56,104 @@ now re-use the same tools and techniques when deploying applications
as containers as we would have done when deploying them 'on metal' in
our data centre.
+### Manual addressing
+
+The examples so far have leveraged weave's [address allocation](#ipam)
+and [discovery](#dns) features, meaning that we've not had to concern
+ourselves with IP addresses at all. It is, however, possible to
+specify address and network explicitly using [CIDR
+notation](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation)
+- let's see how the first example would have looked:
+
+On $HOST1:
+
+ host1$ C=$(weave run 10.2.1.1/24 -ti ubuntu)
+
+And $HOST2:
+
+ host2$ C=$(weave run 10.2.1.2/24 -ti ubuntu)
+
+Then on $HOST1...
+
+ host1$ docker attach $C
+ root@28841bd02eff:/# ping -c 1 -q 10.2.1.2
+ PING 10.2.1.2 (10.2.1.2): 48 data bytes
+ --- 10.2.1.2 ping statistics ---
+ 1 packets transmitted, 1 packets received, 0% packet loss
+ round-trip min/avg/max/stddev = 1.048/1.048/1.048/0.000 ms
+
+Similarly, on $HOST2...
+
+ host2$ docker attach $C
+ root@f76829496120:/# ping -c 1 -q 10.2.1.1
+ PING 10.2.1.1 (10.2.1.1): 48 data bytes
+ --- 10.2.1.1 ping statistics ---
+ 1 packets transmitted, 1 packets received, 0% packet loss
+ round-trip min/avg/max/stddev = 1.034/1.034/1.034/0.000 ms
+
+The IP addresses and netmasks can be anything you like, but make sure
+they don't conflict with any IP ranges in use on the hosts (including
+those delegated to IPAM) or IP addresses of external services the
+hosts or containers need to connect to. The same IP range must be used
+everywhere, and the individual IP addresses must, of course, be
+unique.
+
### Application isolation
A single weave network can host multiple, isolated applications, with
each application's containers being able to communicate with each
other but not containers of other applications.
-To accomplish that, we assign each application a different subnet. So,
-in the above example, if we wanted to add another application similar
-to, but isolated from, our first, we'd launch the containers with...
+To accomplish that, we assign each application a different subnet.
+Let's begin by configuring weave's allocator to manage multiple
+subnets:
- host1$ D=$(weave run 10.2.2.1/24 -t -i ubuntu)
- host2$ D=$(weave run 10.2.2.2/24 -t -i ubuntu)
+ host1$ weave launch -iprange 10.2.0.0/16 -ipsubnet 10.2.1.0/24
+ host1$ weave launch-dns
+ host2$ weave launch -iprange 10.2.0.0/16 -ipsubnet 10.2.1.0/24 $HOST1
+ host2$ weave launch-dns
+
+This delegates the entire 10.2.0.0/16 subnet to weave, and instructs
+it to allocate from 10.2.1.0/24 within that if no specific subnet is
+specified. Now we can launch some containers in the default subnet:
+
+ host1$ weave run --name a1 -ti ubuntu
+ host2$ weave run --name a2 -ti ubuntu
+
+And some more containers in a different subnet:
+
+ host1$ weave run net:10.2.2.0/24 --name b1 -ti ubuntu
+ host2$ weave run net:10.2.2.0.24 --name b2 -ti ubuntu
A quick 'ping' test in the containers confirms that they can talk to
each other but not the containers of our first application...
- host1$ docker attach $D
-
- root@da50502598d5:/# ping -c 1 -q 10.2.2.2
- PING 10.2.2.2 (10.2.2.2): 48 data bytes
- --- 10.2.2.2 ping statistics ---
- 1 packets transmitted, 1 packets received, 0% packet loss
- round-trip min/avg/max/stddev = 0.562/0.562/0.562/0.000 ms
-
- root@da50502598d5:/# ping -c 1 -q 10.2.1.1
- PING 10.2.1.1 (10.2.1.1) 56(84) bytes of data.
- --- 10.2.1.1 ping statistics ---
+ host1:~$ docker attach b1
+
+ root@b1:/# ping -c 1 -q b2
+ PING b2.weave.local (10.2.2.128) 56(84) bytes of data.
+ --- b2.weave.local ping statistics ---
+ 1 packets transmitted, 1 received, 0% packet loss, time 0ms
+ rtt min/avg/max/mdev = 1.338/1.338/1.338/0.000 ms
+
+ root@b1:/# ping -c 1 -q a1
+ PING a1.weave.local (10.2.1.2) 56(84) bytes of data.
+ --- a1.weave.local ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
-
- root@da50502598d5:/# ping -c 1 -q 10.2.1.2
- PING 10.2.1.2 (10.2.1.2) 56(84) bytes of data.
- --- 10.2.1.2 ping statistics ---
+
+ root@b1:/# ping -c 1 -q a2
+ PING a2.weave.local (10.2.1.130) 56(84) bytes of data.
+ --- a2.weave.local ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
+
This isolation-through-subnets scheme is an example of carrying over a
well-known technique from the 'on metal' days to containers.
If desired, a container can be attached to multiple subnets when it is
started:
- host1$ weave run 10.2.2.1/24 10.2.3.1/24 -t -i ubuntu
+ host1$ weave run net:default net:10.2.2.0/24 -ti ubuntu
NB: By default docker permits communication between containers on the
same host, via their docker-assigned IP addresses. For complete
@@ -117,29 +175,29 @@ to the weave network. To illustrate, we can achieve the same effect as
the first example with
host1$ C=$(docker run -d -t -i ubuntu)
- host1$ weave attach 10.2.1.1/24 $C
+ host1$ weave attach $C
There is a matching `weave detach` command:
- host1$ weave detach 10.2.1.1/24 $C
+ host1$ weave detach $C
You can detach a container from one application network and attach it
to another:
- host1$ weave detach 10.2.1.1/24 $C
- host1$ weave attach 10.2.2.1/24 $C
+ host1$ weave detach net:default $C
+ host1$ weave attach net:10.2.2.0/24 $C
or attach a container to multiple application networks, effectively
sharing it between applications:
- host1$ weave attach 10.2.1.1/24 $C
- host1$ weave attach 10.2.2.1/24 $C
+ host1$ weave attach net:default
+ host1$ weave attach net:10.2.2.0/24
Finally, multiple addresses can be attached or detached with a single
invocation:
- host1$ weave attach 10.2.1.1/24 10.2.2.1/24 10.2.3.1/24 $C
- host1$ weave detach 10.2.1.1/24 10.2.2.1/24 10.2.3.1/24 $C
+ host1$ weave attach net:default net:10.2.2.0/24 net:10.2.3.0/24 $C
+ host1$ weave detach net:default net:10.2.2.0/24 net:10.2.3.0/24 $C
### Security
@@ -174,31 +232,38 @@ anywhere.
Let's say that in our example we want `$HOST2` to have access to the
application containers. On `$HOST2` we run
- host2$ weave expose 10.2.1.102/24
+ host2$ weave expose
-choosing an unused IP address in the application subnet. (There is a
-corresponding 'hide' command to revert this step.)
+(There is a corresponding 'hide' command to revert this step.)
-Now
+Now, after finding allocated IPs via `weave ps`
- host2$ ping 10.2.1.2
+ host2$ weave ps weave:expose
+ weave:expose 02:80:5c:02:f1:b2 10.2.1.132/24
+
+ host1$ weave ps a1
+ a1 1e:88:d7:5b:77:68 10.2.1.2/24
+
+this
+
+ host2$ ping 10.2.1.132
will work. And, more interestingly,
- host2$ ping 10.2.1.1
+ host2$ ping 10.2.1.2
will work too, which is talking to a container that resides on `$HOST1`.
Multiple subnet addresses can be exposed or hidden with a single
invocation:
- host2$ weave expose 10.2.1.102/24 10.2.2.102/24
- host2$ weave hide 10.2.1.102/24 10.2.2.102/24
+ host2$ weave expose net:default net:10.2.2.0/24
+ host2$ weave hide net:default net:10.2.2.0/24
Finally, exposed addresses can be added to weaveDNS by supplying a
fully-qualified domain name:
- host2$ weave expose 10.2.1.102/24 -h exposed.weave.local
+ host2$ weave expose -h exposed.weave.local
### Service export
@@ -213,18 +278,21 @@ a container on `$HOST1`, accessible to the outside world via `$HOST2`.
First we need to expose the application network to `$HOST2`, as
explained [above](#host-network-integration), i.e.
- host2$ weave expose 10.2.1.102/24
+ host2$ weave expose
Then we add a NAT rule to route from the outside world to the
destination container service.
+ host1$ weave ps a1
+ a1 1e:88:d7:5b:77:68 10.2.1.2/24
+
host2$ iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 2211 \
- -j DNAT --to-destination 10.2.1.1:4422
+ -j DNAT --to-destination 10.2.1.2:4422
Here we are assuming that the "outside world" is connecting to `$HOST2`
via 'eth0'. We want TCP traffic to port 2211 on the external IPs to be
routed to our 'nc' service, which is running on port 4422 in the
-container with IP 10.2.1.1.
+container a1.
With the above in place, we can connect to our 'nc' service from
anywhere with
@@ -253,12 +321,15 @@ First we need to expose the application network to the host, as
explained [above](#host-network-integration), this time on `$HOST1`,
i.e.
- host1$ weave expose 10.2.1.101/24
+ host1$ weave expose -h host1.weave.local
Then we add a NAT rule to route from the above IP to the destination
service.
- host1$ iptables -t nat -A PREROUTING -p tcp -d 10.2.1.101 --dport 3322 \
+ host1$ weave ps weave:expose
+ weave:expose 66:46:f5:ac:7b:c9 10.2.1.3/24
+
+ host1$ iptables -t nat -A PREROUTING -p tcp -d 10.2.1.3 --dport 3322 \
-j DNAT --to-destination $HOST3:2211
This allows any application container to reach the service by
@@ -269,7 +340,7 @@ service on port 2211, e.g.
then we can connect to it from our application container on `$HOST2` with
- root@f76829496120:/# echo 'Hello, world.' | nc 10.2.1.101 3322
+ root@a2:/# echo 'Hello, world.' | nc host1 3322
The same command will work from any application container.
@@ -278,7 +349,7 @@ The same command will work from any application container.
Importing a service provides a degree of indirection that allows late
and dynamic binding, similar to what can be achieved with a proxy. In
our example, application containers are unaware that the service they
-are accessing at `10.2.1.101:3322` is in fact residing on
+are accessing at `10.2.1.3:3322` is in fact residing on
`$HOST3:2211`. We can point application containers at another service
location by changing the above NAT rule, without having to alter the
applications themselves.
@@ -300,14 +371,17 @@ In our example above, the netcat service on `$HOST3` is imported into
weave via `$HOST1`. We can export it on `$HOST2` by first exposing the
application network with
- host2$ weave expose 10.2.1.102/24
+ host2$ weave expose
and then adding a NAT rule which routes traffic from the `$HOST2`
network (i.e. anything which can connect to `$HOST2`) to the service
endpoint in the weave network
+ host1$ weave ps weave:expose
+ weave:expose 66:46:f5:ac:7b:c9 10.2.1.3/24
+
host2$ iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4433 \
- -j DNAT --to-destination 10.2.1.101:3322
+ -j DNAT --to-destination 10.2.1.3:3322
Now any host on the same network as `$HOST2` can access the service with