Merge pull request #893 from bboreham/743-default-iprange-in-script

Default value for -iprange

Closes #743. Closes #870.
This commit is contained in:
Matthias Radestock committed 2015-06-12 11:17:12 +01:00
commit 685d7d2559
8 files changed
+195 -80

No files matched your search

+2
View File
@@ -35,6 +35,7 @@ prog/weavedns/weavedns
prog/weaveproxy/weaveproxy
prog/sigproxy/sigproxy
prog/weavewait/weavewait
prog/netcheck/netcheck
tools/bin
tools/build
releases
@@ -45,6 +46,7 @@ prog/weaveexec/weave
prog/weaveexec/weaveproxy
prog/weaveexec/weavewait
prog/weaveexec/sigproxy
prog/weaveexec/netcheck
prog/weaveexec/docker*.tgz
Vagrantfile.local
test/tls/*.pem
+5 -3
View File
@@ -14,8 +14,9 @@ WEAVEDNS_EXE=prog/weavedns/weavedns
WEAVEPROXY_EXE=prog/weaveproxy/weaveproxy
SIGPROXY_EXE=prog/sigproxy/sigproxy
WEAVEWAIT_EXE=prog/weavewait/weavewait
NETCHECK_EXE=prog/netcheck/netcheck
EXES=$(WEAVER_EXE) $(WEAVEDNS_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE)
EXES=$(WEAVER_EXE) $(WEAVEDNS_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(NETCHECK_EXE)
WEAVER_IMAGE=$(DOCKERHUB_USER)/weave
WEAVEDNS_IMAGE=$(DOCKERHUB_USER)/weavedns
@@ -40,7 +41,7 @@ travis: $(EXES)
update: $(EXES)
go get -u -f -v -tags -netgo $(addprefix ./,$(dir $(EXES)))
$(WEAVER_EXE) $(WEAVEDNS_EXE) $(WEAVEPROXY_EXE): common/*.go common/*/*.go net/*.go
$(WEAVER_EXE) $(WEAVEDNS_EXE) $(WEAVEPROXY_EXE) $(NETCHECK_EXE): common/*.go common/*/*.go net/*.go
go get -tags netgo ./$(@D)
go build -ldflags "-extldflags \"-static\" -X main.version $(WEAVE_VERSION)" -tags netgo -o $@ ./$(@D)
@strings $@ | grep cgo_stub\\\.go >/dev/null || { \
@@ -73,11 +74,12 @@ $(WEAVEDNS_EXPORT): prog/weavedns/Dockerfile $(WEAVEDNS_EXE)
$(SUDO) docker build -t $(WEAVEDNS_IMAGE) prog/weavedns
$(SUDO) docker save $(WEAVEDNS_IMAGE):latest > $@
$(WEAVEEXEC_EXPORT): prog/weaveexec/Dockerfile $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE)
$(WEAVEEXEC_EXPORT): prog/weaveexec/Dockerfile $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(NETCHECK_EXE)
cp weave prog/weaveexec/weave
cp $(SIGPROXY_EXE) prog/weaveexec/sigproxy
cp $(WEAVEPROXY_EXE) prog/weaveexec/weaveproxy
cp $(WEAVEWAIT_EXE) prog/weaveexec/weavewait
cp $(NETCHECK_EXE) prog/weaveexec/netcheck
cp $(DOCKER_DISTRIB) prog/weaveexec/docker.tgz
$(SUDO) docker build -t $(WEAVEEXEC_IMAGE) prog/weaveexec
$(SUDO) docker save $(WEAVEEXEC_IMAGE):latest > $@
+28
View File
@@ -0,0 +1,28 @@
package net
import (
"fmt"
"net"
"github.com/vishvananda/netlink"
)
// A network is considered free if it does not overlap any existing
// routes on this host. This is the same approach taken by Docker.
func CheckNetworkFree(subnet *net.IPNet) error {
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return err
}
for _, route := range routes {
if route.Dst != nil && overlaps(route.Dst, subnet) {
return fmt.Errorf("network %s would overlap with route %s", subnet, route.Dst)
}
}
return nil
}
// Two networks overlap if the start-point of one is inside the other.
func overlaps(n1, n2 *net.IPNet) bool {
return n1.Contains(n2.IP) || n2.Contains(n1.IP)
}
+25
View File
@@ -0,0 +1,25 @@
package net
import (
"net"
"testing"
wt "github.com/weaveworks/weave/testing"
)
func TestOverlap(t *testing.T) {
_, subnet1, _ := net.ParseCIDR("10.0.3.0/24")
_, subnet2, _ := net.ParseCIDR("10.0.4.0/24")
_, subnet3, _ := net.ParseCIDR("10.0.3.128/25")
_, subnet4, _ := net.ParseCIDR("10.0.3.192/25")
_, universe, _ := net.ParseCIDR("10.0.0.0/8")
wt.AssertEquals(t, overlaps(subnet1, subnet2), false)
wt.AssertEquals(t, overlaps(subnet2, subnet1), false)
wt.AssertEquals(t, overlaps(subnet1, subnet1), true)
wt.AssertEquals(t, overlaps(subnet1, subnet3), true)
wt.AssertEquals(t, overlaps(subnet1, subnet4), true)
wt.AssertEquals(t, overlaps(subnet2, subnet4), false)
wt.AssertEquals(t, overlaps(subnet4, subnet2), false)
wt.AssertEquals(t, overlaps(universe, subnet1), true)
wt.AssertEquals(t, overlaps(subnet1, universe), true)
}
+31
View File
@@ -0,0 +1,31 @@
/* netcheck: check whether a given network overlaps with any existing routes */
package main
import (
"fmt"
"net"
"os"
weavenet "github.com/weaveworks/weave/net"
)
func fatal(err error) {
fmt.Println(err)
os.Exit(1)
}
func main() {
if len(os.Args) <= 1 {
os.Exit(0)
}
ipRangeStr := os.Args[1]
_, ipnet, err := net.ParseCIDR(ipRangeStr)
if err != nil {
fatal(err)
}
if err := weavenet.CheckNetworkFree(ipnet); err != nil {
fatal(err)
}
os.Exit(0)
}
+1
View File
@@ -16,6 +16,7 @@ WORKDIR /home/weave
ADD ./weave /home/weave/
ADD ./sigproxy /home/weave/
ADD ./weaveproxy /home/weave/
ADD ./netcheck /usr/bin/
ADD ./weavewait /w/w
ADD ./docker.tgz /
+95 -77
View File
@@ -5,14 +5,9 @@ layout: default
# Automatic IP Address Management
Weave can automatically assign unique IP addresses to each container
across the network. To make this work, weave must be told on startup
what range of addresses to allocate from, for example:
host1# weave launch -iprange 10.2.0.0/16
The `run`, `start`, `attach`, `detach`, `expose` and `hide` commands
will then fetch an address automatically if none is specified, i.e.:
Weave can automatically assign containers an IP address that is unique
across the network. This is triggered by running containers without
specifying an address, e.g.
host1# C=$(weave run -ti ubuntu)
@@ -20,74 +15,22 @@ You can see which address was allocated with
[`weave ps`](troubleshooting.html#list-attached-containers):
host1# weave ps $C
a7aff7249393 7a:51:d1:09:21:78 10.2.3.1/24
a7aff7249393 7a:51:d1:09:21:78 10.128.0.1/9
You may wish to [run containers on different
subnets](features.html#application-isolation). To set a default
subnet, launch with `-ipsubnet`:
Weave detects when a container has exited and releases its
automatically allocated addresses so they can be re-used.
host1# weave launch -iprange 10.2.0.0/16 -ipsubnet 10.2.3.0/24
`-iprange` should cover the entire range that you will ever use for
allocation, and `-ipsubnet` is the subnet that will be used when
you don't explicitly specify one.
Then, to request the allocation of an address from a subnet other than
the default, use the `net:` prefix:
host1# C=$(weave run net:10.2.7.0/24 -ti ubuntu)
To explicitly request the default subnet, use `net:default`.
And, you can ask for multiple addresses in different subnets and add
in manually-assigned addresses on the same line, for instance:
host1# C=$(weave run net:10.2.7.0/24 net:10.2.8.0/24 ip:10.3.9.1/24 -ti ubuntu)
Note that `-iprange` can be smaller than `-ipsubnet`, if you want to
use a mixture of automatically-allocated addresses and manually-chosen
addresses, and have the containers communicate with each other. For
example, if you say:
host1# weave launch -iprange 10.9.0.0/17 -ipsubnet 10.9.0.0/16
then you can run all containers in the 10.9.0.0/16 subnet, with IPAM
using the lower half and leaving the upper half free for manual
allocation.
The subnet parameters are written in [CIDR
notation](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing)
format - in this example "/24" means the first 24 bits of the address
form the network address and the allocator is to allocate container
addresses that all start 10.2.3. The ".0" and ".-1" addresses in a
subnet are not used, as required by [RFC
1122](https://tools.ietf.org/html/rfc1122#page-29).
Once you have given a range of addresses to the IP allocator, you must
not use any addresses in that range for anything else. If, in our
example, you subsequently did `weave run 10.2.3.x/24`, you run the
risk that that address will be allocated to another container, which
will make network traffic delivery intermittent or non-existent for
the containers that share the same IP address. No diagnostic message
is output by weave if you break this rule.
Weave will automatically learn when a container has exited
and hence can release its IP address.
Weave shares the IP range across all peers, dynamically according to
their needs. If a group of peers becomes isolated from the rest (a
partition), they can continue to work with the IP ranges they had
before isolation, and can be re-connected to the rest of the network
and carry on. Note that you must specify the same range with
`-iprange` on each host, and you cannot mix weaves started with and
without -iprange.
Automatic IP address assignment is available for the `run`, `start`,
`attach`, `detach`, `expose` and `hide` commands.
### Initialisation
Just once, when you start up the whole network, weave needs a majority
of peers to agree in order to avoid isolated groups starting off
inconsistently. Therefore, you must either supply the list of all
peers in the network to `weave launch` or add the `-initpeercount`
Just once, when the first automatic IP address allocation is requested
in the whole network, weave needs a majority of peers to be present in
order to avoid formation of isolated groups, which could lead to
inconsistency, i.e. the same IP address being allocated to two
different containers. Therefore, you must either supply the list of
all peers in the network to `weave launch` or add the `-initpeercount`
flag to specify how many peers there will be. It isn't a problem to
over-estimate by a bit, but if you supply a number that is too small
then multiple independent groups may form.
@@ -96,20 +39,95 @@ To illustrate, suppose you have three hosts, accessible to each other
as `$HOST1`, `$HOST2` and `$HOST3`. You can start weave on those three
hosts with these three commands:
host1$ weave launch -iprange 10.3.0.0/16 $HOST2 $HOST3
host1$ weave launch $HOST2 $HOST3
host2$ weave launch -iprange 10.3.0.0/16 $HOST1 $HOST3
host2$ weave launch $HOST1 $HOST3
host3$ weave launch -iprange 10.3.0.0/16 $HOST1 $HOST2
host3$ weave launch $HOST1 $HOST2
Or, if it is not convenient to name all the other hosts at launch
time, you can give the number of peers like this:
host1$ weave launch -iprange 10.3.0.0/16 -initpeercount 3
host1$ weave launch -initpeercount 3
host2$ weave launch -iprange 10.3.0.0/16 -initpeercount 3 $HOST3
host2$ weave launch -initpeercount 3 $HOST3
host3$ weave launch -iprange 10.3.0.0/16 -initpeercount 3 $HOST2
host3$ weave launch -initpeercount 3 $HOST2
### Choosing the IP address allocation range
By default, weave will allocate IP addresses in the 10.128.0.0/9
range. This can be overridden with the `-iprange` option, e.g.
host1# weave launch -iprange 10.2.0.0/16
and must be the same on every host.
The range parameter is written in
[CIDR notation](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) -
in this example "/16" means the first 16 bits of the address form the
network address and the allocator is to allocate container addresses
that all start 10.2. The ".0" and ".-1" addresses in a subnet are not
used, as required by
[RFC 1122](https://tools.ietf.org/html/rfc1122#page-29).
Weave shares the IP address range across all peers, dynamically
according to their needs. If a group of peers becomes isolated from
the rest (a partition), they can continue to work with the address
ranges they had before isolation, and can subsequently be re-connected
to the rest of the network without any conflicts arising.
Once you have given a range of addresses to the IP allocator, you must
not use any addresses in that range for anything else. If, in our
example, you subsequently executed `weave run 10.2.3.1/24 -ti ubuntu`,
you run the risk that the IP allocator will assign the same address to
another container, which will make network traffic delivery
intermittent or non-existent for the containers that share the same IP
address.
### Automatic allocation across multiple subnets
When
[running containers on different subnets](features.html#application-isolation),
you may wish to request the allocation of an address from a particular
subnet. This is done by specifying the subnet with `net:<subnet>`, in
CIDR notation, e.g.
host1# C=$(weave run net:10.2.7.0/24 -ti ubuntu)
You can ask for multiple addresses in different subnets and add in
manually-assigned addresses (outside the automatic allocation range),
for instance:
host1# C=$(weave run net:10.2.7.0/24 net:10.2.8.0/24 ip:10.3.9.1/24 -ti ubuntu)
When working with multiple subnets in this way, it is usually
desirable to constrain the default subnet - i.e. the one chosen by the
allocator when no subnet is supplied - so that it does not overlap
with others. One can specify that with `-ipsubnet`:
host1# weave launch -iprange 10.2.0.0/16 -ipsubnet 10.2.3.0/24
`-iprange` should cover the entire range that you will ever use for
allocation, and `-ipsubnet` is the subnet that will be used when you
don't explicitly specify one.
When specifying addresses, the default subnet can be denoted
symbolically with `net:default`.
### Mixing automatic and manual allocation in the same subnet
If you want to start containers with a mixture of
automatically-allocated addresses and manually-chosen addresses, and
have the containers communicate with each other, you can choose a
`-iprange` that is smaller than `-ipsubnet`, For example, if you
launch weave with:
host1# weave launch -iprange 10.9.0.0/17 -ipsubnet 10.9.0.0/16
then you can run all containers in the 10.9.0.0/16 subnet, with
automatic allocation using the lower half, leaving the upper half free
for manual allocation.
### Stopping and removing peers
+8
View File
@@ -984,6 +984,14 @@ case "$COMMAND" in
esac
done
eval "set -- $ARGS"
if [ -z "$IPRANGE" ] ; then
IPRANGE="-iprange 10.128.0.0/9"
if command_exists netcheck && ! netcheck ${IPRANGE#* } ; then
echo "Default" $IPRANGE "overlaps with existing route." >&2
echo "Please pick another range and set it on all hosts." >&2
exit 1
fi
fi
# Set WEAVE_DOCKER_ARGS in the environment in order to supply
# additional parameters, such as resource limits, to docker
# when launching the weave container.