Skip to content

Commit 8cb7b95

Browse files
committed
Fix the "supress health checks when only one backing service" logic
Previously we had attempted to suppress the health checks, but it was looking at the endpoints of the service, not the servers that back the route. The problem is that if we just look at endpoints, then if a route has two backing services, each with one endpoint, we would incorrectly suppress the health checks. This is the third attempt. I had missed a case in the last one, so now the logic is moved to be computed and recorded by the router controller, but used in the template. Fixes bug 1507664 (https://bugzilla.redhat.com/show_bug.cgi?id=1507664)
1 parent e4ac5b0 commit 8cb7b95

File tree

3 files changed

+43
-18
lines changed

3 files changed

+43
-18
lines changed

images/router/haproxy/conf/haproxy-config.template

+2-4
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,8 @@ backend be_secure:{{$cfgIdx}}
410410
{{- else if or (eq $cfg.TLSTermination "") (eq $cfg.TLSTermination "edge") }}
411411
{{- end }}{{/* end type specific options*/}}
412412

413-
{{- if not $endpoint.NoHealthCheck }} check inter {{firstMatch $timeSpecPattern (index $cfg.Annotations "router.openshift.io/haproxy.health.check.interval") (env "ROUTER_BACKEND_CHECK_INTERVAL") "5000ms"}}
413+
{{- if and (not $endpoint.NoHealthCheck) (gt $cfg.ActiveEndpoints 1) }} check inter {{firstMatch $timeSpecPattern (index $cfg.Annotations "router.openshift.io/haproxy.health.check.interval") (env "ROUTER_BACKEND_CHECK_INTERVAL") "5000ms"}}
414414
{{- end }}{{/* end else no health check */}}
415-
416-
417415
{{- end }}{{/* end if cg.TLSTermination */}}
418416
{{- end }}{{/* end range processEndpointsForAlias */}}
419417
{{- end }}{{/* end get serviceUnit from its name */}}
@@ -464,7 +462,7 @@ backend be_tcp:{{$cfgIdx}}
464462
{{- with $serviceUnit := index $.ServiceUnits $serviceUnitName }}
465463
{{- range $idx, $endpoint := processEndpointsForAlias $cfg $serviceUnit (env "ROUTER_BACKEND_PROCESS_ENDPOINTS" "") }}
466464
server {{$endpoint.ID}} {{$endpoint.IP}}:{{$endpoint.Port}} weight {{$weight}}
467-
{{- if not $endpoint.NoHealthCheck }} check inter {{firstMatch $timeSpecPattern (index $cfg.Annotations "router.openshift.io/haproxy.health.check.interval") (env "ROUTER_BACKEND_CHECK_INTERVAL") "5000ms"}}
465+
{{- if and (not $endpoint.NoHealthCheck) (gt $cfg.ActiveEndpoints 1) }} check inter {{firstMatch $timeSpecPattern (index $cfg.Annotations "router.openshift.io/haproxy.health.check.interval") (env "ROUTER_BACKEND_CHECK_INTERVAL") "5000ms"}}
468466
{{- end }}{{/* end else no health check */}}
469467
{{- end }}{{/* end range processEndpointsForAlias */}}
470468
{{- end }}{{/* end get ServiceUnit from serviceUnitName */}}

pkg/router/template/router.go

+38-14
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ func (r *templateRouter) writeConfig() error {
387387
// called here to make sure we have the actual number of endpoints.
388388
cfg.ServiceUnitNames = r.calculateServiceWeights(cfg.ServiceUnits)
389389

390+
// Calculate the number of active endpoints for the route.
391+
cfg.ActiveEndpoints = r.getActiveEndpoints(cfg.ServiceUnits)
392+
390393
cfg.Status = ServiceAliasConfigStatusSaved
391394
r.state[k] = cfg
392395
}
@@ -877,28 +880,49 @@ func getServiceUnits(route *routeapi.Route) map[string]int32 {
877880

878881
// get the weight and number of endpoints for each service
879882
key := endpointsKeyFromParts(route.Namespace, route.Spec.To.Name)
880-
serviceUnits[key] = 0
881-
if route.Spec.To.Weight != nil {
882-
serviceUnits[key] = int32(*route.Spec.To.Weight)
883-
}
884-
if serviceUnits[key] < 0 || serviceUnits[key] > 256 {
885-
serviceUnits[key] = 0
886-
}
883+
serviceUnits[key] = getServiceUnitWeight(route.Spec.To.Weight)
887884

888885
for _, svc := range route.Spec.AlternateBackends {
889886
key = endpointsKeyFromParts(route.Namespace, svc.Name)
890-
serviceUnits[key] = 0
891-
if svc.Weight != nil {
892-
serviceUnits[key] = int32(*svc.Weight)
893-
}
894-
if serviceUnits[key] < 0 || serviceUnits[key] > 256 {
895-
serviceUnits[key] = 0
896-
}
887+
serviceUnits[key] = getServiceUnitWeight(svc.Weight)
897888
}
898889

899890
return serviceUnits
900891
}
901892

893+
// getServiceUnitWeight takes a reference to a weight and returns its value or the default.
894+
// It also checks that it is in the correct range.
895+
func getServiceUnitWeight(weightRef *int32) int32 {
896+
// Default to 1 if there is no weight
897+
var weight int32 = 1
898+
if weightRef != nil {
899+
weight = *weightRef
900+
}
901+
902+
// Do a bounds check
903+
if weight < 0 {
904+
weight = 0
905+
} else if weight > 256 {
906+
weight = 256
907+
}
908+
909+
return weight
910+
}
911+
912+
// getActiveEndpoints calculates the number of endpoints that are not associated
913+
// with service units with a zero weight and returns the count.
914+
func (r *templateRouter) getActiveEndpoints(serviceUnits map[string]int32) int {
915+
var activeEndpoints int32 = 0
916+
917+
for key, weight := range serviceUnits {
918+
if weight > 0 {
919+
activeEndpoints += r.numberOfEndpoints(key)
920+
}
921+
}
922+
923+
return int(activeEndpoints)
924+
}
925+
902926
// calculateServiceWeights returns a map of service keys to their weights.
903927
// Each service gets (weight/sum_of_weights) fraction of the requests.
904928
// For each service, the requests are distributed among the endpoints.

pkg/router/template/types.go

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ type ServiceAliasConfig struct {
6464

6565
// ActiveServiceUnits is a count of the service units with a non-zero weight
6666
ActiveServiceUnits int
67+
68+
// ActiveEndpoints is a count of the route endpoints that are part of a service unit with a non-zero weight
69+
ActiveEndpoints int
6770
}
6871

6972
type ServiceAliasConfigStatus string

0 commit comments

Comments
 (0)