Skip to content

Commit 203252b

Browse files
authored
Merge pull request #2966 from FelipeYepez/l4-weighted-ilb-rendezvous
Add Rendezvous hashing for ILB weighted load balancing
2 parents ca0a061 + a6a00e6 commit 203252b

File tree

5 files changed

+178
-34
lines changed

5 files changed

+178
-34
lines changed

pkg/backends/backends.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,14 @@ type LocalityLBPolicyType string
4848
const (
4949
// LocalityLBPolicyDefault is the default locality lb policy for a backend service.
5050
LocalityLBPolicyDefault LocalityLBPolicyType = ""
51-
// LocalityLBPolicyWeightedMaglev is the locality lb policy for weighted load balancing by pods-per-node.
51+
// LocalityLBPolicyWeightedMaglev is the locality lb policy for NetLB weighted load balancing by pods-per-node.
5252
LocalityLBPolicyWeightedMaglev LocalityLBPolicyType = "WEIGHTED_MAGLEV"
5353
// LocalityLBPolicyMaglev is the locality lb policy when weighted load balancing by pods-per-node is disabled.
5454
LocalityLBPolicyMaglev LocalityLBPolicyType = "MAGLEV"
55+
// LocalityLBPolicyWeightedRendezvous is the locality lb policy for ILB weighted load balancing by pods-per-node.
56+
LocalityLBPolicyWeightedRendezvous LocalityLBPolicyType = "WEIGHTED_GCP_RENDEZVOUS"
57+
// LocalityLbPolicyRendezvous used for ILB will become the default locality lb policy for a backend service.
58+
LocalityLbPolicyRendezvous LocalityLBPolicyType = "GCP_RENDEZVOUS"
5559
)
5660

5761
// Pool handles CRUD operations on a pool of GCE Backend Services.
@@ -512,11 +516,13 @@ func backendSvcEqual(newBS, oldBS *composite.BackendService, compareConnectionTr
512516
svcsEqual = svcsEqual && backendServiceLogConfigEqual(oldBS.LogConfig, newBS.LogConfig)
513517
}
514518

515-
// If the locality lb policy is not set for existing services, no need to update to MAGLEV since it is the default now.
519+
// If the locality lb policy is not set for existing services, no need to update to MAGLEV since it is the default for NetLB.
520+
// GCP_RENDEZVOUS will become the default so the controller should prevent trying to unset it each resync.
516521
svcsEqual = svcsEqual &&
517522
(newBS.LocalityLbPolicy == oldBS.LocalityLbPolicy ||
518523
(newBS.LocalityLbPolicy == string(LocalityLBPolicyDefault) && oldBS.LocalityLbPolicy == string(LocalityLBPolicyMaglev)) ||
519-
(newBS.LocalityLbPolicy == string(LocalityLBPolicyMaglev) && oldBS.LocalityLbPolicy == string(LocalityLBPolicyDefault)))
524+
(newBS.LocalityLbPolicy == string(LocalityLBPolicyMaglev) && oldBS.LocalityLbPolicy == string(LocalityLBPolicyDefault)) ||
525+
(newBS.LocalityLbPolicy == string(LocalityLBPolicyDefault) && oldBS.LocalityLbPolicy == string(LocalityLbPolicyRendezvous)))
520526

521527
// If zonal affinity is set, needs to be equal
522528
svcsEqual = svcsEqual && zonalAffinityEqual(newBS, oldBS)

pkg/backends/backends_test.go

