Skip to content

Commit 7c64a95

Browse files
committed
feat(l4): Add support for enabling L4 NetLB Regional Backend Services by default
1 parent 0f9248e commit 7c64a95

File tree

6 files changed

+73
-13
lines changed

6 files changed

+73
-13
lines changed

pkg/context/context.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ type ControllerContextConfig struct {
138138
EnableL4ILBMixedProtocol bool
139139
EnableL4NetLBMixedProtocol bool
140140
EnableL4NetLBForwardingRulesOptimizations bool
141+
EnableL4NetLBRBSByDefault bool
141142
}
142143

143144
// NewControllerContext returns a new shared set of informers.

pkg/flags/flags.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ var F = struct {
149149
EnableNEGsForIngress bool
150150
EnableIPv6OnlyL4 bool
151151
L4ILBLegacyHeadStartTime time.Duration
152+
EnableL4NetLBRBSByDefault bool
152153

153154
// ===============================
154155
// DEPRECATED FLAGS
@@ -362,6 +363,7 @@ L7 load balancing. CSV values accepted. Example: -node-port-ranges=80,8080,400-5
362363
flag.BoolVar(&F.EnableNEGsForIngress, "enable-negs-for-ingress", true, "Allow the NEG controller to create NEGs for Ingress services.")
363364
flag.BoolVar(&F.EnableIPv6OnlyL4, "enable-ipv6-only-l4", false, "Enables IPv6-only mode for the L4 ILB and NetLB controllers, disabling all IPv4-related logic and resource management.")
364365
flag.DurationVar(&F.L4ILBLegacyHeadStartTime, "prevent-legacy-race-l4-ilb", 0*time.Second, "Delay before processing new L4 ILB services without existing finalizers. This gives the legacy controller a head start to claim the service, preventing a race condition upon service creation.")
366+
flag.BoolVar(&F.EnableL4NetLBRBSByDefault, "enable-l4-netlb-rbs-by-default", false, "Enable L4 NetLB Regional Backend Services by default for new L4 NetLB services.")
365367
}
366368

