From 8873d69b77b3d54cf5dd64e0045be7bfaa4420fa Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Thu, 11 Jun 2015 14:03:07 +0100 Subject: [PATCH 1/6] [proxy] Add --without-dns flag, and change meaning of --with-dns flag --- prog/weaveproxy/main.go | 7 +++++- proxy/create_container_interceptor.go | 13 +++++++---- proxy/proxy.go | 3 ++- site/proxy.md | 18 +++++++++------ test/630_proxy_dns_test.sh | 33 +++++++++++++++++++++++---- weave | 2 +- 6 files changed, 58 insertions(+), 18 deletions(-) diff --git a/prog/weaveproxy/main.go b/prog/weaveproxy/main.go index 4b8f039b..8f66e59f 100644 --- a/prog/weaveproxy/main.go +++ b/prog/weaveproxy/main.go @@ -36,7 +36,8 @@ func main() { getopt.BoolVarLong(&c.TLSConfig.Enabled, "tls", 0, "Use TLS; implied by --tlsverify") getopt.StringVarLong(&c.TLSConfig.Key, "tlskey", 0, "Path to TLS key file") getopt.BoolVarLong(&c.TLSConfig.Verify, "tlsverify", 0, "Use TLS and verify the remote") - getopt.BoolVarLong(&c.WithDNS, "with-dns", 'w', "instruct created containers to use weaveDNS as their nameserver") + getopt.BoolVarLong(&c.WithDNS, "with-dns", 'w', "instruct created containers to always use weaveDNS as their nameserver") + getopt.BoolVarLong(&c.WithoutDNS, "without-dns", 0, "instruct created containers to never use weaveDNS as their nameserver") getopt.BoolVarLong(&c.WithIPAM, "with-ipam", 'i', "automatically allocate addresses for containers without a WEAVE_CIDR") getopt.Parse() @@ -45,6 +46,10 @@ func main() { os.Exit(0) } + if c.WithDNS && c.WithoutDNS { + Error.Fatalf("Cannot use both '--with-dns' and '--without-dns' flags") + } + if debug { InitDefaultLogging(true) } diff --git a/proxy/create_container_interceptor.go b/proxy/create_container_interceptor.go index 22d29214..dbb3c920 100644 --- a/proxy/create_container_interceptor.go +++ b/proxy/create_container_interceptor.go @@ -81,7 +81,12 @@ func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Co } func (i *createContainerInterceptor) setWeaveDNS(container *createContainerRequestBody, r *http.Request) error { - if !i.proxy.WithDNS { + if i.proxy.WithoutDNS { + return nil + } + + dnsDomain, dnsRunning := i.getDNSDomain() + if !(dnsRunning || i.proxy.WithDNS) { return nil } @@ -95,13 +100,13 @@ func (i *createContainerInterceptor) setWeaveDNS(container *createContainerReque if container.Hostname == "" && name != "" { container.Hostname = name // Strip trailing period because it's unusual to see it used on the end of a host name - container.Domainname = strings.TrimSuffix(i.getDNSDomain(), ".") + container.Domainname = strings.TrimSuffix(dnsDomain, ".") } return nil } -func (i *createContainerInterceptor) getDNSDomain() (domain string) { +func (i *createContainerInterceptor) getDNSDomain() (domain string, running bool) { domain = nameserver.DefaultLocalDomain dnsContainer, err := i.proxy.client.InspectContainer("weavedns") if err != nil || @@ -122,7 +127,7 @@ func (i *createContainerInterceptor) getDNSDomain() (domain string) { return } - return string(b) + return string(b), true } func (i *createContainerInterceptor) InterceptResponse(r *http.Response) error { diff --git a/proxy/proxy.go b/proxy/proxy.go index 1751b48c..1c44b679 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -37,6 +37,7 @@ type Config struct { TLSConfig TLSConfig Version string WithDNS bool + WithoutDNS bool WithIPAM bool } @@ -61,7 +62,7 @@ func NewProxy(c Config) (*Proxy, error) { }, } - if p.WithDNS { + if !p.WithoutDNS { dockerBridgeIP, err := callWeave("docker-bridge-ip") if err != nil { return nil, err diff --git a/site/proxy.md b/site/proxy.md index 0c666afe..2ddc5d81 100644 --- a/site/proxy.md +++ b/site/proxy.md @@ -115,13 +115,17 @@ are handled as before. ## Automatic discovery -Containers started via the proxy are automatically registered in -[weaveDNS](weavedns.html) if they have a hostname in the weaveDNS -domain (usually `.weave.local`). In order for containers to be able to -look up such names, their DNS resolver needs to be configured to point -at weaveDNS. This can be done [manually](weavedns.html#without-run), -or automatically by the proxy by launching it with the `--with-dns` -option, i.e. +Containers started via the proxy are +automatically registered in [weaveDNS](weavedns.html) if they have a +hostname in the weaveDNS domain (usually `.weave.local`). In order for +containers to be able to look up such names, their DNS resolver needs +to be configured to point at weaveDNS. This will be done automatically by the proxy + while weaveDNS is running. To disable this launch the proxy with the `--without-dns` option, i.e. + + host1$ weave launch-proxy --without-dns + +To enable weaveDNS resolution when weaveDNS is not running, launch the +proxy with the `--with-dns` option, i.e. host1$ weave launch-proxy --with-dns diff --git a/test/630_proxy_dns_test.sh b/test/630_proxy_dns_test.sh index e0284f60..6fcf4c79 100755 --- a/test/630_proxy_dns_test.sh +++ b/test/630_proxy_dns_test.sh @@ -7,14 +7,39 @@ C2=10.2.0.34 C1_NAME=c1.weave.local C2_NAME=seetwo.weave.local +boot_containers() { + proxy docker_on $HOST1 run -e WEAVE_CIDR=$C2/24 -dt --name=c2 -h $C2_NAME $DNS_IMAGE /bin/sh + proxy docker_on $HOST1 run -e WEAVE_CIDR=$C1/24 -dt --name=c1 $DNS_IMAGE /bin/sh +} + +kill_containers() { + docker_on $HOST1 kill c1 c2 + docker_on $HOST1 rm c1 c2 +} + start_suite "Proxy registers containers with dns" -weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS -weave_on $HOST1 launch-proxy --with-dns -proxy docker_on $HOST1 run -e WEAVE_CIDR=$C2/24 -dt --name=c2 -h $C2_NAME $DNS_IMAGE /bin/sh -proxy docker_on $HOST1 run -e WEAVE_CIDR=$C1/24 -dt --name=c1 $DNS_IMAGE /bin/sh +bridge_ip=$(weave_on $HOST1 docker-bridge-ip) +weave_on $HOST1 launch-proxy --with-dns +boot_containers +assert "exec_on $HOST1 c1 cat /etc/resolv.conf" "nameserver $bridge_ip" +assert "exec_on $HOST1 c2 cat /etc/resolv.conf" "nameserver $bridge_ip" +weave_on $HOST1 stop-proxy +kill_containers + +weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS + +weave_on $HOST1 launch-proxy +boot_containers assert_dns_record $HOST1 c1 $C2_NAME $C2 assert_dns_record $HOST1 c2 $C1_NAME $C1 +weave_on $HOST1 stop-proxy +kill_containers + +weave_on $HOST1 launch-proxy --without-dns +boot_containers +assert_no_dns_record $HOST1 c1 $C2_NAME +assert_no_dns_record $HOST1 c2 $C1_NAME end_suite diff --git a/weave b/weave index 339a1c0e..9b3cfadc 100755 --- a/weave +++ b/weave @@ -29,7 +29,7 @@ usage() { echo "weave launch [-password ] [-nickname ] [-nodiscovery]" echo " [-iprange [-ipsubnet ]] ..." echo "weave launch-dns []" - echo "weave launch-proxy [-D ] [-H ] [--with-dns] [--with-ipam]" + echo "weave launch-proxy [-D ] [-H ] [--with-dns|--without-dns] [--with-ipam]" echo "weave connect [--replace] [ ...]" echo "weave forget ..." echo "weave run [--with-dns] [ ...] ..." From fdce84d9d98293e4bcfa3a004196f80831a5cc95 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 11 Jun 2015 16:42:37 +0100 Subject: [PATCH 2/6] New --with-dns/--without-dns behaviour in weave script --- weave | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/weave b/weave index 9b3cfadc..c5e9eb3b 100755 --- a/weave +++ b/weave @@ -29,10 +29,11 @@ usage() { echo "weave launch [-password ] [-nickname ] [-nodiscovery]" echo " [-iprange [-ipsubnet ]] ..." echo "weave launch-dns []" - echo "weave launch-proxy [-D ] [-H ] [--with-dns|--without-dns] [--with-ipam]" + echo "weave launch-proxy [-D ] [-H ]" + echo " [--with-dns | --without-dns] [--with-ipam]" echo "weave connect [--replace] [ ...]" echo "weave forget ..." - echo "weave run [--with-dns] [ ...] ..." + echo "weave run [--with-dns | --without-dns] [ ...] ..." echo "weave start [ ...] " echo "weave attach [ ...] " echo "weave detach [ ...] " @@ -119,6 +120,14 @@ collect_ip_args() { done } +dns_arg_count() { + if [ "$1" = "--with-dns" -o "$1" = "--without-dns" ]; then + echo 1 + else + echo 0 + fi +} + # "run" is a special case because we want to use docker directly, # rather than the docker in $EXEC_IMAGE remotely. That's because we # are passing arbitrary arguments on to docker run, and we can't rely @@ -126,10 +135,10 @@ collect_ip_args() { if [ "$1" = "run" ] ; then shift 1 check_docker_version - if [ "$1" = "--with-dns" ] ; then - shift 1 - DNS_ARGS=$(exec_remote dns-args "$@") + if [ "$1" != "--without-dns" ] ; then + DNS_ARGS=$(exec_remote dns-args "$@" || true) fi + shift $(dns_arg_count "$@") collect_cidr_args "$@" shift $CIDR_ARG_COUNT CONTAINER=$(docker $DOCKER_CLIENT_ARGS run $DNS_ARGS -d "$@") @@ -631,7 +640,7 @@ dns_args() { # versions prior to 1.3.0 fail to include the domain when # setting the hostname, so lookups for non-fully-qualified # names fail. - echo "ERROR: The '--with-dns' option requires Docker 1.3.0 or later; you are running $DOCKER_VERSION" >&2 + echo "ERROR: Need Docker 1.3.0 or later to configure container DNS; you are running $DOCKER_VERSION" >&2 exit 1 fi docker_bridge_ip @@ -639,6 +648,8 @@ dns_args() { DNS_SEARCH_ARG="--dns-search=." NAME_ARG="" HOSTNAME_SPECIFIED= + WITH_DNS= + WITHOUT_DNS= while [ $# -gt 0 ] ; do case "$1" in --dns-search=*) @@ -654,9 +665,19 @@ dns_args() { -h|--hostname|--hostname=*) HOSTNAME_SPECIFIED=1 ;; + --with-dns) + WITH_DNS=1 + ;; + --without-dns) + WITHOUT_DNS=1 + ;; esac shift done + [ -n "$WITHOUT_DNS" ] && return 0 + if [ -z "$WITH_DNS" ] ; then + check_running $DNS_CONTAINER_NAME 2>/dev/null || return 0 + fi DNS_ARGS="$DNS_ARG $DNS_SEARCH_ARG" if [ -n "$NAME_ARG" -a -z "$HOSTNAME_SPECIFIED" ] ; then DOMAIN=$(call_dns GET /domain 2>/dev/null) || DOMAIN=weave.local. @@ -1071,10 +1092,8 @@ case "$COMMAND" in fi ;; run) - if [ "$1" = "--with-dns" ] ; then - shift 1 - dns_args "$@" - fi + dns_args "$@" + shift $(dns_arg_count "$@") collect_cidr_args "$@" shift $CIDR_ARG_COUNT CONTAINER=$(docker run $DNS_ARGS -d "$@") From e5b1cc21a93a0697709318644cfbc06c15de488a Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 11 Jun 2015 16:45:49 +0100 Subject: [PATCH 3/6] Smoke test for new weave script DNS behaviour --- test/280_with_or_without_dns_test.sh | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100755 test/280_with_or_without_dns_test.sh diff --git a/test/280_with_or_without_dns_test.sh b/test/280_with_or_without_dns_test.sh new file mode 100755 index 00000000..5d6e0de5 --- /dev/null +++ b/test/280_with_or_without_dns_test.sh @@ -0,0 +1,40 @@ +#! /bin/bash + +. ./config.sh + +IP=10.2.0.34 +TARGET=seetwo.weave.local +TARGET_IP=10.2.0.78 + +assert_no_resolution() { + container=$(weave_on $HOST1 run "$@" $IP/24 -t $DNS_IMAGE /bin/sh) + assert_no_dns_record $HOST1 "$container" $TARGET + docker_on $HOST1 rm -f "$container" >/dev/null +} + +assert_resolution() { + container=$(weave_on $HOST1 run "$@" $IP/24 -t $DNS_IMAGE /bin/sh) + assert_dns_record $HOST1 "$container" $TARGET $TARGET_IP + docker_on $HOST1 rm -f "$container" >/dev/null +} + +start_suite "With or without DNS test" + +weave_on $HOST1 launch + +DNS_IP=$(weave_on $HOST1 docker-bridge-ip) + +# Assert behaviour without weaveDNS running +assert_no_resolution --without-dns +assert_no_resolution +assert_no_resolution --with-dns + +weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS +start_container $HOST1 $TARGET_IP/24 --name c2 -h $TARGET + +# Assert behaviour with weaveDNS running +assert_no_resolution --without-dns +assert_resolution +assert_resolution --with-dns + +end_suite From 03b83811faa655a4b3c346602496197cd9a8a4b3 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 11 Jun 2015 17:22:58 +0100 Subject: [PATCH 4/6] Update documentation --- site/proxy.md | 31 ++++++++++++------------------- site/weavedns.md | 32 ++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/site/proxy.md b/site/proxy.md index 2ddc5d81..4b0a1e6e 100644 --- a/site/proxy.md +++ b/site/proxy.md @@ -115,25 +115,18 @@ are handled as before. ## Automatic discovery -Containers started via the proxy are -automatically registered in [weaveDNS](weavedns.html) if they have a -hostname in the weaveDNS domain (usually `.weave.local`). In order for -containers to be able to look up such names, their DNS resolver needs -to be configured to point at weaveDNS. This will be done automatically by the proxy - while weaveDNS is running. To disable this launch the proxy with the `--without-dns` option, i.e. - - host1$ weave launch-proxy --without-dns - -To enable weaveDNS resolution when weaveDNS is not running, launch the -proxy with the `--with-dns` option, i.e. - - host1$ weave launch-proxy --with-dns - -Now any containers started via the proxy, and with a `WEAVE_CIDR=...` -environment variable (or even without it, if IPAM is -[configured](#ipam)), will use weaveDNS for name resolution. If not -provided, the hostname will default to the container name and will be -registered in weaveDNS. +Containers started via the proxy are automatically registered in +[weaveDNS](weavedns.html) if they have a hostname in the weaveDNS +domain (usually `.weave.local`). In order for containers to be able to +look up such names, their DNS resolver needs to be configured to point +at weaveDNS. This will be done automatically by the proxy while +weaveDNS is running. To override this behaviour launch the proxy with +either `--with-dns` or `--without-dns`, which will force the proxy to +always/never set the resolver to weaveDNS. If there is no hostname +provided, the container will be registered in weaveDNS using its +container name. Otherwise, if there is no container name, and no +hostname (or a hostname outside the weaveDNS domain), the container +will not be registered in weaveDNS. ## Multi-host example diff --git a/site/weavedns.md b/site/weavedns.md index dbe2ab83..7eda546e 100644 --- a/site/weavedns.md +++ b/site/weavedns.md @@ -27,16 +27,27 @@ hosts. WeaveDNS is deployed as a set of containers that communicate with each other over the weave network. One such container needs to be started on every weave host, by invoking the weave script command -`launch-dns`. Application containers are then instructed to use -weaveDNS as their nameserver by supplying the `--with-dns` option when -starting them; containers so started also automatically register their -container name in the weaveDNS domain. For example: +`launch-dns`. ```bash $ weave launch $ weave launch-dns 10.2.254.1/24 -$ weave run --with-dns 10.2.1.25/24 -ti --name=pingme ubuntu -$ shell1=$(weave run --with-dns 10.2.1.26/24 -ti --name=ubuntu ubuntu) +``` + +Containers started while weaveDNS is running are automatically +registered in [weaveDNS](weavedns.html) if they have a hostname in the +weaveDNS domain (usually `.weave.local`). In order for containers to +be able to look up such names, their DNS resolver needs to be +configured to point at weaveDNS. This will be done automatically while +weaveDNS is running. If there is no hostname provided, the container +will be registered in weaveDNS using its container name. Otherwise, if +there is no container name, and no hostname (or a hostname outside the +weaveDNS domain), the container will not be registered in weaveDNS. +For example, to use the container name as the hostname: + +```bash +$ weave run 10.2.1.25/24 -ti --name=pingme ubuntu +$ shell1=$(weave run 10.2.1.26/24 -ti --name=ubuntu ubuntu) $ docker attach $shell1 root@ubuntu:/# ping pingme @@ -51,6 +62,11 @@ it in weaveDNS simply by giving the container a hostname in the $ weave run 10.2.1.25/24 -ti -h pingme.weave.local ubuntu ``` +It is also possible to force or forbid an application container's use +of weaveDNS with the `--with-dns` and `--without-dns` options to +`weave run`; these override the runtime detection of the weaveDNS +container. + Each weaveDNS container started with `launch-dns` needs to be given its own, unique, IP address, in a subnet that is common to all weaveDNS containers and not in use on any of the hosts. @@ -62,7 +78,7 @@ use weaveDNS on a second host we would run: ```bash host2$ weave launch $HOST1 host2$ weave launch-dns 10.2.254.2/24 -host2$ shell2=$(weave run --with-dns 10.2.1.36/24 -ti --name=ubuntu2 ubuntu) +host2$ shell2=$(weave run 10.2.1.36/24 -ti --name=ubuntu2 ubuntu) host2$ docker attach $shell2 root@ubuntu2:/# ping pingme @@ -117,7 +133,7 @@ Returning to our earlier example, let us start an additional `pingme` container, this time on the 2nd host, and then run some ping tests... ```bash -host2$ weave run --with-dns 10.2.1.35/24 -ti --name=pingme ubuntu +host2$ weave run 10.2.1.35/24 -ti --name=pingme ubuntu host2$ docker attach $shell2 root@ubuntu2:/# ping -nq -c 1 pingme From b33d4497faf88d343aa1f1b1bc98f69db743276c Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Fri, 12 Jun 2015 11:57:11 +0100 Subject: [PATCH 5/6] Fix test broken by new default behaviour --- test/240_dns_add_name_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/240_dns_add_name_test.sh b/test/240_dns_add_name_test.sh index 176354f6..1b0a4070 100755 --- a/test/240_dns_add_name_test.sh +++ b/test/240_dns_add_name_test.sh @@ -12,8 +12,8 @@ start_suite "Add and remove names on a single host" weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS -start_container $HOST1 $C2/24 --name=c2 -start_container_with_dns $HOST1 $C1/24 --name=c1 +start_container $HOST1 --without-dns $C2/24 --name=c2 +start_container_with_dns $HOST1 $C1/24 --name=c1 weave_on $HOST1 dns-add $C2 c2 -h $NAME2 From af38f07d26feff5eb26bb5ce87b9e3aea183fd11 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 12 Jun 2015 16:50:01 +0100 Subject: [PATCH 6/6] refactoring proxy dns test --- test/280_with_or_without_dns_test.sh | 8 ++++---- test/630_proxy_dns_test.sh | 30 +++++++++++++++++----------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/test/280_with_or_without_dns_test.sh b/test/280_with_or_without_dns_test.sh index 5d6e0de5..f537b7dd 100755 --- a/test/280_with_or_without_dns_test.sh +++ b/test/280_with_or_without_dns_test.sh @@ -8,14 +8,14 @@ TARGET_IP=10.2.0.78 assert_no_resolution() { container=$(weave_on $HOST1 run "$@" $IP/24 -t $DNS_IMAGE /bin/sh) - assert_no_dns_record $HOST1 "$container" $TARGET - docker_on $HOST1 rm -f "$container" >/dev/null + assert_no_dns_record $HOST1 $container $TARGET + rm_containers $HOST1 $container } assert_resolution() { container=$(weave_on $HOST1 run "$@" $IP/24 -t $DNS_IMAGE /bin/sh) - assert_dns_record $HOST1 "$container" $TARGET $TARGET_IP - docker_on $HOST1 rm -f "$container" >/dev/null + assert_dns_record $HOST1 $container $TARGET $TARGET_IP + rm_containers $HOST1 $container } start_suite "With or without DNS test" diff --git a/test/630_proxy_dns_test.sh b/test/630_proxy_dns_test.sh index 6fcf4c79..f37e388b 100755 --- a/test/630_proxy_dns_test.sh +++ b/test/630_proxy_dns_test.sh @@ -13,33 +13,39 @@ boot_containers() { } kill_containers() { - docker_on $HOST1 kill c1 c2 - docker_on $HOST1 rm c1 c2 + rm_containers $HOST1 c1 c2 +} + +assert_no_resolution() { + boot_containers + assert_no_dns_record $HOST1 c1 $C2_NAME $C2 + assert_no_dns_record $HOST1 c2 $C1_NAME $C1 + kill_containers } start_suite "Proxy registers containers with dns" bridge_ip=$(weave_on $HOST1 docker-bridge-ip) +# Assert behaviour without weaveDNS running, but dns forced weave_on $HOST1 launch-proxy --with-dns -boot_containers -assert "exec_on $HOST1 c1 cat /etc/resolv.conf" "nameserver $bridge_ip" -assert "exec_on $HOST1 c2 cat /etc/resolv.conf" "nameserver $bridge_ip" +assert_no_resolution weave_on $HOST1 stop-proxy -kill_containers - -weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS +# Assert behaviour without weaveDNS weave_on $HOST1 launch-proxy +assert_no_resolution + +# Assert behaviour with weaveDNS running +weave_on $HOST1 launch-dns 10.2.254.1/24 $WEAVEDNS_ARGS boot_containers assert_dns_record $HOST1 c1 $C2_NAME $C2 assert_dns_record $HOST1 c2 $C1_NAME $C1 -weave_on $HOST1 stop-proxy kill_containers +weave_on $HOST1 stop-proxy +# Assert behaviour with weaveDNS running, but dns forced off weave_on $HOST1 launch-proxy --without-dns -boot_containers -assert_no_dns_record $HOST1 c1 $C2_NAME -assert_no_dns_record $HOST1 c2 $C1_NAME +assert_no_resolution end_suite