Merge pull request #893 from bboreham/743-default-iprange-in-script
Default value for -iprange Closes #743. Closes #870.
This commit is contained in:
commit
685d7d2559
8 files changed
+195
-80
No files matched your search
@@ -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
|
||||
@@ -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 > $@
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user