diff --git a/api/server/router/system/system_routes.go b/api/server/router/system/system_routes.go index 365095159a..2d496a189c 100644 --- a/api/server/router/system/system_routes.go +++ b/api/server/router/system/system_routes.go @@ -50,6 +50,7 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht } if s.cluster != nil { info.Swarm = s.cluster.Info() + info.Warnings = append(info.Warnings, info.Swarm.Warnings...) } if versions.LessThan(httputils.VersionFromContext(ctx), "1.25") { diff --git a/api/types/swarm/swarm.go b/api/types/swarm/swarm.go index 484cd0be7f..b25f999646 100644 --- a/api/types/swarm/swarm.go +++ b/api/types/swarm/swarm.go @@ -209,6 +209,8 @@ type Info struct { Managers int `json:",omitempty"` Cluster *ClusterInfo `json:",omitempty"` + + Warnings []string `json:",omitempty"` } // Peer represents a peer. diff --git a/daemon/cluster/swarm.go b/daemon/cluster/swarm.go index 8cc172e9ce..18a909199a 100644 --- a/daemon/cluster/swarm.go +++ b/daemon/cluster/swarm.go @@ -459,6 +459,20 @@ func (c *Cluster) Info() types.Info { } } } + + switch info.LocalNodeState { + case types.LocalNodeStateInactive, types.LocalNodeStateLocked, types.LocalNodeStateError: + // nothing to do + default: + if info.Managers == 2 { + const warn string = `WARNING: Running Swarm in a two-manager configuration. This configuration provides + no fault tolerance, and poses a high risk to loose control over the cluster. + Refer to https://docs.docker.com/engine/swarm/admin_guide/ to configure the + Swarm for fault-tolerance.` + + info.Warnings = append(info.Warnings, warn) + } + } } if state.swarmNode != nil {