diff --git a/api/client/swarm/init.go b/api/client/swarm/init.go index d543610422..0555243f0d 100644 --- a/api/client/swarm/init.go +++ b/api/client/swarm/init.go @@ -44,8 +44,8 @@ func newInitCommand(dockerCli *client.DockerCli) *cobra.Command { } flags := cmd.Flags() - flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") - flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") + flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") + flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") flags.BoolVar(&opts.forceNewCluster, "force-new-cluster", false, "Force create a new cluster from current state.") addSwarmFlags(flags, &opts.swarmOptions) return cmd diff --git a/api/client/swarm/join.go b/api/client/swarm/join.go index 504cc790f8..de2e15ab23 100644 --- a/api/client/swarm/join.go +++ b/api/client/swarm/join.go @@ -35,8 +35,8 @@ func newJoinCommand(dockerCli *client.DockerCli) *cobra.Command { } flags := cmd.Flags() - flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") - flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") + flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") + flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") flags.StringVar(&opts.token, flagToken, "", "Token for entry into the swarm") return cmd } diff --git a/daemon/cluster/listen_addr.go b/daemon/cluster/listen_addr.go index b293a290b1..c3dbe083ea 100644 --- a/daemon/cluster/listen_addr.go +++ b/daemon/cluster/listen_addr.go @@ -7,10 +7,13 @@ import ( ) var ( - errNoSuchInterface = errors.New("no such interface") - errMultipleIPs = errors.New("could not choose an IP address to advertise since this system has multiple addresses") - errNoIP = errors.New("could not find the system's IP address") - errMustSpecifyListenAddr = errors.New("must specify a listening address because the address to advertise is not recognized as a system address") + errNoSuchInterface = errors.New("no such interface") + errMultipleIPs = errors.New("could not choose an IP address to advertise since this system has multiple addresses") + errNoIP = errors.New("could not find the system's IP address") + errMustSpecifyListenAddr = errors.New("must specify a listening address because the address to advertise is not recognized as a system address") + errBadListenAddr = errors.New("listen address must be an IP address or network interface (with optional port number)") + errBadAdvertiseAddr = errors.New("advertise address must be an IP address or network interface (with optional port number)") + errBadDefaultAdvertiseAddr = errors.New("default advertise address must be an IP address or network interface (without a port number)") ) func resolveListenAddr(specifiedAddr string) (string, string, error) { @@ -29,6 +32,11 @@ func resolveListenAddr(specifiedAddr string) (string, string, error) { return "", "", err } + // If it's not an interface, it must be an IP (for now) + if net.ParseIP(specifiedHost) == nil { + return "", "", errBadListenAddr + } + return specifiedHost, specifiedPort, nil } @@ -61,6 +69,11 @@ func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (st return "", "", err } + // If it's not an interface, it must be an IP (for now) + if net.ParseIP(advertiseHost) == nil { + return "", "", errBadAdvertiseAddr + } + return advertiseHost, advertisePort, nil } @@ -76,6 +89,11 @@ func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (st return "", "", err } + // If it's not an interface, it must be an IP (for now) + if net.ParseIP(c.config.DefaultAdvertiseAddr) == nil { + return "", "", errBadDefaultAdvertiseAddr + } + return c.config.DefaultAdvertiseAddr, listenAddrPort, nil } diff --git a/docs/reference/api/docker_remote_api_v1.24.md b/docs/reference/api/docker_remote_api_v1.24.md index 071a6ffa10..a583d748c1 100644 --- a/docs/reference/api/docker_remote_api_v1.24.md +++ b/docs/reference/api/docker_remote_api_v1.24.md @@ -3592,6 +3592,7 @@ Initialize a new Swarm { "ListenAddr": "0.0.0.0:4500", + "AdvertiseAddr": "192.168.1.1:4500", "ForceNewCluster": false, "Spec": { "Orchestration": {}, @@ -3620,6 +3621,11 @@ JSON Parameters: address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port number, like `eth0:4567`. If the port number is omitted, the default swarm listening port is used. +- **AdvertiseAddr** – Externally reachable address advertised to other nodes. This can either be + an address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port + number, like `eth0:4567`. If the port number is omitted, the port number from the listen + address is used. If `AdvertiseAddr` is not specified, it will be automatically detected when + possible. - **ForceNewCluster** – Force creating a new Swarm even if already part of one. - **Spec** – Configuration settings of the new Swarm. - **Orchestration** – Configuration settings for the orchestration aspects of the Swarm. @@ -3660,6 +3666,7 @@ Join an existing new Swarm { "ListenAddr": "0.0.0.0:4500", + "AdvertiseAddr: "192.168.1.1:4500", "RemoteAddrs": ["node1:4500"], "JoinToken": "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" } @@ -3680,6 +3687,11 @@ JSON Parameters: - **ListenAddr** – Listen address used for inter-manager communication if the node gets promoted to manager, as well as determining the networking interface used for the VXLAN Tunnel Endpoint (VTEP). +- **AdvertiseAddr** – Externally reachable address advertised to other nodes. This can either be + an address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port + number, like `eth0:4567`. If the port number is omitted, the port number from the listen + address is used. If `AdvertiseAddr` is not specified, it will be automatically detected when + possible. - **RemoteAddr** – Address of any manager node already participating in the Swarm to join. - **JoinToken** – Secret token for joining this Swarm. diff --git a/docs/reference/commandline/swarm_init.md b/docs/reference/commandline/swarm_init.md index fdc8b1039e..a7b936991d 100644 --- a/docs/reference/commandline/swarm_init.md +++ b/docs/reference/commandline/swarm_init.md @@ -18,13 +18,13 @@ Usage: docker swarm init [OPTIONS] Initialize a swarm Options: - --advertise-addr value Advertised address (format: [:port]) + --advertise-addr value Advertised address (format: [:port]) --cert-expiry duration Validity period for node certificates (default 2160h0m0s) --dispatcher-heartbeat duration Dispatcher heartbeat period (default 5s) --external-ca value Specifications of one or more certificate signing endpoints --force-new-cluster Force create a new cluster from current state. --help Print usage - --listen-addr value Listen address (format: [:port]) + --listen-addr value Listen address (format: [:port]) --task-history-limit int Task history retention limit (default 5) ``` @@ -80,7 +80,7 @@ The node listens for inbound Swarm manager traffic on this address. The default 0.0.0.0:2377. It is also possible to specify a network interface to listen on that interface's address; for example `--listen-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address or interface name, the default port 2377 will be used. ### `--advertise-addr value` @@ -95,7 +95,7 @@ inter-manager communication and overlay networking. It is also possible to specify a network interface to advertise that interface's address; for example `--advertise-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address or interface name, the default port 2377 will be used. ### `--task-history-limit` diff --git a/docs/reference/commandline/swarm_join.md b/docs/reference/commandline/swarm_join.md index d6e20a5cf1..d207c2c9f3 100644 --- a/docs/reference/commandline/swarm_join.md +++ b/docs/reference/commandline/swarm_join.md @@ -18,9 +18,9 @@ Usage: docker swarm join [OPTIONS] HOST:PORT Join a swarm as a node and/or manager Options: - --advertise-addr value Advertised address (format: [:port]) + --advertise-addr value Advertised address (format: [:port]) --help Print usage - --listen-addr value Listen address + --listen-addr value Listen address (format: [:port) --token string Token for entry into the swarm ``` @@ -65,7 +65,7 @@ If the node is a manager, it will listen for inbound Swarm manager traffic on th address. The default is to listen on 0.0.0.0:2377. It is also possible to specify a network interface to listen on that interface's address; for example `--listen-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address, or interface name, the default port 2377 will be used. This flag is generally not necessary when joining an existing swarm. @@ -82,7 +82,7 @@ communication and overlay networking. It is also possible to specify a network interface to advertise that interface's address; for example `--advertise-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address, or interface name, the default port 2377 will be used. This flag is generally not necessary when joining an existing swarm. diff --git a/man/dockerd.8.md b/man/dockerd.8.md index 15e2d9635a..a098a708a3 100644 --- a/man/dockerd.8.md +++ b/man/dockerd.8.md @@ -55,7 +55,7 @@ dockerd - Enable daemon mode [**-s**|**--storage-driver**[=*STORAGE-DRIVER*]] [**--selinux-enabled**] [**--storage-opt**[=*[]*]] -[**--swarm-default-advertise-addr**[=*IP|HOSTNAME|INTERFACE*]] +[**--swarm-default-advertise-addr**[=*IP|INTERFACE*]] [**--tls**] [**--tlscacert**[=*~/.docker/ca.pem*]] [**--tlscert**[=*~/.docker/cert.pem*]] @@ -240,7 +240,7 @@ output otherwise. **--storage-opt**=[] Set storage driver options. See STORAGE DRIVER OPTIONS. -**--swarm-default-advertise-addr**=*IP|HOSTNAME|INTERFACE* +**--swarm-default-advertise-addr**=*IP|INTERFACE* Set default address or interface for swarm to advertise as its externally-reachable address to other cluster members. This can be a hostname, an IP address, or an interface such as `eth0`. A port cannot be specified with this option.