Lines changed: 115 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ func TestBackendSvcEqual(t *testing.T) {
351351
withZonalAffinityEnabled bool
352352
withL4LoggingManagementEnabled bool
353353
wantEqual bool
354+
skipBidirectionalCheck bool
354355
}{
355356
{
356357
desc: "Test empty backend services are equal",
@@ -764,7 +765,7 @@ func TestBackendSvcEqual(t *testing.T) {
764765
wantEqual: true,
765766
},
766767
{
767-
desc: "Test existing backend service diff with weighted load balancing feature enabled",
768+
desc: "Test prevent unnecessary NetLB recreation",
768769
oldBackendService: &composite.BackendService{
769770
LocalityLbPolicy: string(LocalityLBPolicyDefault),
770771
},
@@ -774,7 +775,17 @@ func TestBackendSvcEqual(t *testing.T) {
774775
wantEqual: true,
775776
},
776777
{
777-
desc: "Test backend service diff with weighted load balancing pods-per-node ENABLED",
778+
desc: "Test prevent unsupported disablement of Maglev - NetLB",
779+
oldBackendService: &composite.BackendService{
780+
LocalityLbPolicy: string(LocalityLBPolicyMaglev),
781+
},
782+
newBackendService: &composite.BackendService{
783+
LocalityLbPolicy: string(LocalityLBPolicyDefault),
784+
},
785+
wantEqual: true,
786+
},
787+
{
788+
desc: "Test backend service diff with NetLB weighted load balancing pods-per-node ENABLED",
778789
oldBackendService: &composite.BackendService{
779790
LocalityLbPolicy: string(LocalityLBPolicyDefault),
780791
},
@@ -783,6 +794,16 @@ func TestBackendSvcEqual(t *testing.T) {
783794
},
784795
wantEqual: false,
785796
},
797+
{
798+
desc: "Test backend service diff with ILB weighted load balancing pods-per-node ENABLED",
799+
oldBackendService: &composite.BackendService{
800+
LocalityLbPolicy: string(LocalityLBPolicyDefault),
801+
},
802+
newBackendService: &composite.BackendService{
803+
LocalityLbPolicy: string(LocalityLBPolicyWeightedRendezvous),
804+
},
805+
wantEqual: false,
806+
},
786807
{
787808
desc: "Test backend service diff with weighted load balancing pods-per-node DISABLED",
788809
oldBackendService: &composite.BackendService{
@@ -794,7 +815,7 @@ func TestBackendSvcEqual(t *testing.T) {
794815
wantEqual: true,
795816
},
796817
{
797-
desc: "Test backend service diff disable weighted load balancing pods-per-node",
818+
desc: "Test backend service diff disable NetLB weighted load balancing pods-per-node",
798819
oldBackendService: &composite.BackendService{
799820
LocalityLbPolicy: string(LocalityLBPolicyWeightedMaglev),
800821
},
@@ -803,6 +824,48 @@ func TestBackendSvcEqual(t *testing.T) {
803824
},
804825
wantEqual: false,
805826
},
827+
{
828+
desc: "Test backend service diff disable ILB weighted load balancing pods-per-node",
829+
oldBackendService: &composite.BackendService{
830+
LocalityLbPolicy: string(LocalityLBPolicyWeightedRendezvous),
831+
},
832+
newBackendService: &composite.BackendService{
833+
LocalityLbPolicy: string(LocalityLBPolicyDefault),
834+
},
835+
wantEqual: false,
836+
},
837+
{
838+
desc: "Test backend service diff ILB post-disabling weighted load balancing pods-per-node",
839+
oldBackendService: &composite.BackendService{
840+
LocalityLbPolicy: string(LocalityLBPolicyWeightedRendezvous),
841+
},
842+
newBackendService: &composite.BackendService{
843+
LocalityLbPolicy: string(LocalityLbPolicyRendezvous),
844+
},
845+
wantEqual: false,
846+
},
847+
{
848+
desc: "Test prevent ILB resync failure after GCP_RENDEZVOUS is defaulted",
849+
oldBackendService: &composite.BackendService{
850+
LocalityLbPolicy: string(LocalityLbPolicyRendezvous),
851+
},
852+
newBackendService: &composite.BackendService{
853+
LocalityLbPolicy: string(LocalityLBPolicyDefault),
854+
},
855+
wantEqual: true,
856+
skipBidirectionalCheck: true,
857+
},
858+
{
859+
desc: "Test GCP_RENDEZVOUS not set as ILB default",
860+
oldBackendService: &composite.BackendService{
861+
LocalityLbPolicy: string(LocalityLBPolicyDefault),
862+
},
863+
newBackendService: &composite.BackendService{
864+
LocalityLbPolicy: string(LocalityLbPolicyRendezvous),
865+
},
866+
wantEqual: false,
867+
skipBidirectionalCheck: true,
868+
},
806869
{
807870
desc: "Test LocalityLbPolicy equal does not override the other params",
808871
oldBackendService: &composite.BackendService{
@@ -949,7 +1012,7 @@ func TestBackendSvcEqual(t *testing.T) {
9491012
t.Errorf("backendSvcEqual() returned %v, expected %v. Diff(oldScv, newSvc): %s",
9501013
result, tc.wantEqual, cmp.Diff(tc.oldBackendService, tc.newBackendService))
9511014
}
952-
if result != backendSvcEqual(tc.oldBackendService, tc.newBackendService, tc.compareConnectionTracking) {
1015+
if !tc.skipBidirectionalCheck && result != backendSvcEqual(tc.oldBackendService, tc.newBackendService, tc.compareConnectionTracking) {
9531016
t.Error("result from backendSvcEqual(old, new) should be the same as backendSvcEqual(new, old)")
9541017
}
9551018
})
@@ -964,47 +1027,83 @@ func TestUpdateLocalityLBPolicy(t *testing.T) {
9641027
wantBSLocalityLbPolicy LocalityLBPolicyType
9651028
}{
9661029
{
967-
desc: "from empty to WEIGHTED_MAGLEV",
1030+
desc: "from MAGLEV to MAGLEV",
1031+
existingBSLocalityLbPolicy: LocalityLBPolicyMaglev,
1032+
updatedBSLocalityLbPolicy: LocalityLBPolicyMaglev,
1033+
wantBSLocalityLbPolicy: LocalityLBPolicyMaglev,
1034+
},
1035+
{
1036+
desc: "from empty to WEIGHTED_MAGLEV NetLB",
9681037
existingBSLocalityLbPolicy: LocalityLBPolicyDefault,
9691038
updatedBSLocalityLbPolicy: LocalityLBPolicyWeightedMaglev,
9701039
wantBSLocalityLbPolicy: LocalityLBPolicyWeightedMaglev,
9711040
},
9721041
{
973-
desc: "from empty to MAGLEV",
1042+
desc: "from empty to MAGLEV NetLB",
9741043
existingBSLocalityLbPolicy: LocalityLBPolicyDefault,
9751044
updatedBSLocalityLbPolicy: LocalityLBPolicyMaglev,
9761045
wantBSLocalityLbPolicy: LocalityLBPolicyDefault,
9771046
},
9781047
{
979-
desc: "from MAGLEV to empty",
1048+
desc: "from MAGLEV to empty NetLB",
9801049
existingBSLocalityLbPolicy: LocalityLBPolicyMaglev,
9811050
updatedBSLocalityLbPolicy: LocalityLBPolicyDefault,
9821051
wantBSLocalityLbPolicy: LocalityLBPolicyMaglev,
9831052
},
9841053
{
985-
desc: "from MAGLEV to MAGLEV",
986-
existingBSLocalityLbPolicy: LocalityLBPolicyMaglev,
987-
updatedBSLocalityLbPolicy: LocalityLBPolicyMaglev,
988-
wantBSLocalityLbPolicy: LocalityLBPolicyMaglev,
989-
},
990-
{
991-
desc: "from MAGLEV to WEIGHTED_MAGLEV",
1054+
desc: "from MAGLEV to WEIGHTED_MAGLEV NetLB",
9921055
existingBSLocalityLbPolicy: LocalityLBPolicyMaglev,
9931056
updatedBSLocalityLbPolicy: LocalityLBPolicyWeightedMaglev,
9941057
wantBSLocalityLbPolicy: LocalityLBPolicyWeightedMaglev,
9951058
},
9961059
{
997-
desc: "from WEIGHTED_MAGLEV to MAGLEV",
1060+
desc: "from WEIGHTED_MAGLEV to MAGLEV NetLB",
9981061
existingBSLocalityLbPolicy: LocalityLBPolicyWeightedMaglev,
9991062
updatedBSLocalityLbPolicy: LocalityLBPolicyMaglev,
10001063
wantBSLocalityLbPolicy: LocalityLBPolicyMaglev,
10011064
},
10021065
{
1003-
desc: "from WEIGHTED_MAGLEV to empty",
1066+
desc: "from WEIGHTED_MAGLEV to empty ILB - allowlisted",
10041067
existingBSLocalityLbPolicy: LocalityLBPolicyWeightedMaglev,
10051068
updatedBSLocalityLbPolicy: LocalityLBPolicyDefault,
10061069
wantBSLocalityLbPolicy: LocalityLBPolicyDefault,
10071070
},
1071+
{
1072+
desc: "from empty to GCP_RENDEZVOUS",
1073+
existingBSLocalityLbPolicy: LocalityLBPolicyDefault,
1074+
updatedBSLocalityLbPolicy: LocalityLbPolicyRendezvous,
1075+
wantBSLocalityLbPolicy: LocalityLbPolicyRendezvous,
1076+
},
1077+
{
1078+
desc: "from empty to WEIGHTED_GCP_RENDEZVOUS",
1079+
existingBSLocalityLbPolicy: LocalityLBPolicyDefault,
1080+
updatedBSLocalityLbPolicy: LocalityLBPolicyWeightedRendezvous,
1081+
wantBSLocalityLbPolicy: LocalityLBPolicyWeightedRendezvous,
1082+
},
1083+
{
1084+
desc: "from GCP_RENDEZVOUS to empty",
1085+
existingBSLocalityLbPolicy: LocalityLbPolicyRendezvous,
1086+
updatedBSLocalityLbPolicy: LocalityLBPolicyDefault,
1087+
wantBSLocalityLbPolicy: LocalityLbPolicyRendezvous,
1088+
},
1089+
{
1090+
desc: "from GCP_RENDEZVOUS to WEIGHTED_GCP_RENDEZVOUS",
1091+
existingBSLocalityLbPolicy: LocalityLbPolicyRendezvous,
1092+
updatedBSLocalityLbPolicy: LocalityLBPolicyWeightedRendezvous,
1093+
wantBSLocalityLbPolicy: LocalityLBPolicyWeightedRendezvous,
1094+
},
1095+
{
1096+
desc: "from WEIGHTED_GCP_RENDEZVOUS to GCP_RENDEZVOUS",
1097+
existingBSLocalityLbPolicy: LocalityLBPolicyWeightedRendezvous,
1098+
updatedBSLocalityLbPolicy: LocalityLbPolicyRendezvous,
1099+
wantBSLocalityLbPolicy: LocalityLbPolicyRendezvous,
1100+
},
1101+
{
1102+
desc: "from WEIGHTED_GCP_RENDEZVOUS to empty ILB",
1103+
existingBSLocalityLbPolicy: LocalityLBPolicyWeightedRendezvous,
1104+
updatedBSLocalityLbPolicy: LocalityLBPolicyDefault,
1105+
wantBSLocalityLbPolicy: LocalityLBPolicyDefault,
1106+
},
10081107
}
10091108

10101109
for _, tc := range testCases {

pkg/loadbalancers/l4.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ func (l4 *L4) EnsureInternalLoadBalancer(nodeNames []string, svc *corev1.Service
573573
bs, bsSyncStatus, err := l4.backendPool.EnsureL4BackendService(backendParams, l4.svcLogger)
574574
result.ResourceUpdates.SetBackendService(bsSyncStatus)
575575
if err != nil {
576-
if utils.IsUnsupportedFeatureError(err, string(backends.LocalityLBPolicyMaglev)) {
576+
if utils.IsUnsupportedFeatureError(err, string(backends.LocalityLbPolicyRendezvous)) {
577577
result.GCEResourceInError = annotations.BackendServiceResource
578578
l4.recorder.Eventf(l4.Service, corev1.EventTypeWarning, "AllowlistingRequired", WeightedLBPodsPerNodeAllowlistMessage)
579579
result.Error = utils.NewUserError(err)
@@ -811,30 +811,31 @@ func (l4 *L4) getOldIPv4ForwardingRule(existingBS *composite.BackendService) (*c
811811

812812
// determineBackendServiceLocalityPolicy returns the locality policy to be used for the backend service of the internal load balancer.
813813
func (l4 *L4) determineBackendServiceLocalityPolicy() backends.LocalityLBPolicyType {
814-
// If the service has weighted load balancing enabled, the locality policy will be WEIGHTED_MAGLEV.
814+
// If the ILB service has weighted load balancing enabled, the locality policy will be WEIGHTED_GCP_RENDEZVOUS.
815815
if l4.enableWeightedLB {
816816
if annotations.HasWeightedLBPodsPerNodeAnnotation(l4.Service) {
817817
if l4.Service.Spec.ExternalTrafficPolicy == corev1.ServiceExternalTrafficPolicyTypeLocal {
818818
// If the service has the annotation "networking.gke.io/weighted-load-balancing = pods-per-node"
819819
// and the external traffic policy is local, weighted load balancing is enabled and the backend
820-
// service locality policy is set to WEIGHTED_MAGLEV.
821-
return backends.LocalityLBPolicyWeightedMaglev
820+
// service locality policy is set to WEIGHTED_GCP_RENDEZVOUS.
821+
return backends.LocalityLBPolicyWeightedRendezvous
822822
} else {
823823
// If the service has the annotation "networking.gke.io/weighted-load-balancing = pods-per-node"
824824
// and the external traffic policy is cluster, weighted load balancing is not enabled.
825825
l4.recorder.Eventf(l4.Service, corev1.EventTypeWarning, "UnsupportedConfiguration",
826826
"Weighted load balancing by pods-per-node has no effect with External Traffic Policy: Cluster.")
827-
// TODO(FelipeYepez) use LocalityLBPolicyMaglev once it does not require allow lisiting
827+
// The default unset locality lb policy is used to disable ILB Weighted Load Balancing
828+
// It will eventually be "GCP_RENDEZVOUS"
828829
return backends.LocalityLBPolicyDefault
829830
}
830831
}
831832
}
832-
// The default unset locality lb policy is used to disable ILB Weighted Load Balancing
833+
// We leave the LocalityLbPolicy field unset since the default value will be handled outside of the controller.
833834
return backends.LocalityLBPolicyDefault
834835
}
835836

836837
func (l4 *L4) isWeightedLBPodsPerNode() bool {
837-
return backends.LocalityLBPolicyWeightedMaglev == l4.determineBackendServiceLocalityPolicy()
838+
return backends.LocalityLBPolicyWeightedRendezvous == l4.determineBackendServiceLocalityPolicy()
838839
}
839840

840841
func (l4 *L4) isLBWithZonalAffinity() bool {

pkg/loadbalancers/l4_test.go

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,33 +2310,61 @@ func TestWeightedILB(t *testing.T) {
23102310
wantLocalityLBPolicy backends.LocalityLBPolicyType
23112311
}{
23122312
{
2313-
desc: "Flag enabled, Service with weighted annotation, externalTrafficPolicy local",
2313+
desc: "Flag DISABLED, Service with weighted annotation, externalTrafficPolicy local",
23142314
addAnnotationForWeighted: true,
2315-
weightedFlagEnabled: true,
2315+
weightedFlagEnabled: false,
23162316
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
2317-
wantLocalityLBPolicy: backends.LocalityLBPolicyWeightedMaglev,
2317+
wantLocalityLBPolicy: backends.LocalityLBPolicyDefault,
23182318
},
23192319
{
2320-
desc: "Flag enabled, NO weighted annotation, externalTrafficPolicy local",
2320+
desc: "Flag DISABLED, Service with weighted annotation, externalTrafficPolicy cluster",
2321+
addAnnotationForWeighted: true,
2322+
weightedFlagEnabled: false,
2323+
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeCluster,
2324+
wantLocalityLBPolicy: backends.LocalityLBPolicyDefault,
2325+
},
2326+
{
2327+
desc: "Flag DISABLED, Service without weighted annotation, externalTrafficPolicy local",
23212328
addAnnotationForWeighted: false,
2322-
weightedFlagEnabled: true,
2329+
weightedFlagEnabled: false,
23232330
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
23242331
wantLocalityLBPolicy: backends.LocalityLBPolicyDefault,
23252332
},
23262333
{
2327-
desc: "Flag DISABLED, Service with weighted annotation, externalTrafficPolicy local",
2328-
addAnnotationForWeighted: true,
2334+
desc: "Flag DISABLED, Service without weighted annotation, externalTrafficPolicy cluster",
2335+
addAnnotationForWeighted: false,
23292336
weightedFlagEnabled: false,
2330-
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
2337+
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeCluster,
23312338
wantLocalityLBPolicy: backends.LocalityLBPolicyDefault,
23322339
},
2340+
{
2341+
desc: "Flag enabled, Service with weighted annotation, externalTrafficPolicy local",
2342+
addAnnotationForWeighted: true,
2343+
weightedFlagEnabled: true,
2344+
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
2345+
wantLocalityLBPolicy: backends.LocalityLBPolicyWeightedRendezvous,
2346+
},
23332347
{
23342348
desc: "Flag enabled, Service with weighted annotation and externalTrafficPolicy CLUSTER",
23352349
addAnnotationForWeighted: true,
23362350
weightedFlagEnabled: true,
23372351
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeCluster,
23382352
wantLocalityLBPolicy: backends.LocalityLBPolicyDefault,
23392353
},
2354+
{
2355+
desc: "Flag enabled, NO weighted annotation, externalTrafficPolicy local",
2356+
addAnnotationForWeighted: false,
2357+
weightedFlagEnabled: true,
2358+
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeLocal,
2359+
wantLocalityLBPolicy: backends.LocalityLBPolicyDefault,
2360+
},
2361+
{
2362+
desc: "Flag enabled, NO weighted annotation, externalTrafficPolicy cluster",
2363+
addAnnotationForWeighted: false,
2364+
weightedFlagEnabled: true,
2365+
externalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeCluster,
2366+
wantLocalityLBPolicy: backends.LocalityLBPolicyDefault,
2367+
},
23402368
}
23412369

23422370
for _, tc := range tests {
@@ -2386,6 +2414,11 @@ func TestWeightedILB(t *testing.T) {
23862414
if bs.LocalityLbPolicy != string(tc.wantLocalityLBPolicy) {
23872415
t.Errorf("Unexpected BackendService LocalityLbPolicy value, got: %v, want: %v", bs.LocalityLbPolicy, tc.wantLocalityLBPolicy)
23882416
}
2417+
2418+
isWeightedLBPodsPerNode := l4.isWeightedLBPodsPerNode()
2419+
if tc.weightedFlagEnabled && tc.addAnnotationForWeighted && tc.externalTrafficPolicy == v1.ServiceExternalTrafficPolicyTypeLocal && !isWeightedLBPodsPerNode {
2420+
t.Errorf("Expected isWeightedLBPodsPerNode() to return true for Service with weighted load balancing enabled")
2421+
}
23892422
})
23902423
}
23912424
}

pkg/loadbalancers/l4netlb_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,11 @@ func TestWeightedNetLB(t *testing.T) {
12601260
if bs.LocalityLbPolicy != string(tc.wantLocalityLBPolicy) {
12611261
t.Errorf("Unexpected BackendService LocalityLbPolicy value, got: %v, want: %v", bs.LocalityLbPolicy, tc.wantLocalityLBPolicy)
12621262
}
1263+
1264+
isWeightedLBPodsPerNode := l4NetLB.isWeightedLBPodsPerNode()
1265+
if tc.weightedFlagEnabled && tc.addAnnotationForWeighted && tc.externalTrafficPolicy == v1.ServiceExternalTrafficPolicyTypeLocal && !isWeightedLBPodsPerNode {
1266+
t.Errorf("Expected isWeightedLBPodsPerNode() to return true for Service with weighted load balancing enabled")
1267+
}
12631268
})
12641269
}
12651270
}

0 commit comments

Comments
 (0)