[proxy] More flexible container name -> hostname derivation
Provides to new two new flags: `--hostname-match <regexp>` and `--hostname-replacement <replacement>`. When launching a container, its name matched against regular expression `<regexp>`. Then, based on that match, `<replacement>` will be used to generate a hostname, which will ultimately be handed over to weaveDNS for registration. The substitution is implemented with https://golang.org/pkg/regexp/#Regexp.ReplaceAllString . Thus, references to regexp substitution groups should be prepended with a dollar sign. For instance, if we provide `--hostname-match '^aws-[0-9]+-(.*)$'` and `--hostname-replacement 'my-app-$1'`, running a container named `aws-12798186823-foo` through WeaveProxy will lead to WeaveDNS registering `my-app-foo`. Closes #1018
This commit is contained in:
1 parent
bbacaa42b8
commit
4f82dc97fd
6 files changed
+92
-15
No files matched your search
@@ -51,6 +51,8 @@ func main() {
|
||||
mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit")
|
||||
mflag.StringVar(&logLevel, []string{"-log-level"}, "info", "logging level (debug, info, warning, error)")
|
||||
ListVar(&c.ListenAddrs, []string{"H"}, defaultListenAddrs, "addresses on which to listen")
|
||||
mflag.StringVar(&c.HostnameMatch, []string{"-hostname-match"}, "(.*)", "Regexp pattern to apply on container names (e.g. '^aws-[0-9]+-(.*)$')")
|
||||
mflag.StringVar(&c.HostnameReplacement, []string{"-hostname-replacement"}, "$1", "Expression to generate hostnames based on matches from --hostname-match (e.g. 'my-app-$1')")
|
||||
mflag.BoolVar(&c.NoDefaultIPAM, []string{"#-no-default-ipam", "-no-default-ipalloc"}, false, "do not automatically allocate addresses for containers without a WEAVE_CIDR")
|
||||
mflag.BoolVar(&c.NoRewriteHosts, []string{"no-rewrite-hosts"}, false, "do not automatically rewrite /etc/hosts. Use if you need the docker IP to remain in /etc/hosts")
|
||||
mflag.StringVar(&c.TLSConfig.CACert, []string{"#tlscacert", "-tlscacert"}, "", "Trust certs signed only by this CA")
|
||||
|
||||
@@ -58,7 +58,9 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
if err := i.setWeaveWaitEntrypoint(container.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := i.setWeaveDNS(&container, r.URL.Query().Get("name")); err != nil {
|
||||
containerName := r.URL.Query().Get("name")
|
||||
hostname := i.proxy.hostnameMatchRegexp.ReplaceAllString(containerName, i.proxy.HostnameReplacement)
|
||||
if err := i.setWeaveDNS(&container, hostname); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+25
-14
@@ -15,11 +15,13 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultCaFile = "ca.pem"
|
||||
defaultKeyFile = "key.pem"
|
||||
defaultCertFile = "cert.pem"
|
||||
dockerSock = "/var/run/docker.sock"
|
||||
dockerSockUnix = "unix://" + dockerSock
|
||||
defaultCaFile = "ca.pem"
|
||||
defaultKeyFile = "key.pem"
|
||||
defaultCertFile = "cert.pem"
|
||||
dockerSock = "/var/run/docker.sock"
|
||||
dockerSockUnix = "unix://" + dockerSock
|
||||
substitutionPatternName = "pattern"
|
||||
substitutionReplacementName = "replacement"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -29,19 +31,22 @@ var (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ListenAddrs []string
|
||||
NoDefaultIPAM bool
|
||||
NoRewriteHosts bool
|
||||
TLSConfig TLSConfig
|
||||
Version string
|
||||
WithDNS bool
|
||||
WithoutDNS bool
|
||||
HostnameMatch string
|
||||
HostnameReplacement string
|
||||
ListenAddrs []string
|
||||
NoDefaultIPAM bool
|
||||
NoRewriteHosts bool
|
||||
TLSConfig TLSConfig
|
||||
Version string
|
||||
WithDNS bool
|
||||
WithoutDNS bool
|
||||
}
|
||||
|
||||
type Proxy struct {
|
||||
Config
|
||||
client *docker.Client
|
||||
dockerBridgeIP string
|
||||
client *docker.Client
|
||||
dockerBridgeIP string
|
||||
hostnameMatchRegexp *regexp.Regexp
|
||||
}
|
||||
|
||||
func NewProxy(c Config) (*Proxy, error) {
|
||||
@@ -65,6 +70,12 @@ func NewProxy(c Config) (*Proxy, error) {
|
||||
p.dockerBridgeIP = string(dockerBridgeIP)
|
||||
}
|
||||
|
||||
p.hostnameMatchRegexp, err = regexp.Compile(c.HostnameMatch)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Incorrect hostname match '%s': %s", c.HostnameMatch, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,35 @@ automatically if it is running at the point when they are started -
|
||||
see the [weaveDNS usage](weavedns.html#usage) section for an in-depth
|
||||
explanation of the behaviour and how to control it.
|
||||
|
||||
Typicaly, the proxy will pass on container names as-is to [weaveDNS](weavedns.html)
|
||||
for registration. However, there are situations in which the final container
|
||||
name is out of the user's control (e.g. when using Docker orchestrators which
|
||||
append control/namespacing identifiers to the original container names).
|
||||
|
||||
For those situations, the proxy provides two flags: `--hostname-match <regexp>`
|
||||
and `--hostname-replacement <replacement>`. When launching a container, its name
|
||||
matched against regular expression `<regexp>`. Then, based on that match,
|
||||
`<replacement>` will be used to generate a hostname, which will ultimately be
|
||||
handed over to weaveDNS for registration.
|
||||
|
||||
For instance, if we launch the proxy using
|
||||
`--hostname-match '^aws-[0-9]+-(.*)$'` and `--hostname-replacement 'my-app-$1'`
|
||||
|
||||
host1$ weave launch-router && weave launch-dns && weave launch-proxy --hostname-match '^aws-[0-9]+-(.*)$' and --hostname-replacement 'my-app-$1'
|
||||
host1$ eval "$(weave env)"
|
||||
|
||||
then, running a container named `aws-12798186823-foo` will lead to weaveDNS registering
|
||||
hostname `my-app-foo` and not `aws-12798186823-foo`.
|
||||
|
||||
host1$ docker run -ti --name=aws-12798186823-foo ubuntu ping my-app-foo
|
||||
PING my-app-foo.weave.local (10.32.0.2) 56(84) bytes of data.
|
||||
64 bytes from my-app-foo.weave.local (10.32.0.2): icmp_seq=1 ttl=64 time=0.027 ms
|
||||
64 bytes from my-app-foo.weave.local (10.32.0.2): icmp_seq=2 ttl=64 time=0.067 ms
|
||||
|
||||
Note how regexp substitution groups should be prepended with a dollar sign
|
||||
(e.g. `$1`). For further details on the regular expression syntax please see
|
||||
[Google's re2 documentation](https://github.com/google/re2/wiki/Syntax).
|
||||
|
||||
## <a name="tls"></a>Securing the docker communication with TLS
|
||||
|
||||
If you are
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#! /bin/bash
|
||||
|
||||
. ./config.sh
|
||||
|
||||
C1=10.2.0.78
|
||||
C2=10.2.0.34
|
||||
C3=10.2.0.57
|
||||
CNAME1=qiuds71y827hdi-seeone-1io9qd9i0wd
|
||||
NAME1=seeone.weave.local
|
||||
CNAME2=124DJKSNK812-seetwo-128hbaJ881
|
||||
NAME2=seetwo.weave.local
|
||||
CNAME3=doesnotmatchpattern
|
||||
NAME3=doesnotmatchpattern.weave.local
|
||||
|
||||
start_container() {
|
||||
proxy docker_on $HOST1 run "$@" -dt $DNS_IMAGE /bin/sh
|
||||
}
|
||||
|
||||
start_suite "Hostname derivation through container name substitutions"
|
||||
|
||||
weave_on $HOST1 launch-dns 10.2.254.1/24
|
||||
weave_on $HOST1 launch-proxy --hostname-match '^[^-]+-(?P<appname>[^-]*)-[^-]+$' --hostname-replacement '$appname'
|
||||
|
||||
start_container -e WEAVE_CIDR=$C1/24 --name=$CNAME1
|
||||
start_container -e WEAVE_CIDR=$C2/24 --name=$CNAME2
|
||||
start_container -e WEAVE_CIDR=$C3/24 --name=$CNAME3
|
||||
|
||||
assert_dns_a_record $HOST1 $CNAME1 $NAME2 $C2
|
||||
assert_dns_a_record $HOST1 $CNAME2 $NAME3 $C3
|
||||
assert_dns_a_record $HOST1 $CNAME3 $NAME1 $C1
|
||||
|
||||
end_suite
|
||||
@@ -37,6 +37,7 @@ weave launch-router [--password <password>] [--nickname <nickname>]
|
||||
weave launch-dns [<addr>]
|
||||
weave launch-proxy [-H <endpoint>] [--with-dns | --without-dns]
|
||||
[--no-default-ipalloc] [--no-rewrite-hosts]
|
||||
[[--hostname-match <regexp>] [--hostname-replacement <replacement>]]
|
||||
weave connect [--replace] [<peer> ...]
|
||||
weave forget <peer> ...
|
||||
weave run [--with-dns | --without-dns] [<addr> ...]
|
||||
|
||||
Reference in new issue
Block a user