367369
func Validate() {

pkg/l4lb/l4netlbcontroller.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ type L4NetLBController struct {
8383
serviceVersions *serviceVersionsTracker
8484
enableNEGSupport bool
8585
enableNEGAsDefault bool
86+
enableRBSDefault bool
8687

8788
hasSynced func() bool
8889

@@ -119,6 +120,7 @@ func NewL4NetLBController(
119120
serviceVersions: NewServiceVersionsTracker(),
120121
logger: logger,
121122
hasSynced: ctx.HasSynced,
123+
enableRBSDefault: ctx.EnableL4NetLBRBSByDefault,
122124
}
123125
var networkLister cache.Indexer
124126
if ctx.NetworkInformer != nil {
@@ -386,7 +388,13 @@ func (lc *L4NetLBController) isRBSBasedService(svc *v1.Service, svcLogger klog.L
386388
if svc.Spec.LoadBalancerClass != nil {
387389
return annotations.HasLoadBalancerClass(svc, annotations.RegionalExternalLoadBalancerClass)
388390
}
389-
return annotations.HasRBSAnnotation(svc) || utils.HasL4NetLBFinalizerV2(svc) || utils.HasL4NetLBFinalizerV3(svc) || lc.hasRBSForwardingRule(svc, svcLogger)
391+
if utils.HasL4NetLBFinalizerV1(svc) {
392+
return false
393+
}
394+
if lc.hasLegacyForwardingRule(svc, svcLogger) {
395+
return false
396+
}
397+
return lc.enableRBSDefault || annotations.HasRBSAnnotation(svc) || utils.HasL4NetLBFinalizerV2(svc) || utils.HasL4NetLBFinalizerV3(svc) || lc.hasRBSForwardingRule(svc, svcLogger)
390398
}
391399

392400
func (lc *L4NetLBController) preventLegacyServiceHandling(service *v1.Service, key string, svcLogger klog.Logger) (bool, error) {
@@ -470,6 +478,21 @@ func (lc *L4NetLBController) hasRBSForwardingRule(svc *v1.Service, svcLogger klo
470478
return existingFR != nil && existingFR.LoadBalancingScheme == string(cloud.SchemeExternal) && existingFR.BackendService != ""
471479
}
472480

481+
// hasLegacyForwardingRule checks if services loadbalancer has forwarding rule pointing to target pool
482+
func (lc *L4NetLBController) hasLegacyForwardingRule(svc *v1.Service, svcLogger klog.Logger) bool {
483+
frName := utils.LegacyForwardingRuleName(svc)
484+
// to optimize number of api calls, at first, check if forwarding rule exists in annotation
485+
if lc.hasForwardingRuleAnnotation(svc, frName) {
486+
return true
487+
}
488+
existingFR, err := lc.forwardingRules.Get(frName)
489+
if err != nil {
490+
svcLogger.Error(err, "Error getting forwarding rule", "forwardingRule", frName)
491+
return false
492+
}
493+
return existingFR != nil && existingFR.LoadBalancingScheme == string(cloud.SchemeExternal) && existingFR.Target != ""
494+
}
495+
473496
func (lc *L4NetLBController) SystemHealth() error {
474497
lastEnqueueTime := lc.enqueueTracker.Get()
475498
lastSyncTime := lc.syncTracker.Get()

pkg/l4lb/l4netlbcontroller_test.go

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ func getFakeGCECloud(vals gce.TestClusterValues) *gce.Cloud {
308308
return fakeGCE
309309
}
310310

311-
func buildContext(vals gce.TestClusterValues, readOnlyMode bool) (*ingctx.ControllerContext, error) {
311+
func buildContext(vals gce.TestClusterValues, readOnlyMode bool, isRBSdefault bool) (*ingctx.ControllerContext, error) {
312312
fakeGCE := getFakeGCECloud(vals)
313313
kubeClient := fake.NewSimpleClientset()
314314
networkClient := netfake.NewSimpleClientset()
@@ -317,22 +317,31 @@ func buildContext(vals gce.TestClusterValues, readOnlyMode bool) (*ingctx.Contro
317317
namer := namer.NewNamer(clusterUID, "", klog.TODO())
318318

319319
ctxConfig := ingctx.ControllerContextConfig{
320-
Namespace: v1.NamespaceAll,
321-
ResyncPeriod: 1 * time.Minute,
322-
NumL4NetLBWorkers: 5,
323-
MaxIGSize: 1000,
324-
ReadOnlyMode: readOnlyMode,
320+
Namespace: v1.NamespaceAll,
321+
ResyncPeriod: 1 * time.Minute,
322+
NumL4NetLBWorkers: 5,
323+
MaxIGSize: 1000,
324+
ReadOnlyMode: readOnlyMode,
325+
EnableL4NetLBRBSByDefault: isRBSdefault,
325326
}
326327
return ingctx.NewControllerContext(kubeClient, nil, nil, nil, svcNegClient, nil, networkClient, nil, kubeClient /*kube client to be used for events*/, fakeGCE, namer, "" /*kubeSystemUID*/, ctxConfig, klog.TODO())
327328
}
328329

329330
func newL4NetLBServiceController() *L4NetLBController {
330-
return createL4NetLBServiceController(test.DefaultTestClusterValues(), false)
331+
return createL4NetLBServiceController(test.DefaultTestClusterValues(), false, false)
331332
}
332333

333-
func createL4NetLBServiceController(vals gce.TestClusterValues, readOnlyMode bool) *L4NetLBController {
334+
func newL4NetLBServiceControllerReadOnlyMode(readOnlyMode bool) *L4NetLBController {
335+
return createL4NetLBServiceController(test.DefaultTestClusterValues(), readOnlyMode, false)
336+
}
337+
338+
func newL4NetLBServiceControllerRBSDefault(isRBSdefault bool) *L4NetLBController {
339+
return createL4NetLBServiceController(test.DefaultTestClusterValues(), false, isRBSdefault)
340+
}
341+
342+
func createL4NetLBServiceController(vals gce.TestClusterValues, readOnlyMode bool, isRBSdefault bool) *L4NetLBController {
334343
stopCh := make(chan struct{})
335-
ctx, err := buildContext(vals, readOnlyMode)
344+
ctx, err := buildContext(vals, readOnlyMode, isRBSdefault)
336345
if err != nil {
337346
klog.Fatalf("Failed to build context: %v", err)
338347
}
@@ -1625,6 +1634,7 @@ func TestIsRBSBasedService(t *testing.T) {
16251634
finalizers []string
16261635
annotations map[string]string
16271636
frHook getForwardingRuleHook
1637+
isRBSDefault bool
16281638
expectRBSService bool
16291639
}{
16301640
{
@@ -1661,13 +1671,30 @@ func TestIsRBSBasedService(t *testing.T) {
16611671
frHook: test.GetLegacyForwardingRule,
16621672
expectRBSService: false,
16631673
},
1674+
{
1675+
desc: "Should detect RBS by default",
1676+
isRBSDefault: true,
1677+
expectRBSService: true,
1678+
},
1679+
{
1680+
desc: "Should not detect RBS by forwarding rule pointed to target pool, even if RBS is default",
1681+
frHook: test.GetLegacyForwardingRule,
1682+
isRBSDefault: true,
1683+
expectRBSService: false,
1684+
},
1685+
{
1686+
desc: "Legacy service should not be marked as RBS, even if RBS is default",
1687+
finalizers: []string{common.NetLBFinalizerV1},
1688+
isRBSDefault: true,
1689+
expectRBSService: false,
1690+
},
16641691
}
16651692

16661693
for _, testCase := range testCases {
16671694
t.Run(testCase.desc, func(t *testing.T) {
16681695
// Setup
16691696
svc := test.NewL4LegacyNetLBService(8080, 30234)
1670-
controller := newL4NetLBServiceController()
1697+
controller := newL4NetLBServiceControllerRBSDefault(testCase.isRBSDefault)
16711698
svc.Annotations = testCase.annotations
16721699
svc.ObjectMeta.Finalizers = testCase.finalizers
16731700
controller.ctx.Cloud.Compute().(*cloud.MockGCE).MockForwardingRules.GetHook = testCase.frHook
@@ -2279,7 +2306,7 @@ func TestEnsureExternalLoadBalancerClass(t *testing.T) {
22792306
},
22802307
} {
22812308
t.Run(tc.desc, func(t *testing.T) {
2282-
lc := createL4NetLBServiceController(test.DefaultTestClusterValues(), false)
2309+
lc := newL4NetLBServiceController()
22832310

22842311
svc := test.NewL4LBServiceWithLoadBalancerClass(tc.loadBalancerClass)
22852312
if tc.loadBalancerClass == "" {
@@ -2382,7 +2409,7 @@ func TestEnsureReadOnlyModeDoesNotProvision(t *testing.T) {
23822409
},
23832410
} {
23842411
t.Run(tc.desc, func(t *testing.T) {
2385-
lc := createL4NetLBServiceController(test.DefaultTestClusterValues(), tc.readOnlyModeEnabled)
2412+
lc := newL4NetLBServiceControllerReadOnlyMode(tc.readOnlyModeEnabled)
23862413

23872414
svc := test.NewL4LBServiceWithLoadBalancerClass(tc.loadBalancerClass)
23882415
if tc.loadBalancerClass == "" {

pkg/utils/common/finalizer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ const (
4040
ILBFinalizerV2 = "gke.networking.io/l4-ilb-v2"
4141
// NegFinalizerKey is the finalizer used by neg controller to ensure NEG CRs are deleted after corresponding negs are deleted
4242
NegFinalizerKey = "networking.gke.io/neg-finalizer"
43+
// NetLBFinalizerV1 is the finalizer used by legacy cloud controller manager that manage L4 External LoadBalancer services.
44+
NetLBFinalizerV1 = "gke.networking.io/l4-netlb-v1"
4345
// NetLBFinalizerV2 is the finalizer used by newer controllers that manage L4 External LoadBalancer services.
4446
NetLBFinalizerV2 = "gke.networking.io/l4-netlb-v2"
4547
// NetLBFinalizerV3 is the finalizer used by the NEG backed variant of the L4 External LoadBalancer services.

pkg/utils/utils.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,11 @@ func HasL4ILBFinalizerV2(svc *api_v1.Service) bool {
760760
return slice.ContainsString(svc.ObjectMeta.Finalizers, common.ILBFinalizerV2, nil)
761761
}
762762

763+
// HasL4NetLBFinalizerV1 returns true if the given Service has NetLBFinalizerV1
764+
func HasL4NetLBFinalizerV1(svc *api_v1.Service) bool {
765+
return slice.ContainsString(svc.ObjectMeta.Finalizers, common.NetLBFinalizerV1, nil)
766+
}
767+
763768
// HasL4NetLBFinalizerV2 returns true if the given Service has NetLBFinalizerV2
764769
func HasL4NetLBFinalizerV2(svc *api_v1.Service) bool {
765770
return slice.ContainsString(svc.ObjectMeta.Finalizers, common.NetLBFinalizerV2, nil)

0 commit comments

Comments
 (0)