Skip to content
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

Tune default outlier detection parameters for remote endpoints #207

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
d457913
Bootstrapping admiral
aattuluri Sep 19, 2019
7b9a2ff
Add circle ci config
aattuluri Sep 19, 2019
c9e80a5
Fix the working directory for builds
aattuluri Sep 19, 2019
76b9561
Bootstrapping admiral
aattuluri Sep 19, 2019
85aeeaa
Add circle ci config
aattuluri Sep 19, 2019
fe313cc
Fix the working directory for builds
aattuluri Sep 19, 2019
306ad93
Merge branch 'master' of https://github.com/aattuluri/admiral
aattuluri Sep 19, 2019
a9fa409
Add build status badge.
aattuluri Sep 19, 2019
4ae717d
Revert "Add build status badge."
aattuluri Sep 19, 2019
ff09cfb
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 19, 2019
eb51849
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 20, 2019
928c0d2
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 20, 2019
2fb3364
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 23, 2019
ea3ed61
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 23, 2019
15e7845
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 24, 2019
3b34036
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 29, 2019
656bf71
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 29, 2019
0245314
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 29, 2019
111c3de
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 4, 2019
e39651c
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 4, 2019
b280c0b
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 6, 2019
4b74679
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 16, 2019
09b8a5b
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 30, 2019
6546170
Merge remote-tracking branch 'upstream/master'
aattuluri Dec 27, 2019
1b0dfeb
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 2, 2020
9b0010b
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 9, 2020
7b68379
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 21, 2020
5ae2f4c
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 24, 2020
6e297db
Publish images: i) latest from master, ii) TAG if its set and iii) co…
aattuluri Jan 24, 2020
d6674b9
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 19, 2020
e45ef03
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 26, 2020
9096f16
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 27, 2020
1e7a3d5
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 8, 2020
a9e55b3
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 20, 2020
c40a8be
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 27, 2020
798b06a
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 6, 2020
f028e1e
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 16, 2020
0956d03
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 27, 2020
cecd2ca
Merge remote-tracking branch 'upstream/master'
aattuluri May 13, 2020
b46682c
Merge remote-tracking branch 'upstream/master'
aattuluri May 14, 2020
2d3460c
Merge remote-tracking branch 'upstream/master'
aattuluri May 26, 2020
77c46e0
Merge remote-tracking branch 'upstream/master'
aattuluri Jun 15, 2020
82a4223
Merge remote-tracking branch 'upstream/master'
aattuluri Jul 24, 2020
065b6d4
Merge remote-tracking branch 'upstream/master'
aattuluri Aug 26, 2020
933650b
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 20, 2020
d2e76cb
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 2, 2020
63b4c60
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 6, 2020
7b6626f
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 12, 2020
0631dce
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 13, 2020
51a27da
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 21, 2021
8683c4e
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 23, 2021
e05e909
Merge remote-tracking branch 'upstream/master'
aattuluri Jun 3, 2021
85a586e
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 30, 2022
5a3d36f
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 4, 2022
0f387e1
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 10, 2022
cf0996e
Do not do destructive updates during bootup time
aattuluri Feb 10, 2022
accf659
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 2, 2022
0ef1a24
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 22, 2022
f85d4b0
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 8, 2022
a9b8aee
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 12, 2022
6d42f79
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 19, 2022
eca0be5
Tune outlier detection defaults
aattuluri Apr 19, 2022
d3b2a46
Update outlier parameters
aattuluri Apr 21, 2022
1f4d253
Bumping up consecutive errors to a higher number to smooth out tempor…
aattuluri May 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions admiral/pkg/clusters/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package clusters
import (
"bytes"
"fmt"
"net"
"reflect"
"sort"
"strings"
Expand Down Expand Up @@ -61,20 +62,15 @@ func getIstioResourceName(host string, suffix string) string {
return strings.ToLower(host) + suffix
}

func getDestinationRule(host string, locality string, gtpTrafficPolicy *model.TrafficPolicy) *v1alpha32.DestinationRule {
func getDestinationRule(se *v1alpha32.ServiceEntry, locality string, gtpTrafficPolicy *model.TrafficPolicy) *v1alpha32.DestinationRule {
var dr = &v1alpha32.DestinationRule{}
dr.Host = host
nirvanagit marked this conversation as resolved.
Show resolved Hide resolved
dr.Host = se.Hosts[0]
dr.TrafficPolicy = &v1alpha32.TrafficPolicy{Tls: &v1alpha32.TLSSettings{Mode: v1alpha32.TLSSettings_ISTIO_MUTUAL}}
processGtp := true
if len(locality) == 0 {
log.Warnf(LogErrFormat, "Process", "GlobalTrafficPolicy", host, "", "Skipping gtp processing, locality of the cluster nodes cannot be determined. Is this minikube?")
log.Warnf(LogErrFormat, "Process", "GlobalTrafficPolicy", dr.Host, "", "Skipping gtp processing, locality of the cluster nodes cannot be determined. Is this minikube?")
processGtp = false
}
outlierDetection := &v1alpha32.OutlierDetection{
BaseEjectionTime: &types.Duration{Seconds: 300},
Consecutive_5XxErrors: &types.UInt32Value{Value: uint32(10)},
Interval: &types.Duration{Seconds: 60},
}
if gtpTrafficPolicy != nil && processGtp {
var loadBalancerSettings = &v1alpha32.LoadBalancerSettings{
LbPolicy: &v1alpha32.LoadBalancerSettings_Simple{Simple: v1alpha32.LoadBalancerSettings_ROUND_ROBIN},
Expand Down Expand Up @@ -103,10 +99,33 @@ func getDestinationRule(host string, locality string, gtpTrafficPolicy *model.Tr
dr.TrafficPolicy.LoadBalancer = loadBalancerSettings
}
}
dr.TrafficPolicy.OutlierDetection = outlierDetection
dr.TrafficPolicy.OutlierDetection = getOutlierDetection(se, locality, gtpTrafficPolicy)
return dr
}

func getOutlierDetection(se *v1alpha32.ServiceEntry, locality string, gtpTrafficPolicy *model.TrafficPolicy) *v1alpha32.OutlierDetection {

outlierDetection := &v1alpha32.OutlierDetection{
BaseEjectionTime: &types.Duration{Seconds: 300},
ConsecutiveGatewayErrors: &types.UInt32Value{Value: uint32(50)},
Interval: &types.Duration{Seconds: 60},
}

//Scenario 1: Only one endpoint present and is local service (ends in svc.cluster.local) - no outlier detection (optimize this for headless services in future?)
if len(se.Endpoints) == 1 && (strings.Contains(se.Endpoints[0].Address, common.DotLocalDomainSuffix) || net.ParseIP(se.Endpoints[0].Address).To4() != nil) {
nirvanagit marked this conversation as resolved.
Show resolved Hide resolved
return nil
} else if len(se.Endpoints) == 1 {
//Scenario 2: Only one endpoint present and is remote - outlier detection with 34% ejection (protection against zone specific issues)
outlierDetection.MaxEjectionPercent = 34
} else {
//Scenario 3: Two endpoints present each with different locality and both remote - outlier detection with 100% ejection
//Scenario 4: Two endpoints present each with different locality with one local and other remote - outlier detection with 100% ejection
//for service entries with more than 2 endpoints eject 100% to failover to other endpoint within or outside the same region
outlierDetection.MaxEjectionPercent = 100
}
return outlierDetection
}

func (se *ServiceEntryHandler) Added(obj *v1alpha3.ServiceEntry) {
if IgnoreIstioResource(obj.Spec.ExportTo, obj.Annotations, obj.Namespace) {
log.Infof(LogFormat, "Add", "ServiceEntry", obj.Name, se.ClusterID, "Skipping resource from namespace="+obj.Namespace)
Expand Down
113 changes: 105 additions & 8 deletions admiral/pkg/clusters/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,16 @@ func TestGetDestinationRule(t *testing.T) {
//Do setup here
outlierDetection := &v1alpha3.OutlierDetection{
BaseEjectionTime: &types.Duration{Seconds: 300},
Consecutive_5XxErrors: &types.UInt32Value{Value: 10},
Interval: &types.Duration{Seconds: 60}}
ConsecutiveGatewayErrors: &types.UInt32Value{Value: 50},
Interval: &types.Duration{Seconds: 60},
MaxEjectionPercent: 100,
}
mTLS := &v1alpha3.TrafficPolicy{Tls: &v1alpha3.TLSSettings{Mode: v1alpha3.TLSSettings_ISTIO_MUTUAL}, OutlierDetection: outlierDetection}


se := &v1alpha3.ServiceEntry{Hosts: []string{"qa.myservice.global"},Endpoints:[]*v1alpha3.ServiceEntry_Endpoint{
{Address: "east.com", Locality: "us-east-2"}, {Address: "west.com", Locality: "us-west-2"},
}}
noGtpDr := v1alpha3.DestinationRule{
Host: "qa.myservice.global",
TrafficPolicy: mTLS,
Expand Down Expand Up @@ -243,35 +249,35 @@ func TestGetDestinationRule(t *testing.T) {
//Struct of test case info. Name is required.
testCases := []struct {
name string
host string
se *v1alpha3.ServiceEntry
locality string
gtpPolicy *model.TrafficPolicy
destinationRule *v1alpha3.DestinationRule
}{
{
name: "Should handle a nil GTP",
host: "qa.myservice.global",
se: se,
locality: "uswest2",
gtpPolicy: nil,
destinationRule: &noGtpDr,
},
{
name: "Should return default DR with empty locality",
host: "qa.myservice.global",
se: se,
locality: "",
gtpPolicy: failoverGTPPolicy,
destinationRule: &noGtpDr,
},
{
name: "Should handle a topology GTP",
host: "qa.myservice.global",
se: se,
locality: "uswest2",
gtpPolicy: topologyGTPPolicy,
destinationRule: &basicGtpDr,
},
{
name: "Should handle a failover GTP",
host: "qa.myservice.global",
se: se,
locality: "uswest2",
gtpPolicy: failoverGTPPolicy,
destinationRule: &failoverGtpDr,
Expand All @@ -281,14 +287,105 @@ func TestGetDestinationRule(t *testing.T) {
//Run the test for every provided case
for _, c := range testCases {
t.Run(c.name, func(t *testing.T) {
result := getDestinationRule(c.host, c.locality, c.gtpPolicy)
result := getDestinationRule(c.se, c.locality, c.gtpPolicy)
if !cmp.Equal(result, c.destinationRule) {
t.Fatalf("DestinationRule Mismatch. Diff: %v", cmp.Diff(result, c.destinationRule))
}
})
}
}

func TestGetOutlierDetection(t *testing.T) {
//Do setup here
outlierDetection := &v1alpha3.OutlierDetection{
BaseEjectionTime: &types.Duration{Seconds: 300},
ConsecutiveGatewayErrors: &types.UInt32Value{Value: 50},
Interval: &types.Duration{Seconds: 60},
MaxEjectionPercent: 100,
}

outlierDetectionOneHostRemote := &v1alpha3.OutlierDetection{
BaseEjectionTime: &types.Duration{Seconds: 300},
ConsecutiveGatewayErrors: &types.UInt32Value{Value: 50},
Interval: &types.Duration{Seconds: 60},
MaxEjectionPercent: 34,
}

topologyGTPPolicy := &model.TrafficPolicy{
LbType: model.TrafficPolicy_TOPOLOGY,
Target: []*model.TrafficGroup{
{
Region: "us-west-2",
Weight: 100,
},
},
}

se := &v1alpha3.ServiceEntry{Hosts: []string{"qa.myservice.global"},Endpoints:[]*v1alpha3.ServiceEntry_Endpoint{
{Address: "east.com", Locality: "us-east-2"}, {Address: "west.com", Locality: "us-west-2"},
}}

seOneHostRemote := &v1alpha3.ServiceEntry{Hosts: []string{"qa.myservice.global"},Endpoints:[]*v1alpha3.ServiceEntry_Endpoint{
{Address: "east.com", Locality: "us-east-2"},
}}

seOneHostLocal := &v1alpha3.ServiceEntry{Hosts: []string{"qa.myservice.global"},Endpoints:[]*v1alpha3.ServiceEntry_Endpoint{
{Address: "hello.ns.svc.cluster.local", Locality: "us-east-2"},
}}

seOneHostRemoteIp := &v1alpha3.ServiceEntry{Hosts: []string{"qa.myservice.global"},Endpoints:[]*v1alpha3.ServiceEntry_Endpoint{
{Address: "95.45.25.34", Locality: "us-east-2"},
}}

//Struct of test case info. Name is required.
testCases := []struct {
name string
se *v1alpha3.ServiceEntry
locality string
gtpPolicy *model.TrafficPolicy
outlierDetection *v1alpha3.OutlierDetection
}{
{
name: "Should return nil for cluster local only endpoint",
se: seOneHostLocal,
locality: "uswest2",
gtpPolicy: topologyGTPPolicy,
outlierDetection: nil,
},
{
name: "Should return nil for one IP endpoint",
se: seOneHostRemoteIp,
locality: "uswest2",
gtpPolicy: topologyGTPPolicy,
outlierDetection: nil,
},
{
name: "Should return 34% ejection for remote endpoint with one entry",
se: seOneHostRemote,
locality: "uswest2",
gtpPolicy: topologyGTPPolicy,
outlierDetection: outlierDetectionOneHostRemote,
},
{
name: "Should return 100% ejection for two remote endpoints",
se: se,
locality: "uswest2",
gtpPolicy: topologyGTPPolicy,
outlierDetection: outlierDetection,
},
}

//Run the test for every provided case
for _, c := range testCases {
t.Run(c.name, func(t *testing.T) {
result := getOutlierDetection(c.se, c.locality, c.gtpPolicy)
if !cmp.Equal(result, c.outlierDetection) {
t.Fatalf("OutlierDetection Mismatch. Diff: %v", cmp.Diff(result, c.outlierDetection))
}
})
}
}

func TestHandleVirtualServiceEvent(t *testing.T) {
tooManyHosts := v1alpha32.VirtualService{
Spec: v1alpha3.VirtualService{
Expand Down
4 changes: 2 additions & 2 deletions admiral/pkg/clusters/serviceentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ func createSeAndDrSetFromGtp(env, region string, se *networking.ServiceEntry, gl
var seDr = &SeDrTuple{
DrName: drName,
SeName: seName,
DestinationRule: getDestinationRule(host, region, gtpTrafficPolicy),
DestinationRule: getDestinationRule(modifiedSe, region, gtpTrafficPolicy),
ServiceEntry: modifiedSe,
}
seDrSet[host] = seDr
Expand All @@ -480,7 +480,7 @@ func createSeAndDrSetFromGtp(env, region string, se *networking.ServiceEntry, gl
var seDr = &SeDrTuple{
DrName: defaultDrName,
SeName: defaultSeName,
DestinationRule: getDestinationRule(se.Hosts[0], region, nil),
DestinationRule: getDestinationRule(se, region, nil),
ServiceEntry: se,
}
seDrSet[se.Hosts[0]] = seDr
Expand Down