Merge pull request #498 from awh/467_multi_cidr_launch
Allow multiple CIDR arguments to run/start/attach/detach/expose/hide Closes #467.
This commit is contained in:
commit
254b837a92
3 files changed
+212
-68
No files matched your search
@@ -90,6 +90,11 @@ each other but not the containers of our first application...
|
||||
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
|
||||
|
||||
NB: By default docker permits communication between containers on the
|
||||
same host, via their docker-assigned IP addresses. For complete
|
||||
isolation between application containers, that feature needs to be
|
||||
@@ -128,6 +133,12 @@ sharing it between applications:
|
||||
host1# weave attach 10.2.1.1/24 $C
|
||||
host1# weave attach 10.2.2.1/24 $C
|
||||
|
||||
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
|
||||
|
||||
### <a name="security"></a>Security
|
||||
|
||||
In order to connect containers across untrusted networks, weave peers
|
||||
@@ -173,6 +184,12 @@ will work. And, more interestingly,
|
||||
|
||||
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
|
||||
|
||||
### <a name="service-export"></a>Service export
|
||||
|
||||
Services running in containers on a weave network can be made
|
||||
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
#! /bin/bash
|
||||
|
||||
. ./config.sh
|
||||
|
||||
start_suite "Weave run/start/attach/detach with multiple cidr arguments"
|
||||
|
||||
# Cleanup from previous run
|
||||
weave_on $HOST1 stop || true
|
||||
weave_on $HOST1 stop-dns || true
|
||||
docker_on $HOST1 rm -f multicidr || true
|
||||
|
||||
weave_on $HOST1 launch
|
||||
weave_on $HOST1 launch-dns 10.254.254.254/24
|
||||
|
||||
# weave_status_on <host>
|
||||
weave_status_on() {
|
||||
HOST=$1; shift
|
||||
|
||||
DOCKER_HOST=tcp://$HOST:2375 $WEAVE status
|
||||
}
|
||||
|
||||
# weave_ps_on <host>
|
||||
weave_ps_on() {
|
||||
HOST=$1; shift
|
||||
|
||||
DOCKER_HOST=tcp://$HOST:2375 $WEAVE ps
|
||||
}
|
||||
|
||||
# assert_container_cidrs <host> <cid> <cidr> [<cidr> ...]
|
||||
assert_container_cidrs() {
|
||||
HOST=$1; shift
|
||||
CID=$1; shift
|
||||
CIDRS=$@
|
||||
|
||||
# Assert container has attached CIDRs
|
||||
assert_raises "weave_ps_on $HOST | grep \"^$CID [^ ]* $CIDRS$\""
|
||||
}
|
||||
|
||||
# assert_zone_records <host> <cid> <fqdn> <ip> [<ip> ...]
|
||||
assert_zone_records() {
|
||||
HOST=$1; shift
|
||||
CID=$1; shift
|
||||
FQDN=$1; shift
|
||||
|
||||
# Assert correct number of records exist
|
||||
assert "weave_status_on $HOST | grep \"^$CID\" | wc -l" $#
|
||||
|
||||
# Assert correct records exist
|
||||
for IP in $@; do
|
||||
assert_raises "weave_status_on $HOST | grep \"^$CID $IP $FQDN$\""
|
||||
done
|
||||
}
|
||||
|
||||
# assert_bridge_cidrs <host> <dev> <cidr> [<cidr> ...]
|
||||
assert_bridge_cidrs() {
|
||||
HOST=$1; shift
|
||||
DEV=$1; shift
|
||||
CIDRS=$@
|
||||
|
||||
BRIDGE_CIDRS=$($SSH $HOST ip addr show dev $DEV | grep -o 'inet .*' | cut -d ' ' -f 2)
|
||||
|
||||
assert "echo $BRIDGE_CIDRS" "$CIDRS"
|
||||
}
|
||||
|
||||
# Run container with three cidrs
|
||||
CID=$(DOCKER_HOST=tcp://$HOST1:2375 $WEAVE run 10.0.1.1/24 10.0.2.1/24 10.0.3.1/24 -t --name multicidr -h multicidr.weave.local ubuntu | cut -b 1-12)
|
||||
assert_container_cidrs $HOST1 $CID 10.0.1.1/24 10.0.2.1/24 10.0.3.1/24
|
||||
assert_zone_records $HOST1 $CID multicidr.weave.local. 10.0.1.1 10.0.2.1 10.0.3.1
|
||||
|
||||
# Remove two of them
|
||||
weave_on $HOST1 detach 10.0.1.1/24 10.0.3.1/24 $CID
|
||||
assert_container_cidrs $HOST1 $CID 10.0.2.1/24
|
||||
assert_zone_records $HOST1 $CID multicidr.weave.local. 10.0.2.1
|
||||
|
||||
# Put them both back
|
||||
weave_on $HOST1 attach 10.0.1.1/24 10.0.3.1/24 $CID
|
||||
assert_container_cidrs $HOST1 $CID 10.0.2.1/24 10.0.1.1/24 10.0.3.1/24
|
||||
assert_zone_records $HOST1 $CID multicidr.weave.local. 10.0.2.1 10.0.1.1 10.0.3.1
|
||||
|
||||
# Stop the container, restart with three IPs
|
||||
docker_on $HOST1 stop $CID
|
||||
weave_on $HOST1 start 10.0.1.1/24 10.0.2.1/24 10.0.3.1/24 $CID
|
||||
assert_container_cidrs $HOST1 $CID 10.0.1.1/24 10.0.2.1/24 10.0.3.1/24
|
||||
assert_zone_records $HOST1 $CID multicidr.weave.local. 10.0.1.1 10.0.2.1 10.0.3.1
|
||||
|
||||
# Expose some cidrs
|
||||
weave_on $HOST1 expose 10.0.1.2/24 10.0.2.2/24 10.0.3.2/24
|
||||
assert_bridge_cidrs $HOST1 weave 10.0.1.2/24 10.0.2.2/24 10.0.3.2/24
|
||||
|
||||
# Hide some cidrs
|
||||
weave_on $HOST1 hide 10.0.1.2/24 10.0.3.2/24
|
||||
assert_bridge_cidrs $HOST1 weave 10.0.2.2/24
|
||||
|
||||
end_suite
|
||||
@@ -19,10 +19,10 @@ usage() {
|
||||
echo "weave launch-dns <cidr>"
|
||||
echo "weave connect <peer>"
|
||||
echo "weave forget <peer>"
|
||||
echo "weave run [--with-dns] <cidr> <docker run args> ..."
|
||||
echo "weave start <cidr> <container_id>"
|
||||
echo "weave attach <cidr> <container_id>"
|
||||
echo "weave detach <cidr> <container_id>"
|
||||
echo "weave run [--with-dns] <cidr> [<cidr> ...] <docker run args> ..."
|
||||
echo "weave start <cidr> [<cidr> ...] <container_id>"
|
||||
echo "weave attach <cidr> [<cidr> ...] <container_id>"
|
||||
echo "weave detach <cidr> [<cidr> ...] <container_id>"
|
||||
echo "weave expose <cidr>"
|
||||
echo "weave hide <cidr>"
|
||||
echo "weave ps"
|
||||
@@ -71,6 +71,7 @@ exec_remote() {
|
||||
if [ "$1" = "--local" ]; then
|
||||
LOCAL="$1"
|
||||
shift 1
|
||||
[ -t 0 ] && stty -onlcr
|
||||
elif [ "$1" != "run" ]; then
|
||||
exec_remote "$@"
|
||||
exit $?
|
||||
@@ -138,6 +139,16 @@ validate_cidr() {
|
||||
fi
|
||||
}
|
||||
|
||||
collect_cidr_args() {
|
||||
CIDR_ARGS=""
|
||||
CIDR_COUNT=0
|
||||
while is_cidr "$1"; do
|
||||
CIDR_ARGS="$CIDR_ARGS $1"
|
||||
CIDR_COUNT=$(($CIDR_COUNT + 1))
|
||||
shift 1
|
||||
done
|
||||
}
|
||||
|
||||
run_iptables() {
|
||||
# -w is recent addition to iptables
|
||||
if [ -z "$CHECKED_IPTABLES_W" ] ; then
|
||||
@@ -326,23 +337,33 @@ launch() {
|
||||
|
||||
attach() {
|
||||
if ip netns exec $NETNS ip link show $CONTAINER_IFNAME >/dev/null 2>&1 ; then
|
||||
# container already has the expected network interface, so assume we set it up already;
|
||||
# just add the IP address.
|
||||
if ip netns exec $NETNS ip addr show dev $CONTAINER_IFNAME | grep -F $1 >/dev/null ; then
|
||||
# address was there already
|
||||
return 0
|
||||
fi
|
||||
for ADDR; do
|
||||
# container already has the expected network interface, so assume we set it up already;
|
||||
# just add the IP address.
|
||||
if ip netns exec $NETNS ip addr show dev $CONTAINER_IFNAME | grep -F $ADDR >/dev/null ; then
|
||||
# address was there already
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! ip netns exec $NETNS ip addr add $1 dev $CONTAINER_IFNAME ; then
|
||||
return 1
|
||||
fi
|
||||
if ! ip netns exec $NETNS ip addr add $ADDR dev $CONTAINER_IFNAME ; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! connect_container_to_bridge ||
|
||||
! ip netns exec $NETNS ip addr add $1 dev $CONTAINER_IFNAME ||
|
||||
! ip netns exec $NETNS ip link set $CONTAINER_IFNAME up ; then
|
||||
if ! connect_container_to_bridge; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for ADDR; do
|
||||
if ! ip netns exec $NETNS ip addr add $ADDR dev $CONTAINER_IFNAME; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
if ! ip netns exec $NETNS ip link set $CONTAINER_IFNAME up ; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -355,14 +376,16 @@ attach() {
|
||||
}
|
||||
|
||||
detach() {
|
||||
if ! ip netns exec $NETNS ip addr show dev $CONTAINER_IFNAME | grep -F $1 >/dev/null ; then
|
||||
# address is not there, leave the device alone
|
||||
return 0
|
||||
fi
|
||||
for ADDR; do
|
||||
if ! ip netns exec $NETNS ip addr show dev $CONTAINER_IFNAME | grep -F $ADDR >/dev/null ; then
|
||||
# address is not there, leave the device alone
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! ip netns exec $NETNS ip addr del $1 dev $CONTAINER_IFNAME ; then
|
||||
return 1
|
||||
fi
|
||||
if ! ip netns exec $NETNS ip addr del $ADDR dev $CONTAINER_IFNAME ; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$(ip netns exec $NETNS ip -f inet addr show dev $CONTAINER_IFNAME)" ] ; then
|
||||
# other addresses are left, leave the device alone
|
||||
@@ -408,15 +431,21 @@ http_call_ip() {
|
||||
# Perform operation $1 on container ID $2 to local DNS database at address $3
|
||||
# This function is only called where we know $2 is a valid container name
|
||||
tell_dns() {
|
||||
METHOD="$1"
|
||||
CONTAINER_ID="$2"
|
||||
shift 2
|
||||
|
||||
if ! status=$(docker inspect --format='{{.State.Running}}' $DNS_CONTAINER_NAME 2>/dev/null) || [ "$status" != "true" ] ; then
|
||||
# weavedns not running - silently return
|
||||
return
|
||||
fi
|
||||
# get the long form of the container ID
|
||||
CONTAINER=$(docker inspect --format='{{.Id}}' $2 2>/dev/null)
|
||||
CONTAINER=$(docker inspect --format='{{.Id}}' $CONTAINER_ID 2>/dev/null)
|
||||
# extract IP address and routing prefix from CIDR
|
||||
MORE_ARGS=$(docker inspect --format='--data-urlencode fqdn={{.Config.Hostname}}.{{.Config.Domainname}}.' $CONTAINER 2>/dev/null) && true
|
||||
http_call $DNS_CONTAINER_NAME $DNS_HTTP_PORT $1 /name/$CONTAINER/${3%/*} $MORE_ARGS || true
|
||||
for ADDR; do
|
||||
http_call $DNS_CONTAINER_NAME $DNS_HTTP_PORT $METHOD /name/$CONTAINER/${ADDR%/*} $MORE_ARGS || true
|
||||
done
|
||||
}
|
||||
|
||||
# Tell the newly-started weaveDNS about existing weave IPs
|
||||
@@ -645,16 +674,15 @@ case "$COMMAND" in
|
||||
DNS_ARGS=$(exec_remote dns-args "$@")
|
||||
[ "$1" = "--with-dns" ] && shift 1
|
||||
fi
|
||||
CIDR=$1
|
||||
shift 1
|
||||
validate_cidr $CIDR
|
||||
collect_cidr_args "$@"
|
||||
shift $CIDR_COUNT
|
||||
CONTAINER=$(docker run $DNS_ARGS -d "$@")
|
||||
if [ "$LOCAL" = "--local" ]; then
|
||||
create_bridge
|
||||
with_container_netns $CONTAINER attach $CIDR >/dev/null
|
||||
tell_dns PUT $CONTAINER $CIDR
|
||||
with_container_netns $CONTAINER attach $CIDR_ARGS >/dev/null
|
||||
tell_dns PUT $CONTAINER $CIDR_ARGS
|
||||
else
|
||||
exec_remote attach $CIDR $CONTAINER
|
||||
exec_remote attach $CIDR_ARGS $CONTAINER
|
||||
fi
|
||||
echo $CONTAINER
|
||||
;;
|
||||
@@ -663,54 +691,59 @@ case "$COMMAND" in
|
||||
echo -n $DNS_ARGS
|
||||
;;
|
||||
start)
|
||||
[ $# -eq 2 ] || usage
|
||||
CIDR=$1
|
||||
validate_cidr $CIDR
|
||||
[ $# -gt 1 ] || usage
|
||||
collect_cidr_args "$@"
|
||||
shift $CIDR_COUNT
|
||||
CONTAINER_ID="$1"
|
||||
create_bridge
|
||||
CONTAINER=$(docker start $2)
|
||||
with_container_netns $CONTAINER attach $CIDR >/dev/null
|
||||
tell_dns PUT $CONTAINER $CIDR
|
||||
CONTAINER=$(docker start $CONTAINER_ID)
|
||||
with_container_netns $CONTAINER_ID attach $CIDR_ARGS >/dev/null
|
||||
tell_dns PUT $CONTAINER_ID $CIDR_ARGS
|
||||
echo $CONTAINER
|
||||
;;
|
||||
attach)
|
||||
[ $# -eq 2 ] || usage
|
||||
CIDR=$1
|
||||
validate_cidr $CIDR
|
||||
[ $# -gt 1 ] || usage
|
||||
collect_cidr_args "$@"
|
||||
shift $CIDR_COUNT
|
||||
CONTAINER_ID="$1"
|
||||
create_bridge
|
||||
with_container_netns $2 attach $CIDR >/dev/null
|
||||
tell_dns PUT $2 $CIDR
|
||||
with_container_netns $CONTAINER_ID attach $CIDR_ARGS >/dev/null
|
||||
tell_dns PUT $CONTAINER_ID $CIDR_ARGS
|
||||
;;
|
||||
detach)
|
||||
[ $# -eq 2 ] || usage
|
||||
CIDR=$1
|
||||
validate_cidr $CIDR
|
||||
with_container_netns $2 detach $CIDR >/dev/null
|
||||
tell_dns DELETE $2 $CIDR
|
||||
[ $# -gt 1 ] || usage
|
||||
collect_cidr_args "$@"
|
||||
shift $CIDR_COUNT
|
||||
CONTAINER_ID="$1"
|
||||
with_container_netns $CONTAINER_ID detach $CIDR_ARGS >/dev/null
|
||||
tell_dns DELETE $CONTAINER_ID $CIDR_ARGS
|
||||
;;
|
||||
expose)
|
||||
[ $# -eq 1 ] || usage
|
||||
CIDR=$1
|
||||
validate_cidr $CIDR
|
||||
create_bridge --without-ethtool
|
||||
if ! ip addr show dev $BRIDGE | grep -qF $CIDR
|
||||
then
|
||||
ip addr add dev $BRIDGE $CIDR
|
||||
arp_update $BRIDGE $CIDR
|
||||
add_iptables_rule nat WEAVE -o $BRIDGE ! -s $CIDR -j MASQUERADE
|
||||
add_iptables_rule nat WEAVE -s $CIDR ! -o $BRIDGE -j MASQUERADE
|
||||
fi
|
||||
[ $# -gt 0 ] || usage
|
||||
for CIDR; do
|
||||
validate_cidr $CIDR
|
||||
create_bridge --without-ethtool
|
||||
if ! ip addr show dev $BRIDGE | grep -qF $CIDR
|
||||
then
|
||||
ip addr add dev $BRIDGE $CIDR
|
||||
arp_update $BRIDGE $CIDR
|
||||
add_iptables_rule nat WEAVE -o $BRIDGE ! -s $CIDR -j MASQUERADE
|
||||
add_iptables_rule nat WEAVE -s $CIDR ! -o $BRIDGE -j MASQUERADE
|
||||
fi
|
||||
done
|
||||
;;
|
||||
hide)
|
||||
[ $# -eq 1 ] || usage
|
||||
CIDR=$1
|
||||
validate_cidr $CIDR
|
||||
create_bridge --without-ethtool
|
||||
if ip addr show dev $BRIDGE | grep -qF $CIDR
|
||||
then
|
||||
ip addr del dev $BRIDGE $CIDR
|
||||
delete_iptables_rule nat WEAVE -o $BRIDGE ! -s $CIDR -j MASQUERADE
|
||||
delete_iptables_rule nat WEAVE -s $CIDR ! -o $BRIDGE -j MASQUERADE
|
||||
fi
|
||||
[ $# -gt 0 ] || usage
|
||||
for CIDR; do
|
||||
validate_cidr $CIDR
|
||||
create_bridge --without-ethtool
|
||||
if ip addr show dev $BRIDGE | grep -qF $CIDR
|
||||
then
|
||||
ip addr del dev $BRIDGE $CIDR
|
||||
delete_iptables_rule nat WEAVE -o $BRIDGE ! -s $CIDR -j MASQUERADE
|
||||
delete_iptables_rule nat WEAVE -s $CIDR ! -o $BRIDGE -j MASQUERADE
|
||||
fi
|
||||
done
|
||||
;;
|
||||
stop)
|
||||
[ $# -eq 0 ] || usage
|
||||
|
||||
Reference in new issue
Block a user