Merge pull request #890 from awh/use_container_name_as_hostname
Use container name as hostname Closes #750.
This commit is contained in:
commit
e96cde1872
9 files changed
+136
-18
No files matched your search
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#! /bin/bash
|
||||
|
||||
. ./config.sh
|
||||
|
||||
NAME=c1
|
||||
DOMAIN=weave.local.
|
||||
HOSTNAME=$NAME-hostname.$DOMAIN
|
||||
|
||||
# Docker inspect hostname + domainname of container $2 on host $1
|
||||
docker_inspect_fqdn() {
|
||||
docker_on $1 inspect --format='{{.Config.Hostname}}.{{.Config.Domainname}}' $2
|
||||
}
|
||||
|
||||
# Start container with args $2.. and assert fqdn of $1
|
||||
assert_expected_fqdn() {
|
||||
EXPECTED_FQDN=$1
|
||||
shift
|
||||
start_container_with_dns $HOST1 "$@"
|
||||
assert "docker_inspect_fqdn $HOST1 $NAME" $EXPECTED_FQDN
|
||||
docker_on $HOST1 rm -f $NAME
|
||||
}
|
||||
|
||||
start_suite "Use container name as hostname"
|
||||
|
||||
weave_on $HOST1 launch -iprange 10.2.0.0/24
|
||||
|
||||
assert_expected_fqdn "$NAME.$DOMAIN" --name=$NAME
|
||||
assert_expected_fqdn "$NAME.$DOMAIN" --name $NAME
|
||||
assert_expected_fqdn "$HOSTNAME" --name=$NAME -h $HOSTNAME
|
||||
assert_expected_fqdn "$HOSTNAME" --name=$NAME --hostname=$HOSTNAME
|
||||
assert_expected_fqdn "$HOSTNAME" --name=$NAME --hostname $HOSTNAME
|
||||
assert_expected_fqdn "$HOSTNAME" -h $HOSTNAME --name=$NAME
|
||||
assert_expected_fqdn "$HOSTNAME" --hostname=$HOSTNAME --name=$NAME
|
||||
assert_expected_fqdn "$HOSTNAME" --hostname $HOSTNAME --name=$NAME
|
||||
|
||||
end_suite
|
||||
@@ -34,6 +34,10 @@ func ServeHTTP(listener net.Listener, version string, server *DNSServer, domain
|
||||
fmt.Fprintln(w, db.Status())
|
||||
})
|
||||
|
||||
muxRouter.Methods("GET").Path("/domain").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, db.Domain())
|
||||
})
|
||||
|
||||
muxRouter.Methods("PUT").Path("/name/{id:.+}/{ip:.+}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
reqError := func(msg string, logmsg string, logargs ...interface{}) {
|
||||
httpErrorAndLog(Warning, w, msg, http.StatusBadRequest, logmsg, logargs...)
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
const (
|
||||
DefaultServerPort = 53 // The default server port
|
||||
DefaultHTTPPort = 6785 // The default http port
|
||||
DefaultCLICfgFile = "/etc/resolv.conf" // default "resolv.conf" file to try to load
|
||||
DefaultLocalTTL = 30 // default TTL for responses for local domain queries
|
||||
DefaultUDPBuflen = 4096 // bigger than the default 512
|
||||
|
||||
@@ -46,7 +46,7 @@ func main() {
|
||||
flag.StringVar(&domain, "domain", weavedns.DefaultLocalDomain, "local domain (ie, 'weave.local.')")
|
||||
flag.IntVar(&wait, "wait", 0, "number of seconds to wait for interface to be created and come up")
|
||||
flag.IntVar(&dnsPort, "dnsport", weavedns.DefaultServerPort, "port to listen to DNS requests")
|
||||
flag.IntVar(&httpPort, "httpport", 6785, "port to listen to HTTP requests")
|
||||
flag.IntVar(&httpPort, "httpport", weavedns.DefaultHTTPPort, "port to listen to HTTP requests")
|
||||
flag.IntVar(&cacheLen, "cache", weavedns.DefaultCacheLen, "cache length")
|
||||
flag.IntVar(&ttl, "ttl", weavedns.DefaultLocalTTL, "TTL (in secs) for responses for local names")
|
||||
flag.BoolVar(&watch, "watch", true, "watch the docker socket for container events")
|
||||
|
||||
@@ -3,12 +3,14 @@ package proxy
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
"github.com/weaveworks/weave/nameserver"
|
||||
)
|
||||
|
||||
type createContainerInterceptor struct{ proxy *Proxy }
|
||||
@@ -43,7 +45,7 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
if err := i.setWeaveWaitEntrypoint(container.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := i.setWeaveDNS(&container); err != nil {
|
||||
if err := i.setWeaveDNS(&container, r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -78,7 +80,7 @@ func (i *createContainerInterceptor) setWeaveWaitEntrypoint(container *docker.Co
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) setWeaveDNS(container *createContainerRequestBody) error {
|
||||
func (i *createContainerInterceptor) setWeaveDNS(container *createContainerRequestBody, r *http.Request) error {
|
||||
if !i.proxy.WithDNS {
|
||||
return nil
|
||||
}
|
||||
@@ -88,9 +90,40 @@ func (i *createContainerInterceptor) setWeaveDNS(container *createContainerReque
|
||||
if len(container.HostConfig.DNSSearch) == 0 {
|
||||
container.HostConfig.DNSSearch = []string{"."}
|
||||
}
|
||||
|
||||
name := r.URL.Query().Get("name")
|
||||
if container.Hostname == "" && name != "" {
|
||||
container.Hostname = name
|
||||
container.Domainname = i.getDNSDomain()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) getDNSDomain() (domain string) {
|
||||
domain = nameserver.DefaultLocalDomain
|
||||
dnsContainer, err := i.proxy.client.InspectContainer("weavedns")
|
||||
if err != nil ||
|
||||
dnsContainer.NetworkSettings == nil ||
|
||||
dnsContainer.NetworkSettings.IPAddress == "" {
|
||||
return
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("http://%s:%d/domain", dnsContainer.NetworkSettings.IPAddress, nameserver.DefaultHTTPPort)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (i *createContainerInterceptor) InterceptResponse(r *http.Response) error {
|
||||
return nil
|
||||
}
|
||||
+3
-1
@@ -127,7 +127,9 @@ option, i.e.
|
||||
|
||||
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.
|
||||
[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.
|
||||
|
||||
## <a name="multi-host"></a>Multi-host example
|
||||
|
||||
|
||||
+14
-6
@@ -29,20 +29,28 @@ 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. Giving any container a hostname in the `.weave.local`
|
||||
domain registers it in weaveDNS. For example:
|
||||
starting them; containers so started also automatically register their
|
||||
container name in the weaveDNS domain. For example:
|
||||
|
||||
```bash
|
||||
$ weave launch
|
||||
$ weave launch-dns 10.2.254.1/24
|
||||
$ weave run 10.2.1.25/24 -ti -h pingme.weave.local ubuntu
|
||||
$ shell1=$(weave run --with-dns 10.2.1.26/24 -ti -h ubuntu.weave.local ubuntu)
|
||||
$ 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)
|
||||
$ docker attach $shell1
|
||||
|
||||
root@ubuntu:/# ping pingme
|
||||
...
|
||||
```
|
||||
|
||||
If you start an application container sans `--with-dns` you can still register
|
||||
it in weaveDNS simply by giving the container a hostname in the
|
||||
`.weave.local.` domain:
|
||||
|
||||
```
|
||||
$ weave run 10.2.1.25/24 -ti -h pingme.weave.local ubuntu
|
||||
```
|
||||
|
||||
Each weaveDNS container started with `launch-dns` needs to be given
|
||||
its own, unique, IP address, in a subnet that is a) common to all
|
||||
weaveDNS containers, b) disjoint from the application subnets, and c)
|
||||
@@ -55,7 +63,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 -h ubuntu2.weave.local ubuntu)
|
||||
host2$ shell2=$(weave run --with-dns 10.2.1.36/24 -ti --name=ubuntu2 ubuntu)
|
||||
host2$ docker attach $shell2
|
||||
|
||||
root@ubuntu2:/# ping pingme
|
||||
@@ -110,7 +118,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 10.2.1.35/24 -ti -h pingme.weave.local ubuntu
|
||||
host2$ weave run --with-dns 10.2.1.35/24 -ti --name=pingme ubuntu
|
||||
host2$ docker attach $shell2
|
||||
|
||||
root@ubuntu2:/# ping -nq -c 1 pingme
|
||||
|
||||
@@ -4,15 +4,17 @@
|
||||
|
||||
C1=10.2.0.78
|
||||
C2=10.2.0.34
|
||||
NAME=seetwo.weave.local
|
||||
C1_NAME=c1.weave.local
|
||||
C2_NAME=seetwo.weave.local
|
||||
|
||||
start_suite "Proxy registers containers with dns"
|
||||
|
||||
weave_on $HOST1 launch-dns 10.2.254.1/24
|
||||
weave_on $HOST1 launch-proxy --with-dns
|
||||
proxy docker_on $HOST1 run -e WEAVE_CIDR=$C2/24 -dt --name=c2 -h $NAME $SMALL_IMAGE /bin/sh
|
||||
proxy docker_on $HOST1 run -e WEAVE_CIDR=$C1/24 -dt --name=c1 $DNS_IMAGE /bin/sh
|
||||
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
|
||||
|
||||
assert_dns_record $HOST1 c1 $NAME $C2
|
||||
assert_dns_record $HOST1 c1 $C2_NAME $C2
|
||||
assert_dns_record $HOST1 c2 $C1_NAME $C1
|
||||
|
||||
end_suite
|
||||
@@ -648,16 +648,45 @@ dns_args() {
|
||||
docker_bridge_ip
|
||||
DNS_ARG="--dns $DOCKER_BRIDGE_IP"
|
||||
DNS_SEARCH_ARG="--dns-search=."
|
||||
for arg in "$@" ; do
|
||||
case $arg in
|
||||
NAME_ARG=""
|
||||
HOSTNAME_SPECIFIED=false
|
||||
while [ $# -gt 0 ] ; do
|
||||
case "$1" in
|
||||
--dns-search=*)
|
||||
DNS_SEARCH_ARG=""
|
||||
shift
|
||||
;;
|
||||
--name)
|
||||
NAME_ARG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--name=*)
|
||||
NAME_ARG="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
-h|--hostname|--hostname=*)
|
||||
HOSTNAME_SPECIFIED=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
DNS_ARGS="$DNS_ARG $DNS_SEARCH_ARG"
|
||||
if [ -n "$NAME_ARG" -a "$HOSTNAME_SPECIFIED" = "false" ] ; then
|
||||
DNS_ARGS="$DNS_ARGS --hostname=$NAME_ARG.$(dns_domain)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Use the weaveDNS REST API to determine the local domain. If weaveDNS is not
|
||||
# running, return the default value ('weave.local.')
|
||||
dns_domain() {
|
||||
if DOMAIN=$(http_call $DNS_CONTAINER_NAME $DNS_HTTP_PORT GET /domain 2>/dev/null) ; then
|
||||
echo $DOMAIN
|
||||
else
|
||||
echo 'weave.local.'
|
||||
fi
|
||||
}
|
||||
|
||||
# Print an error to stderr and return with an indicative exit status
|
||||
@@ -687,9 +716,9 @@ with_container_fqdn() {
|
||||
COMMAND="$2"
|
||||
shift 2
|
||||
|
||||
CONTAINER_FQDN=$(docker inspect --format='{{.Config.Hostname}}.{{.Config.Domainname}}.' $CONTAINER 2>/dev/null) || return 0
|
||||
CONTAINER_FQDN=$(docker inspect --format='{{.Config.Hostname}}.{{.Config.Domainname}}' $CONTAINER 2>/dev/null) || return 0
|
||||
|
||||
if echo "$CONTAINER_FQDN" | grep -qv '\.\.$' ; then
|
||||
if echo "$CONTAINER_FQDN" | grep -Eq '[^.]+\..+' ; then
|
||||
$COMMAND "$CONTAINER" "$CONTAINER_FQDN" "$@"
|
||||
fi
|
||||
}
|
||||
@@ -1069,6 +1098,9 @@ case "$COMMAND" in
|
||||
dns_args "$@"
|
||||
echo -n $DNS_ARGS
|
||||
;;
|
||||
dns-domain)
|
||||
echo $(dns_domain)
|
||||
;;
|
||||
docker-bridge-ip)
|
||||
docker_bridge_ip
|
||||
echo -n $DOCKER_BRIDGE_IP
|
||||
|
||||
Reference in new issue
Block a user