cluster: advertise explicitly for empty addresses (#1386)

memberlist doesn't advertise a valid IP address when the bind address is
empty (":8001") or the unspecified IPv6 address ("[::]:8001).

Signed-off-by: Simon Pasquier <spasquie@redhat.com>
This commit is contained in:
Simon Pasquier 2018-06-07 17:57:01 +02:00 committed by stuart nelson
parent b949f0dc19
commit 9f87f9d6e7
2 changed files with 15 additions and 3 deletions

View File

@ -38,7 +38,7 @@ func calculateAdvertiseAddress(bindAddr, advertiseAddr string) (net.IP, error) {
return ip, nil
}
if bindAddr == "0.0.0.0" {
if isAny(bindAddr) {
privateIP, err := sockaddr.GetPrivateIP()
if err != nil {
return nil, errors.Wrap(err, "failed to get private IP")

View File

@ -122,9 +122,9 @@ func Join(
if err != nil {
return nil, errors.Wrap(err, "invalid listen address")
}
var advertiseHost string
var advertisePort int
if advertiseAddr != "" {
var advertisePortStr string
advertiseHost, advertisePortStr, err = net.SplitHostPort(advertiseAddr)
@ -151,6 +151,11 @@ func Join(
level.Warn(l).Log("err", "this node advertises itself on an unroutable address", "addr", addr.String())
level.Warn(l).Log("err", "this node will be unreachable in the cluster")
level.Warn(l).Log("err", "provide --cluster.advertise-address as a routable IP address or hostname")
} else if isAny(bindAddr) && advertiseHost == "" {
// memberlist doesn't advertise properly when the bind address is empty or unspecified.
level.Info(l).Log("msg", "setting advertise address explicitly", "addr", addr.String(), "port", bindPort)
advertiseHost = addr.String()
advertisePort = bindPort
}
// TODO(fabxc): generate human-readable but random names?
@ -184,7 +189,7 @@ func Join(
cfg.ProbeInterval = probeInterval
cfg.LogOutput = &logWriter{l: l}
if advertiseAddr != "" {
if advertiseHost != "" {
cfg.AdvertiseAddr = advertiseHost
cfg.AdvertisePort = advertisePort
}
@ -667,6 +672,13 @@ func isUnroutable(addr string) bool {
return false
}
func isAny(addr string) bool {
if host, _, err := net.SplitHostPort(addr); err == nil {
addr = host
}
return addr == "" || net.ParseIP(addr).IsUnspecified()
}
// retry executes f every interval seconds until timeout or no error is returned from f.
func retry(interval time.Duration, stopc <-chan struct{}, f func() error) error {
tick := time.NewTicker(interval)