-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allows disabling WAN federation by setting serf WAN port to -1 #3984
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -32,7 +32,6 @@ import ( | |||||||||||||||||||||||||||||||
"github.com/hashicorp/consul/types" | ||||||||||||||||||||||||||||||||
"github.com/hashicorp/raft" | ||||||||||||||||||||||||||||||||
raftboltdb "github.com/hashicorp/raft-boltdb" | ||||||||||||||||||||||||||||||||
"github.com/hashicorp/serf/coordinate" | ||||||||||||||||||||||||||||||||
"github.com/hashicorp/serf/serf" | ||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
|
@@ -75,6 +74,10 @@ const ( | |||||||||||||||||||||||||||||||
raftRemoveGracePeriod = 5 * time.Second | ||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
var ( | ||||||||||||||||||||||||||||||||
ErrWANFederationDisabled = fmt.Errorf("WAN Federation is disabled") | ||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Server is Consul server which manages the service discovery, | ||||||||||||||||||||||||||||||||
// health checking, DC forwarding, Raft, and multiple Serf pools. | ||||||||||||||||||||||||||||||||
type Server struct { | ||||||||||||||||||||||||||||||||
|
@@ -344,25 +347,28 @@ func NewServerLogger(config *Config, logger *log.Logger, tokens *token.Store) (* | |||||||||||||||||||||||||||||||
// created, so we can pull it out from there reliably, even though it's | ||||||||||||||||||||||||||||||||
// a little gross to be reading the updated config. | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Initialize the WAN Serf. | ||||||||||||||||||||||||||||||||
serfBindPortWAN := config.SerfWANConfig.MemberlistConfig.BindPort | ||||||||||||||||||||||||||||||||
s.serfWAN, err = s.setupSerf(config.SerfWANConfig, s.eventChWAN, serfWANSnapshot, true, serfBindPortWAN, "", s.Listener) | ||||||||||||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||||||||||||
s.Shutdown() | ||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("Failed to start WAN Serf: %v", err) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// See big comment above why we are doing this. | ||||||||||||||||||||||||||||||||
if serfBindPortWAN == 0 { | ||||||||||||||||||||||||||||||||
// Initialize the WAN Serf if enabled | ||||||||||||||||||||||||||||||||
serfBindPortWAN := -1 | ||||||||||||||||||||||||||||||||
if config.SerfWANConfig != nil { | ||||||||||||||||||||||||||||||||
serfBindPortWAN = config.SerfWANConfig.MemberlistConfig.BindPort | ||||||||||||||||||||||||||||||||
s.serfWAN, err = s.setupSerf(config.SerfWANConfig, s.eventChWAN, serfWANSnapshot, true, serfBindPortWAN, "", s.Listener) | ||||||||||||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||||||||||||
s.Shutdown() | ||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("Failed to start WAN Serf: %v", err) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
// See big comment above why we are doing this. | ||||||||||||||||||||||||||||||||
if serfBindPortWAN == 0 { | ||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("Failed to get dynamic bind port for WAN Serf") | ||||||||||||||||||||||||||||||||
serfBindPortWAN = config.SerfWANConfig.MemberlistConfig.BindPort | ||||||||||||||||||||||||||||||||
if serfBindPortWAN == 0 { | ||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("Failed to get dynamic bind port for WAN Serf") | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
s.logger.Printf("[INFO] agent: Serf WAN TCP bound to port %d", serfBindPortWAN) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
s.logger.Printf("[INFO] agent: Serf WAN TCP bound to port %d", serfBindPortWAN) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Initialize the LAN segments before the default LAN Serf so we have | ||||||||||||||||||||||||||||||||
// updated port information to publish there. | ||||||||||||||||||||||||||||||||
// TODO preetha: why is this passing WAN port to create segments? | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like just a remnant of calling the same setupSerf function for segments; the servers are already in the default serf LAN before any segments start, so I don't think the segment Serfs need the WAN port tag set. |
||||||||||||||||||||||||||||||||
if err := s.setupSegments(config, serfBindPortWAN, segmentListeners); err != nil { | ||||||||||||||||||||||||||||||||
s.Shutdown() | ||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("Failed to setup network segments: %v", err) | ||||||||||||||||||||||||||||||||
|
@@ -380,20 +386,22 @@ func NewServerLogger(config *Config, logger *log.Logger, tokens *token.Store) (* | |||||||||||||||||||||||||||||||
s.floodSegments(config) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Add a "static route" to the WAN Serf and hook it up to Serf events. | ||||||||||||||||||||||||||||||||
if err := s.router.AddArea(types.AreaWAN, s.serfWAN, s.connPool, s.config.VerifyOutgoing); err != nil { | ||||||||||||||||||||||||||||||||
s.Shutdown() | ||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("Failed to add WAN serf route: %v", err) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
go router.HandleSerfEvents(s.logger, s.router, types.AreaWAN, s.serfWAN.ShutdownCh(), s.eventChWAN) | ||||||||||||||||||||||||||||||||
if s.serfWAN != nil { | ||||||||||||||||||||||||||||||||
if err := s.router.AddArea(types.AreaWAN, s.serfWAN, s.connPool, s.config.VerifyOutgoing); err != nil { | ||||||||||||||||||||||||||||||||
s.Shutdown() | ||||||||||||||||||||||||||||||||
return nil, fmt.Errorf("Failed to add WAN serf route: %v", err) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
go router.HandleSerfEvents(s.logger, s.router, types.AreaWAN, s.serfWAN.ShutdownCh(), s.eventChWAN) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Fire up the LAN <-> WAN join flooder. | ||||||||||||||||||||||||||||||||
portFn := func(s *metadata.Server) (int, bool) { | ||||||||||||||||||||||||||||||||
if s.WanJoinPort > 0 { | ||||||||||||||||||||||||||||||||
return s.WanJoinPort, true | ||||||||||||||||||||||||||||||||
// Fire up the LAN <-> WAN join flooder. | ||||||||||||||||||||||||||||||||
portFn := func(s *metadata.Server) (int, bool) { | ||||||||||||||||||||||||||||||||
if s.WanJoinPort > 0 { | ||||||||||||||||||||||||||||||||
return s.WanJoinPort, true | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
return 0, false | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
return 0, false | ||||||||||||||||||||||||||||||||
go s.Flood(nil, portFn, s.serfWAN) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
go s.Flood(nil, portFn, s.serfWAN) | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Start monitoring leadership. This must happen after Serf is set up | ||||||||||||||||||||||||||||||||
// since it can fire events when leadership is obtained. | ||||||||||||||||||||||||||||||||
|
@@ -831,6 +839,9 @@ func (s *Server) JoinLAN(addrs []string) (int, error) { | |||||||||||||||||||||||||||||||
// The target address should be another node listening on the | ||||||||||||||||||||||||||||||||
// Serf WAN address | ||||||||||||||||||||||||||||||||
func (s *Server) JoinWAN(addrs []string) (int, error) { | ||||||||||||||||||||||||||||||||
if s.serfWAN == nil { | ||||||||||||||||||||||||||||||||
return 0, ErrWANFederationDisabled | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
return s.serfWAN.Join(addrs, true) | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
|
@@ -846,6 +857,9 @@ func (s *Server) LANMembers() []serf.Member { | |||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// WANMembers is used to return the members of the LAN cluster | ||||||||||||||||||||||||||||||||
func (s *Server) WANMembers() []serf.Member { | ||||||||||||||||||||||||||||||||
if s.serfWAN == nil { | ||||||||||||||||||||||||||||||||
return nil | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
return s.serfWAN.Members() | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
|
@@ -854,8 +868,10 @@ func (s *Server) RemoveFailedNode(node string) error { | |||||||||||||||||||||||||||||||
if err := s.serfLAN.RemoveFailedNode(node); err != nil { | ||||||||||||||||||||||||||||||||
return err | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
if err := s.serfWAN.RemoveFailedNode(node); err != nil { | ||||||||||||||||||||||||||||||||
return err | ||||||||||||||||||||||||||||||||
if s.serfWAN != nil { | ||||||||||||||||||||||||||||||||
if err := s.serfWAN.RemoveFailedNode(node); err != nil { | ||||||||||||||||||||||||||||||||
return err | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
return nil | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
@@ -872,12 +888,19 @@ func (s *Server) KeyManagerLAN() *serf.KeyManager { | |||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// KeyManagerWAN returns the WAN Serf keyring manager | ||||||||||||||||||||||||||||||||
func (s *Server) KeyManagerWAN() *serf.KeyManager { | ||||||||||||||||||||||||||||||||
if s.serfWAN == nil { | ||||||||||||||||||||||||||||||||
return nil | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the record I verified all call paths to this to check none will panic on a nil. It's only called from an internal state machine routine when working with WAN keyrings which should be disabled by code in this PR. consul/agent/consul/internal_endpoint.go Lines 143 to 151 in 17681f0
called from consul/agent/consul/internal_endpoint.go Lines 131 to 136 in 17681f0
which is disabled above. |
||||||||||||||||||||||||||||||||
return s.serfWAN.KeyManager() | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Encrypted determines if gossip is encrypted | ||||||||||||||||||||||||||||||||
func (s *Server) Encrypted() bool { | ||||||||||||||||||||||||||||||||
return s.serfLAN.EncryptionEnabled() && s.serfWAN.EncryptionEnabled() | ||||||||||||||||||||||||||||||||
LANEncrypted := s.serfLAN.EncryptionEnabled() | ||||||||||||||||||||||||||||||||
if s.serfWAN == nil { | ||||||||||||||||||||||||||||||||
return LANEncrypted | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
return LANEncrypted && s.serfWAN.EncryptionEnabled() | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// LANSegments returns a map of LAN segments by name | ||||||||||||||||||||||||||||||||
|
@@ -995,9 +1018,11 @@ func (s *Server) Stats() map[string]map[string]string { | |||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||
"raft": s.raft.Stats(), | ||||||||||||||||||||||||||||||||
"serf_lan": s.serfLAN.Stats(), | ||||||||||||||||||||||||||||||||
"serf_wan": s.serfWAN.Stats(), | ||||||||||||||||||||||||||||||||
"runtime": runtimeStats(), | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
if s.serfWAN != nil { | ||||||||||||||||||||||||||||||||
stats["serf_wan"] = s.serfWAN.Stats() | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
return stats | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
|
@@ -1019,11 +1044,6 @@ func (s *Server) GetLANCoordinate() (lib.CoordinateSet, error) { | |||||||||||||||||||||||||||||||
return cs, nil | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// GetWANCoordinate returns the coordinate of the server in the WAN gossip pool. | ||||||||||||||||||||||||||||||||
func (s *Server) GetWANCoordinate() (*coordinate.Coordinate, error) { | ||||||||||||||||||||||||||||||||
return s.serfWAN.GetCoordinate() | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this not used anywhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup |
||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
// Atomically sets a readiness state flag when leadership is obtained, to indicate that server is past its barrier write | ||||||||||||||||||||||||||||||||
func (s *Server) setConsistentReadReady() { | ||||||||||||||||||||||||||||||||
atomic.StoreInt32(&s.readyForConsistentReads, 1) | ||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -37,7 +37,9 @@ func (s *Server) setupSerf(conf *serf.Config, ch chan serf.Event, path string, w | |||||||||||||||
conf.NodeName = fmt.Sprintf("%s.%s", s.config.NodeName, s.config.Datacenter) | ||||||||||||||||
} else { | ||||||||||||||||
conf.NodeName = s.config.NodeName | ||||||||||||||||
conf.Tags["wan_join_port"] = fmt.Sprintf("%d", wanPort) | ||||||||||||||||
if wanPort > 0 { | ||||||||||||||||
conf.Tags["wan_join_port"] = fmt.Sprintf("%d", wanPort) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the record, I checked and it seems the only consumer of that tag in our code already handles the case where it's not present: consul/agent/metadata/server.go Lines 119 to 125 in 7de57ba
|
||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
conf.Tags["role"] = "consul" | ||||||||||||||||
conf.Tags["dc"] = s.config.Datacenter | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -116,6 +116,9 @@ func (r *Router) Shutdown() { | |
|
||
// AddArea registers a new network area with the router. | ||
func (r *Router) AddArea(areaID types.AreaID, cluster RouterSerfCluster, pinger Pinger, useTLS bool) error { | ||
if cluster == nil { | ||
return nil | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is returning an error appropriate here given that we guard the call in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was trying to be defensive here but its better to panic if there are new call sites added for this method in the future, will remove |
||
r.Lock() | ||
defer r.Unlock() | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be "federationEnabled"