From 1fac9952481cd3ee0bb288b4189a9220ab243361 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sat, 13 Sep 2014 07:51:06 +0100 Subject: [PATCH 01/11] work around 'docker rm -f' weirdness I've been seeing ~# docker rm -f weave Error response from daemon: Cannot destroy container weave: Driver devicemapper failed to remove root filesystem 29e46c3e400ee3c8654f2b06a0f6d97bde98dfeb9bb61d25195dba38c04324fc: Device is Busy whereas the corresponding two-step 'docker kill' + 'docker rm' works fine. --- weaver/weave | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/weaver/weave b/weaver/weave index 5dab5d9b..503144aa 100755 --- a/weaver/weave +++ b/weaver/weave @@ -152,9 +152,10 @@ case "$COMMAND" in exit 0 ;; stop) - if ! docker rm -f weave >/dev/null 2>&1 ; then + if ! docker kill weave >/dev/null 2>&1 ; then echo "Weave is not running." fi + docker rm -f weave >/dev/null 2>&1 || true if command_exists conntrack then conntrack -D -p udp --dport 6783 >/dev/null 2>&1 From a53c817b8d0f33d2d78b5cfea651d8e6a959712e Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sat, 13 Sep 2014 17:44:29 +0100 Subject: [PATCH 02/11] create bridge in 'weave expose/hide' since they really need the bridge --- weaver/weave | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weaver/weave b/weaver/weave index 503144aa..f4f87fe9 100755 --- a/weaver/weave +++ b/weaver/weave @@ -135,6 +135,7 @@ case "$COMMAND" in [ $# -gt 0 ] || usage IPADDR=$1 shift 1 + create_bridge if ! ip addr list dev $BRIDGE | grep -qF $IPADDR then ip addr add dev $BRIDGE $IPADDR @@ -145,6 +146,7 @@ case "$COMMAND" in [ $# -gt 0 ] || usage IPADDR=$1 shift 1 + create_bridge if ip addr list dev $BRIDGE | grep -qF $IPADDR then ip addr del dev $BRIDGE $IPADDR From b4791be4f44629996d656a0894216096ba9da82d Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sat, 13 Sep 2014 19:47:38 +0100 Subject: [PATCH 03/11] refactor: extract command checking helper --- weaver/weave | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/weaver/weave b/weaver/weave index f4f87fe9..24f8c1ed 100755 --- a/weaver/weave +++ b/weaver/weave @@ -33,6 +33,16 @@ COMMAND=$1 shift 1 +check_command_and_run() { + if command_exists $1 + then + shift 1 + "$@" + else + echo "Cannot find $1; please install it. Continuing without it." >&2 + fi +} + create_bridge() { [ ! -d /sys/class/net/$BRIDGE ] && { ip link add dev $BRIDGE type bridge @@ -158,12 +168,7 @@ case "$COMMAND" in echo "Weave is not running." fi docker rm -f weave >/dev/null 2>&1 || true - if command_exists conntrack - then - conntrack -D -p udp --dport 6783 >/dev/null 2>&1 - else - echo "Cannot find conntrack; please install it. Continuing without it." >&2 - fi + check_command_and_run conntrack conntrack -D -p udp --dport 6783 >/dev/null 2>&1 exit 0 ;; *) @@ -200,11 +205,6 @@ ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME ip netns exec $NSPID ip addr add $IPADDR dev $CONTAINER_IFNAME ip netns exec $NSPID ip link set $CONTAINER_IFNAME up -if command_exists ethtool -then - ip netns exec $NSPID ethtool -K $IFACE tx off >/dev/null -else - echo "Cannot find ethtool; please install it. Continuing without it." >&2 -fi +check_command_and_run ethtool ip netns exec $NSPID ethtool -K $IFACE tx off >/dev/null [ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID From 6eb7e1aa437df512cf8d891d0044d1acfd7266b0 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sat, 13 Sep 2014 19:58:54 +0100 Subject: [PATCH 04/11] disable offloading on weave bridge since w/o it the kernel just ignores the PMTU when the host talks to weave via 'weave expose' Fixes #52 --- weaver/weave | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weaver/weave b/weaver/weave index 24f8c1ed..14ca46d3 100755 --- a/weaver/weave +++ b/weaver/weave @@ -54,6 +54,8 @@ create_bridge() { ip link add name v${CONTAINER_IFNAME}du mtu $MTU type dummy ip link set dev v${CONTAINER_IFNAME}du master $BRIDGE ip link del dev v${CONTAINER_IFNAME}du + # disable offloading + check_command_and_run ethtool ethtool -K $BRIDGE tx off >/dev/null } ip link set dev $BRIDGE up } From c845ba7872d3ffd931ffc073a4ec22c9fc490108 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sat, 13 Sep 2014 20:48:49 +0100 Subject: [PATCH 05/11] remove detritus we haven't depended on pipework for a while --- weaver/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaver/Makefile b/weaver/Makefile index 7c0ea882..e4f6cbd7 100644 --- a/weaver/Makefile +++ b/weaver/Makefile @@ -15,4 +15,4 @@ docker-image: /tmp/weave.tar clean: -sudo docker rmi zettio/weave - rm -f weaver pipework /tmp/weave.tar + rm -f weaver /tmp/weave.tar From 948312f03d16172bcbee185eb7b6c0051d84ce04 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sat, 13 Sep 2014 21:45:42 +0100 Subject: [PATCH 06/11] refactor: extract container network configuration and use more function parameters in preference to global vars --- weaver/weave | 78 +++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/weaver/weave b/weaver/weave index 14ca46d3..87c6c4c8 100755 --- a/weaver/weave +++ b/weaver/weave @@ -76,8 +76,40 @@ add_nat_rule() { } setup_masquerading() { - add_nat_rule "POSTROUTING -o $BRIDGE ! -s $IPADDR -j MASQUERADE" - add_nat_rule "POSTROUTING -s $IPADDR ! -o $BRIDGE -j MASQUERADE" + add_nat_rule "POSTROUTING -o $BRIDGE ! -s $1 -j MASQUERADE" + add_nat_rule "POSTROUTING -s $1 ! -o $BRIDGE -j MASQUERADE" +} + +# the following borrows from https://github.com/jpetazzo/pipework +configure_container_networking() { + DOCKERPID=$(docker inspect --format='{{ .State.Pid }}' $1) + [ "$DOCKERPID" = 0 ] && { + echo "Docker inspect returned invalid PID 0" + exit 1 + } + [ "$DOCKERPID" = "" ] && { + echo "Container $1 unknown to Docker." + exit 1 + } + NSPID=$DOCKERPID + + [ ! -d /var/run/netns ] && mkdir -p /var/run/netns + [ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID + ln -s /proc/$NSPID/ns/net /var/run/netns/$NSPID + + LOCAL_IFNAME="v${CONTAINER_IFNAME}pl${NSPID}" + GUEST_IFNAME="v${CONTAINER_IFNAME}pg${NSPID}" + ip link add name $LOCAL_IFNAME mtu $MTU type veth peer name $GUEST_IFNAME mtu $MTU + ip link set $LOCAL_IFNAME master $BRIDGE + ip link set $LOCAL_IFNAME up + ip link set $GUEST_IFNAME netns $NSPID + ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME + ip netns exec $NSPID ip addr add $2 dev $CONTAINER_IFNAME + ip netns exec $NSPID ip link set $CONTAINER_IFNAME up + + check_command_and_run ethtool ip netns exec $NSPID ethtool -K $3 tx off >/dev/null + + [ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID } case "$COMMAND" in @@ -86,7 +118,7 @@ case "$COMMAND" in IPADDR=$1 shift 1 create_bridge - setup_masquerading + setup_masquerading $IPADDR # We set the router name to the bridge mac since that is # stable across re-creations of the containers. # @@ -112,8 +144,8 @@ case "$COMMAND" in ;; esac CONTAINER=$(docker run --privileged -d --name=weave -p 6783:6783/tcp -p 6783:6783/udp $WEAVE_DOCKER_ARGS zettio/weave -name $MACADDR "$@") + configure_container_networking $CONTAINER $IPADDR eth0 echo $CONTAINER - IFACE=eth0 ;; status) if ! DOCKERIP=$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' weave 2>/dev/null) ; then @@ -132,7 +164,6 @@ case "$COMMAND" in echo "Cannot find wget or curl. Install one of them for 'weave status' to function." >&2 exit 1 fi - exit 0 ;; run) [ $# -gt 0 ] || usage @@ -140,8 +171,8 @@ case "$COMMAND" in shift 1 create_bridge CONTAINER=$(docker run -d "$@") + configure_container_networking $CONTAINER $IPADDR $CONTAINER_IFNAME echo $CONTAINER - IFACE=$CONTAINER_IFNAME ;; expose) [ $# -gt 0 ] || usage @@ -152,7 +183,6 @@ case "$COMMAND" in then ip addr add dev $BRIDGE $IPADDR fi - exit 0 ;; hide) [ $# -gt 0 ] || usage @@ -163,7 +193,6 @@ case "$COMMAND" in then ip addr del dev $BRIDGE $IPADDR fi - exit 0 ;; stop) if ! docker kill weave >/dev/null 2>&1 ; then @@ -171,42 +200,9 @@ case "$COMMAND" in fi docker rm -f weave >/dev/null 2>&1 || true check_command_and_run conntrack conntrack -D -p udp --dport 6783 >/dev/null 2>&1 - exit 0 ;; *) echo "Unknown weave command '$COMMAND'" usage ;; esac - -# the following borrows from https://github.com/jpetazzo/pipework - -DOCKERPID=$(docker inspect --format='{{ .State.Pid }}' $CONTAINER) -[ "$DOCKERPID" = 0 ] && { - echo "Docker inspect returned invalid PID 0" - exit 1 -} -[ "$DOCKERPID" = "" ] && { - echo "Container $CONTAINER unknown to Docker." - exit 1 -} - -NSPID=$DOCKERPID - -[ ! -d /var/run/netns ] && mkdir -p /var/run/netns -[ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID -ln -s /proc/$NSPID/ns/net /var/run/netns/$NSPID - -LOCAL_IFNAME="v${CONTAINER_IFNAME}pl${NSPID}" -GUEST_IFNAME="v${CONTAINER_IFNAME}pg${NSPID}" -ip link add name $LOCAL_IFNAME mtu $MTU type veth peer name $GUEST_IFNAME mtu $MTU -ip link set $LOCAL_IFNAME master $BRIDGE -ip link set $LOCAL_IFNAME up -ip link set $GUEST_IFNAME netns $NSPID -ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME -ip netns exec $NSPID ip addr add $IPADDR dev $CONTAINER_IFNAME -ip netns exec $NSPID ip link set $CONTAINER_IFNAME up - -check_command_and_run ethtool ip netns exec $NSPID ethtool -K $IFACE tx off >/dev/null - -[ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID From 4c939916511e84a06828c2484c64bb508cc3bc3c Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sun, 14 Sep 2014 19:08:00 +0100 Subject: [PATCH 07/11] ignore conntrack result in 'weave stop' so we exit with status 0, since not having any existing flows is perfectly normal --- weaver/weave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaver/weave b/weaver/weave index 87c6c4c8..62e11d22 100755 --- a/weaver/weave +++ b/weaver/weave @@ -199,7 +199,7 @@ case "$COMMAND" in echo "Weave is not running." fi docker rm -f weave >/dev/null 2>&1 || true - check_command_and_run conntrack conntrack -D -p udp --dport 6783 >/dev/null 2>&1 + check_command_and_run conntrack conntrack -D -p udp --dport 6783 >/dev/null 2>&1 || true ;; *) echo "Unknown weave command '$COMMAND'" From f10c460f48eb6181a7a3133e635b5db013436f6d Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Sun, 14 Sep 2014 19:31:27 +0100 Subject: [PATCH 08/11] leave networking alone on 'weave launch' unless we start container --- weaver/weave | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/weaver/weave b/weaver/weave index 62e11d22..33f7d83e 100755 --- a/weaver/weave +++ b/weaver/weave @@ -117,15 +117,6 @@ case "$COMMAND" in [ $# -gt 0 ] || usage IPADDR=$1 shift 1 - create_bridge - setup_masquerading $IPADDR - # We set the router name to the bridge mac since that is - # stable across re-creations of the containers. - # - # TODO use the mac of one of the physical host interfaces - # (eth0, wlan0, etc) so the name becomes stable across host - # restarts. - MACADDR=`cat /sys/class/net/$BRIDGE/address` case $(docker inspect --format '{{ .State.Running }} {{ .Config.Image }}' weave 2>/dev/null) in "true zettio/weave") echo "Weave is already running." >&2 @@ -143,6 +134,15 @@ case "$COMMAND" in exit 1 ;; esac + create_bridge + setup_masquerading $IPADDR + # We set the router name to the bridge mac since that is + # stable across re-creations of the containers. + # + # TODO use the mac of one of the physical host interfaces + # (eth0, wlan0, etc) so the name becomes stable across host + # restarts. + MACADDR=`cat /sys/class/net/$BRIDGE/address` CONTAINER=$(docker run --privileged -d --name=weave -p 6783:6783/tcp -p 6783:6783/udp $WEAVE_DOCKER_ARGS zettio/weave -name $MACADDR "$@") configure_container_networking $CONTAINER $IPADDR eth0 echo $CONTAINER From 2f1359ae9fa78e5390cd8274c511624d012821f7 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Mon, 15 Sep 2014 11:34:57 +0100 Subject: [PATCH 09/11] remove masquerading rules on 'weave stop/launch' Leaving iptable masquerading rules behind is a bad idea when weave is re-launched with different ip subnet settings. So now we remove the rules on 'weave stop' and also on 'weave launch' (in case weave had been stopped in ways other than 'weave stop'). To make the rule removal easier, we create the rules in a user-defined WEAVE chain. Note that this will break old weave installations, since the rules created by those are left behind. Easiest upgrade path is to restart the machine. Or, for the brave, run `iptables -t nat -S POSTROUTING | grep weave | sed 's/^\-A/-D/g' | while read line; do iptables -t nat $line; done`. Fixes #48 --- weaver/weave | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/weaver/weave b/weaver/weave index 33f7d83e..4a954777 100755 --- a/weaver/weave +++ b/weaver/weave @@ -60,7 +60,7 @@ create_bridge() { ip link set dev $BRIDGE up } -add_nat_rule() { +run_iptables() { # -w is recent addition to iptables if [ -z "$CHECKED_IPTABLES_W" ] ; then if iptables -S -w >/dev/null 2>&1 ; then @@ -69,15 +69,28 @@ add_nat_rule() { CHECKED_IPTABLES_W=1 fi - if ! iptables $IPTABLES_W -t nat -C $1 >/dev/null 2>&1 + iptables $IPTABLES_W "$@" +} + +add_nat_rule() { + if ! run_iptables -t nat -C "$@" >/dev/null 2>&1 then - iptables $IPTABLES_W -t nat -A $1 >/dev/null + run_iptables -t nat -A "$@" >/dev/null fi } setup_masquerading() { - add_nat_rule "POSTROUTING -o $BRIDGE ! -s $1 -j MASQUERADE" - add_nat_rule "POSTROUTING -s $1 ! -o $BRIDGE -j MASQUERADE" + if ! run_iptables -t nat -S WEAVE >/dev/null 2>&1 + then + run_iptables -t nat -N WEAVE + add_nat_rule POSTROUTING -j WEAVE + fi + add_nat_rule WEAVE -o $BRIDGE ! -s $1 -j MASQUERADE + add_nat_rule WEAVE -s $1 ! -o $BRIDGE -j MASQUERADE +} + +stop_masquerading() { + run_iptables -t nat -F WEAVE >/dev/null 2>&1 || true } # the following borrows from https://github.com/jpetazzo/pipework @@ -135,6 +148,7 @@ case "$COMMAND" in ;; esac create_bridge + stop_masquerading setup_masquerading $IPADDR # We set the router name to the bridge mac since that is # stable across re-creations of the containers. @@ -200,6 +214,7 @@ case "$COMMAND" in fi docker rm -f weave >/dev/null 2>&1 || true check_command_and_run conntrack conntrack -D -p udp --dport 6783 >/dev/null 2>&1 || true + stop_masquerading ;; *) echo "Unknown weave command '$COMMAND'" From 8297fef53d83a95112a688ed0c08dee6f9e667b4 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Mon, 15 Sep 2014 12:03:29 +0100 Subject: [PATCH 10/11] remove WEAVE iptable chain on 'weave stop' No point keeping it around. Also, simplify idempotence of masquerading setup. Follow-up to issue #48. --- weaver/weave | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/weaver/weave b/weaver/weave index 4a954777..ca40708d 100755 --- a/weaver/weave +++ b/weaver/weave @@ -80,17 +80,16 @@ add_nat_rule() { } setup_masquerading() { - if ! run_iptables -t nat -S WEAVE >/dev/null 2>&1 - then - run_iptables -t nat -N WEAVE - add_nat_rule POSTROUTING -j WEAVE - fi + run_iptables -t nat -N WEAVE >/dev/null 2>&1 || true + add_nat_rule POSTROUTING -j WEAVE add_nat_rule WEAVE -o $BRIDGE ! -s $1 -j MASQUERADE add_nat_rule WEAVE -s $1 ! -o $BRIDGE -j MASQUERADE } stop_masquerading() { run_iptables -t nat -F WEAVE >/dev/null 2>&1 || true + run_iptables -t nat -D POSTROUTING -j WEAVE >/dev/null 2>&1 || true + run_iptables -t nat -X WEAVE >/dev/null 2>&1 || true } # the following borrows from https://github.com/jpetazzo/pipework From d2bd78435e512577f8a5d653c105aa82817808a9 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Mon, 15 Sep 2014 12:43:58 +0100 Subject: [PATCH 11/11] add 'weave reset' Closes #20. --- README.md | 18 ++++++++++++++++++ weaver/weave | 14 ++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/README.md b/README.md index 3cf56309..7d661868 100644 --- a/README.md +++ b/README.md @@ -363,6 +363,24 @@ One can ask a weave router to report its status with weave status +To stop weave, run + + weave stop + +Note that this leaves the local application container network intact; +containers on the local host can continue to communicate, whereas +communication with containers on different hosts, as well as service +export/import, is disrupted but resumes when weave is relaunched. + +To stop weave and completely remove all traces of the weave network on +the local host, run + + weave reset + +Any running application containers will permanently lose connectivity +with the weave network and have to be restarted in order to +re-connect. + ## Installation with Boot2Docker If you are running Docker inside the Boot2Docker VM, e.g. because you diff --git a/weaver/weave b/weaver/weave index ca40708d..189be878 100755 --- a/weaver/weave +++ b/weaver/weave @@ -9,6 +9,7 @@ usage() { echo "weave hide /" echo "weave status" echo "weave stop" + echo "weave reset" exit 1 } @@ -60,6 +61,12 @@ create_bridge() { ip link set dev $BRIDGE up } +destroy_bridge() { + if [ -d /sys/class/net/$BRIDGE ] ; then + ip link del dev $BRIDGE + fi +} + run_iptables() { # -w is recent addition to iptables if [ -z "$CHECKED_IPTABLES_W" ] ; then @@ -215,6 +222,13 @@ case "$COMMAND" in check_command_and_run conntrack conntrack -D -p udp --dport 6783 >/dev/null 2>&1 || true stop_masquerading ;; + reset) + docker kill weave >/dev/null 2>&1 || true + docker rm -f weave >/dev/null 2>&1 || true + check_command_and_run conntrack conntrack -D -p udp --dport 6783 >/dev/null 2>&1 || true + stop_masquerading + destroy_bridge + ;; *) echo "Unknown weave command '$COMMAND'" usage