diff --git a/agent/proxycfg/state.go b/agent/proxycfg/state.go index 97801a84e..7f46177ea 100644 --- a/agent/proxycfg/state.go +++ b/agent/proxycfg/state.go @@ -1568,7 +1568,7 @@ func (s *state) hostnameEndpoints(loggerName string, localDC string, nodes struc sid := nodes[0].Service.CompoundServiceName() s.logger.Named(loggerName). - Warn("service contains instances with mix of hostnames and IP addresses; only hostnames will be passed to Envoy.", + Warn("service contains instances with mix of hostnames and IP addresses; only hostnames will be passed to Envoy", "dc", dc, "service", sid.String()) } return resp diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 99c15a34a..c081a7bdf 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/hashicorp/consul/logging" "time" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" @@ -582,6 +583,7 @@ type gatewayClusterOpts struct { hostnameEndpoints structs.CheckServiceNodes } +// makeGatewayCluster creates an Envoy cluster for a mesh or terminating gateway func (s *Server) makeGatewayCluster(snap *proxycfg.ConfigSnapshot, opts gatewayClusterOpts) *envoy.Cluster { cfg, err := ParseGatewayConfig(snap.Proxy.Config) if err != nil { @@ -631,11 +633,52 @@ func (s *Server) makeGatewayCluster(snap *proxycfg.ConfigSnapshot, opts gatewayC } cluster.ClusterDiscoveryType = &discoveryType - endpoints := make([]envoyendpoint.LbEndpoint, 0, len(opts.hostnameEndpoints)) + endpoints := make([]envoyendpoint.LbEndpoint, 0, 1) + uniqueHostnames := make(map[string]bool) - for _, e := range opts.hostnameEndpoints { - endpoints = append(endpoints, makeLbEndpoint(e, opts.isRemote, opts.onlyPassing)) + var ( + hostname string + idx int + ) + for i, e := range opts.hostnameEndpoints { + addr, port := e.BestAddress(opts.isRemote) + uniqueHostnames[addr] = true + + health, weight := calculateEndpointHealthAndWeight(e, opts.onlyPassing) + if health == envoycore.HealthStatus_UNHEALTHY { + continue + } + + if len(endpoints) == 0 { + endpoints = append(endpoints, makeLbEndpoint(addr, port, health, weight)) + + hostname = addr + idx = i + break + } } + + dc := opts.hostnameEndpoints[idx].Node.Datacenter + service := opts.hostnameEndpoints[idx].Service.CompoundServiceName() + + loggerName := logging.TerminatingGateway + if snap.Kind == structs.ServiceKindMeshGateway { + loggerName = logging.MeshGateway + } + + if len(endpoints) == 0 { + s.Logger.Named(loggerName). + Warn("service does not contain any healthy instances, skipping Envoy cluster creation", + "dc", dc, "service", service.String()) + + return nil + } + if len(uniqueHostnames) > 1 { + s.Logger.Named(loggerName). + Warn(fmt.Sprintf("service contains instances with more than one unique hostname; only %q be resolved by Envoy", hostname), + "dc", dc, "service", service.String()) + } + cluster.LoadAssignment = &envoy.ClusterLoadAssignment{ ClusterName: cluster.Name, Endpoints: []envoyendpoint.LocalityLbEndpoints{ @@ -683,10 +726,7 @@ func makeThresholdsIfNeeded(limits UpstreamLimits) []*envoycluster.CircuitBreake return []*envoycluster.CircuitBreakers_Thresholds{threshold} } -func makeLbEndpoint(csn structs.CheckServiceNode, isRemote, onlyPassing bool) envoyendpoint.LbEndpoint { - health, weight := calculateEndpointHealthAndWeight(csn, onlyPassing) - addr, port := csn.BestAddress(isRemote) - +func makeLbEndpoint(addr string, port int, health envoycore.HealthStatus, weight int) envoyendpoint.LbEndpoint { return envoyendpoint.LbEndpoint{ HostIdentifier: &envoyendpoint.LbEndpoint_Endpoint{ Endpoint: &envoyendpoint.Endpoint{ diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.golden index 95e66aad5..b3401212b 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.golden @@ -54,18 +54,6 @@ }, "healthStatus": "HEALTHY", "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "456.us-west-2.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 } ] } diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.golden index 95e66aad5..b3401212b 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.golden @@ -54,18 +54,6 @@ }, "healthStatus": "HEALTHY", "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "456.us-west-2.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 } ] } diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.golden index 7941d1510..56b4721ea 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.golden @@ -54,18 +54,6 @@ }, "healthStatus": "HEALTHY", "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "456.us-west-2.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 } ] } diff --git a/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.golden b/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.golden index a2b1ade8e..68093d0bc 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.golden @@ -54,18 +54,6 @@ }, "healthStatus": "HEALTHY", "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "456.us-west-2.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 } ] } diff --git a/agent/xds/testdata/clusters/mesh-gateway.golden b/agent/xds/testdata/clusters/mesh-gateway.golden index a2b1ade8e..68093d0bc 100644 --- a/agent/xds/testdata/clusters/mesh-gateway.golden +++ b/agent/xds/testdata/clusters/mesh-gateway.golden @@ -54,18 +54,6 @@ }, "healthStatus": "HEALTHY", "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "456.us-west-2.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 } ] } diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.golden index 1ff54b0be..81df07784 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.golden @@ -65,18 +65,6 @@ "endpoints": [ { "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - }, { "endpoint": { "address": { diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.golden index e9261c21c..9d6568baf 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.golden @@ -11,18 +11,6 @@ "endpoints": [ { "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - }, { "endpoint": { "address": { diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.golden index e9261c21c..9d6568baf 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.golden @@ -11,18 +11,6 @@ "endpoints": [ { "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - }, { "endpoint": { "address": { diff --git a/agent/xds/testdata/clusters/terminating-gateway.golden b/agent/xds/testdata/clusters/terminating-gateway.golden index a4c473305..1dde72869 100644 --- a/agent/xds/testdata/clusters/terminating-gateway.golden +++ b/agent/xds/testdata/clusters/terminating-gateway.golden @@ -11,18 +11,6 @@ "endpoints": [ { "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.mydomain", - "portValue": 8081 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - }, { "endpoint": { "address": {