Do all weave operations from within the container

Fixes #523
This commit is contained in:
Tom Wilkie
2015-09-29 11:48:37 +00:00
parent 8a8520ffc9
commit 206a56b1ad
4 changed files with 74 additions and 132 deletions

View File

@@ -29,7 +29,7 @@ docker/weave:
curl -L git.io/weave -o docker/weave
chmod u+x docker/weave
$(SCOPE_EXPORT): $(APP_EXE) $(PROBE_EXE) $(DOCKER_DISTRIB) docker/weave $(RUNSVINIT) docker/Dockerfile docker/run-app docker/run-probe
$(SCOPE_EXPORT): $(APP_EXE) $(PROBE_EXE) $(DOCKER_DISTRIB) docker/weave $(RUNSVINIT) docker/Dockerfile docker/run-app docker/run-probe docker/entrypoint.sh
@if [ -z '$(DOCKER_SQUASH)' ] ; then echo "Please install docker-squash by running 'make deps' (and make sure GOPATH/bin is in your PATH)." && exit 1 ; fi
cp $(APP_EXE) $(PROBE_EXE) docker/
cp $(DOCKER_DISTRIB) docker/docker.tgz

View File

@@ -3,7 +3,7 @@ MAINTAINER Weaveworks Inc <help@weave.works>
LABEL works.weave.role=system
WORKDIR /home/weave
RUN echo "http://dl-4.alpinelinux.org/alpine/edge/testing" >>/etc/apk/repositories && \
apk add --update runit conntrack-tools iproute2 util-linux && \
apk add --update runit conntrack-tools iproute2 util-linux curl && \
rm -rf /var/cache/apk/*
ADD ./docker.tgz /
ADD ./weave /usr/bin/

View File

@@ -1,29 +1,63 @@
#!/bin/sh
usage() {
echo "$0 --dns <IP> --hostname <NAME> --searchpath <SEARCHPATH> --app.foo bar --probe.foo bar"
echo "$0 --app.foo bar --probe.foo bar"
exit 1
}
# This script exists to modify the network settings in the scope containers
# as docker doesn't allow it when started with --net=host
WEAVE_CONTAINER_NAME=weave
DOCKER_BRIDGE=docker0
HOSTNAME=scope
DOMAIN=weave.local
IP_REGEXP="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
container_ip() {
if ! status=$(docker inspect --format='{{.State.Running}} {{.NetworkSettings.IPAddress}}' $1 2>/dev/null); then
echo "$2" >&2
return 1
fi
case "$status" in
"true ")
echo "$1 container has no IP address; is Docker networking enabled?" >&2
return 1
;;
true*)
CONTAINER_IP="${status#true }"
;;
*)
echo "$3" >&2
return 1
;;
esac
}
is_running() {
status=$(docker inspect --format='{{.State.Running}}' $1 2>/dev/null) && [ "$status" = "true" ]
return $?
}
docker_bridge_ip() {
local DOCKER_BRIDGE_IP=$(ip -f inet address show dev $DOCKER_BRIDGE | grep -m1 -o 'inet \([.0-9]\)*')
echo ${DOCKER_BRIDGE_IP#inet }
}
# Run `weave expose` if it's not already exposed.
weave_expose() {
status=$(weave --local ps weave:expose | awk '{print $3}' 2>/dev/null)
if [ "$status" = "" ]; then
weave --local expose
fi
}
mkdir -p /etc/weave
APP_ARGS=""
PROBE_ARGS=""
while true; do
case "$1" in
--dns)
[ $# -gt 1 ] || usage
DNS_SERVER="$2"
shift
;;
--searchpath)
[ $# -gt 1 ] || usage
SEARCHPATH="$2"
shift
;;
--app.*)
if echo "$1" | grep "=" 1>/dev/null; then
ARG_NAME=$(echo "$1" | sed 's/\-\-app\.\([^=]*\)=\(.*\)/\1/')
@@ -73,15 +107,34 @@ while true; do
shift
done
if is_running $WEAVE_CONTAINER_NAME; then
container_ip $WEAVE_CONTAINER_NAME
PROBE_ARGS="$PROBE_ARGS -weave.router.addr=$CONTAINER_IP"
weave_expose
DOCKER_BRIDGE_IP=$(docker_bridge_ip)
echo "Weave container detected at $CONTAINER_IP, Docker bridge at $DOCKER_BRIDGE_IP"
echo "domain $DOMAIN" >/etc/resolv.conf
echo "search $DOMAIN" >>/etc/resolv.conf
echo "nameserver $DOCKER_BRIDGE_IP" >>/etc/resolv.conf
IP_ADDRS=$(find /sys/class/net -type l | xargs -n1 basename | grep -vE 'docker|veth|lo' | \
xargs -n1 ip addr show | grep inet | awk '{ print $2 }' | grep -oE "$IP_REGEXP")
CONTAINER=$(docker inspect --format='{{.Id}}' weavescope)
if [ -z "$IP_ADDRS" ]; then
echo "Could not determine local IP address; Weave DNS integration will not work correctly."
exit 1
else
for ip in $IP_ADDRS; do
weave --local dns-add $ip $CONTAINER -h $HOSTNAME.$DOMAIN
done
fi
fi
echo "$APP_ARGS" >/etc/weave/scope-app.args
echo "$PROBE_ARGS" >/etc/weave/scope-probe.args
if [ -n "$DNS_SERVER" -a -n "$SEARCHPATH" ]; then
echo "domain $SEARCHPATH" >/etc/resolv.conf
echo "search $SEARCHPATH" >>/etc/resolv.conf
echo "nameserver $DNS_SERVER" >>/etc/resolv.conf
fi
# End of the command line can optionally be some
# addresses of apps to connect to, for people not
# using Weave DNS. We stick these in /etc/weave/apps

115
scope
View File

@@ -20,33 +20,16 @@ fi
IMAGE_VERSION=${VERSION:-$IMAGE_VERSION}
SCOPE_IMAGE=weaveworks/scope:$IMAGE_VERSION
SCOPE_CONTAINER_NAME=weavescope
WEAVE_CONTAINER_NAME=weave
WEAVEDNS_CONTAINER_NAME=weavedns
HOSTNAME=scope
DOMAINNAME=weave.local
FQDN=$HOSTNAME.$DOMAINNAME
DOCKER_BRIDGE=${DOCKER_BRIDGE:-docker0}
IP_REGEXP="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
IP_ADDR_CMD="find /sys/class/net -type l | xargs -n1 basename | grep -vE 'docker|veth|lo' | \
xargs -n1 ip addr show | grep inet | awk '{ print \$2 }' | grep -oE '$IP_REGEXP'"
WEAVESCOPE_DOCKER_ARGS=${WEAVESCOPE_DOCKER_ARGS:-}
WEAVESCOPE_DNS_ARGS=${WEAVESCOPE_DNS_ARGS:-}
[ $# -gt 0 ] || usage
COMMAND=$1
shift 1
# http://stackoverflow.com/questions/592620/how-to-check-if-a-program-exists-from-a-bash-script
command_exists() {
command -v $1 >/dev/null 2>&1
}
is_running() {
status=$(docker inspect --format='{{.State.Running}}' $1 2>/dev/null) && [ "$status" = "true" ]
return $?
}
# Check that a container named $1 with image $2 is not running
check_not_running() {
case $(docker inspect --format='{{.State.Running}} {{.Config.Image}}' $1 2>/dev/null) in
@@ -75,113 +58,19 @@ check_not_running() {
esac
}
# Run `weave expose` if it's not already exposed.
weave_expose() {
status=$(weave ps weave:expose | awk '{print $3}' 2>/dev/null)
if [ "$status" = "" ]; then
weave expose
fi
}
# Add all Scope IPs to its DNS record.
weave_dns_add() {
CONTAINER_ID="$1"
CONTAINER_FQDN="$2"
shift 2
for ip in $*; do
weave dns-add $ip $CONTAINER_ID -h $CONTAINER_FQDN
done
}
weave_dns_present() {
docker run --rm --entrypoint /bin/sh $SCOPE_IMAGE -c "nc -z $DOCKER_BRIDGE_IP 53" || is_running $WEAVEDNS_CONTAINER_NAME
}
set_docker_bridge_ip() {
DOCKER_BRIDGE_IP=$(docker run --rm --net=host --entrypoint /bin/sh $SCOPE_IMAGE -c "ip -f inet address show dev $DOCKER_BRIDGE" | grep -m1 -o 'inet \([.0-9]\)*')
DOCKER_BRIDGE_IP=${DOCKER_BRIDGE_IP#inet }
}
# Call url $4 with http verb $3 on container $1 at port $2
http_call() {
container_ip $1 \
"$1 container is not present. Have you launched it?" \
"$1 container is not running." \
|| return 1
shift 1
http_call_ip $CONTAINER_IP "$@"
}
http_call_ip() {
ip="$1"
port="$2"
http_verb="$3"
url="$4"
shift 4
curl --connect-timeout 3 -s -X $http_verb "$@" http://$ip:$port$url
}
container_ip() {
if ! status=$(docker inspect --format='{{.State.Running}} {{.NetworkSettings.IPAddress}}' $1 2>/dev/null); then
echo "$2" >&2
return 1
fi
case "$status" in
"true ")
echo "$1 container has no IP address; is Docker networking enabled?" >&2
return 1
;;
true*)
CONTAINER_IP="${status#true }"
;;
*)
echo "$3" >&2
return 1
;;
esac
}
case "$COMMAND" in
launch)
check_not_running $SCOPE_CONTAINER_NAME $SCOPE_IMAGE
set_docker_bridge_ip
# If Weave is running, we want to expose a Weave IP to the host
# network namespace, so Scope can use it.
SCOPE_ARGS=
if command_exists weave && is_running $WEAVE_CONTAINER_NAME; then
container_ip $WEAVE_CONTAINER_NAME
SCOPE_ARGS="--probe.weave.router.addr=$CONTAINER_IP"
weave_expose
fi
# If WeaveDNS is running, we want to automatically tell the scope
# image to use weave dns. We can't use --dns with --net=host, so we
# have to hack it.
if command_exists weave && weave_dns_present; then
WEAVESCOPE_DNS_ARGS="$WEAVESCOPE_DNS_ARGS --dns $DOCKER_BRIDGE_IP --searchpath $DOMAINNAME"
fi
docker rm -f $SCOPE_CONTAINER_NAME >/dev/null 2>&1 || true
CONTAINER=$(docker run --privileged -d --name=$SCOPE_CONTAINER_NAME --net=host --pid=host \
-v /var/run/docker.sock:/var/run/docker.sock \
$WEAVESCOPE_DOCKER_ARGS $SCOPE_IMAGE $WEAVESCOPE_DNS_ARGS $SCOPE_ARGS --probe.docker true "$@")
IP_ADDRS=$(docker run --rm --net=host --entrypoint /bin/sh $SCOPE_IMAGE -c "$IP_ADDR_CMD")
if command_exists weave && is_running $WEAVE_CONTAINER_NAME && weave_dns_present; then
if [ -z "$IP_ADDRS" ]; then
echo "Could not determine local IP address; Weave DNS integration will not work correctly."
exit 1
fi
weave_dns_add $CONTAINER $FQDN $IP_ADDRS
fi
$WEAVESCOPE_DOCKER_ARGS $SCOPE_IMAGE --probe.docker true "$@")
echo $CONTAINER
if ! echo "$@" | grep -E "\-\-no\-app|\-\-service\-token" 1>/dev/null; then
IP_ADDRS=$(docker run --rm --net=host --entrypoint /bin/sh $SCOPE_IMAGE -c "$IP_ADDR_CMD")
echo "Weave Scope is reachable at the following URL(s):" >&2
for ip in $IP_ADDRS; do
echo " * http://$ip:4040/" >&2