-
Notifications
You must be signed in to change notification settings - Fork 298
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
NEG controller part - L4 RBS External LB NEG support #2566
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,13 +97,16 @@ type Controller struct { | |
// syncerMetrics collects NEG controller metrics | ||
syncerMetrics *syncMetrics.SyncerMetrics | ||
|
||
// runL4 indicates whether to run NEG controller that processes L4 services | ||
runL4 bool | ||
// runL4ForILB indicates whether to run NEG controller that processes L4 ILB services | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My understanding is that this is to preserve the existing behavior and be able to gate the new logic. nit, the existing behavior also turns on NEGs for multi-networking which isn't captured by this boolean. |
||
runL4ForILB bool | ||
|
||
// enableIngressRegionalExternal indicates where NEG controller should process | ||
// gce-regional-external ingresses | ||
enableIngressRegionalExternal bool | ||
|
||
// runL4ForNetLB indicates if the controller can create NEGs for L4 NetLB services. | ||
runL4ForNetLB bool | ||
|
||
stopCh <-chan struct{} | ||
logger klog.Logger | ||
} | ||
|
@@ -140,6 +143,7 @@ func NewController( | |
lpConfig labels.PodLabelPropagationConfig, | ||
enableMultiNetworking bool, | ||
enableIngressRegionalExternal bool, | ||
runL4ForNetLB bool, | ||
stopCh <-chan struct{}, | ||
logger klog.Logger, | ||
) *Controller { | ||
|
@@ -231,8 +235,9 @@ func NewController( | |
syncTracker: utils.NewTimeTracker(), | ||
reflector: reflector, | ||
syncerMetrics: syncerMetrics, | ||
runL4: runL4Controller, | ||
runL4ForILB: runL4Controller, | ||
enableIngressRegionalExternal: enableIngressRegionalExternal, | ||
runL4ForNetLB: runL4ForNetLB, | ||
stopCh: stopCh, | ||
logger: logger, | ||
} | ||
|
@@ -503,7 +508,8 @@ func (c *Controller) processService(key string) error { | |
} | ||
} | ||
|
||
if c.runL4 { | ||
// Create L4 PortInfo if subsetting is enable `runL4ForILB==true` or RBS NEG support is enabled `runL4ForNetLB==true`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or if multi networking is enabled? |
||
if c.runL4ForILB || c.runL4ForNetLB { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we check for the variables again in the utils function, do we need the check here still? |
||
if err := c.mergeVmIpNEGsPortInfo(service, types.NamespacedName{Namespace: namespace, Name: name}, svcPortInfoMap, &negUsage, networkInfo); err != nil { | ||
return err | ||
} | ||
|
@@ -597,13 +603,13 @@ func (c *Controller) mergeStandaloneNEGsPortInfo(service *apiv1.Service, name ty | |
// mergeVmIpNEGsPortInfo merges the PortInfo for ILB and multinet NetLB services using GCE_VM_IP NEGs into portInfoMap | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: update the comments to include NEG default |
||
func (c *Controller) mergeVmIpNEGsPortInfo(service *apiv1.Service, name types.NamespacedName, portInfoMap negtypes.PortInfoMap, negUsage *metricscollector.NegServiceState, networkInfo *network.NetworkInfo) error { | ||
wantsILB, _ := annotations.WantsL4ILB(service) | ||
wantsNetLB, _ := annotations.WantsL4NetLB(service) | ||
needsNEGForNetLB := wantsNetLB && !networkInfo.IsDefault && annotations.HasRBSAnnotation(service) | ||
if !wantsILB && !needsNEGForNetLB { | ||
needsNEGForILB := c.runL4ForILB && wantsILB | ||
needsNEGForNetLB := c.netLBServiceNeedsNEG(service, networkInfo) | ||
if !needsNEGForILB && !needsNEGForNetLB { | ||
return nil | ||
} | ||
// Only process ILB services after L4 controller has marked it with v2 finalizer. | ||
if wantsILB && !utils.IsSubsettingL4ILBService(service) { | ||
if needsNEGForILB && !utils.IsSubsettingL4ILBService(service) { | ||
msg := fmt.Sprintf("Ignoring ILB Service %s, namespace %s as it does not have the v2 finalizer", service.Name, service.Namespace) | ||
c.logger.Info(msg) | ||
c.recorder.Eventf(service, apiv1.EventTypeWarning, "ProcessServiceSkipped", msg) | ||
|
@@ -619,8 +625,32 @@ func (c *Controller) mergeVmIpNEGsPortInfo(service *apiv1.Service, name types.Na | |
onlyLocal := helpers.RequestsOnlyLocalTraffic(service) | ||
// Update usage metrics. | ||
negUsage.VmIpNeg = metricscollector.NewVmIpNegType(onlyLocal) | ||
var l4LBType negtypes.L4LBType | ||
if needsNEGForILB { | ||
l4LBType = negtypes.L4InternalLB | ||
} else { | ||
l4LBType = negtypes.L4ExternalLB | ||
} | ||
|
||
return portInfoMap.Merge(negtypes.NewPortInfoMapForVMIPNEG(name.Namespace, name.Name, c.l4Namer, onlyLocal, networkInfo)) | ||
return portInfoMap.Merge(negtypes.NewPortInfoMapForVMIPNEG(name.Namespace, name.Name, c.l4Namer, onlyLocal, networkInfo, l4LBType)) | ||
} | ||
|
||
// netLBServiceNeedsNEG determines if NEGs need to be created for L4 NetLB. | ||
// - service must be an L4 External Load Balancer service | ||
// - service must have the RBS annotation | ||
// - service is a multinetwork service on a non default network OR NEGs are enabled and V3 finalizer is present. | ||
func (c *Controller) netLBServiceNeedsNEG(service *apiv1.Service, networkInfo *network.NetworkInfo) bool { | ||
wantsNetLB, _ := annotations.WantsL4NetLB(service) | ||
if !wantsNetLB { | ||
return false | ||
} | ||
if !annotations.HasRBSAnnotation(service) { | ||
return false | ||
} | ||
if !networkInfo.IsDefault { | ||
return true | ||
} | ||
return c.runL4ForNetLB && utils.HasL4NetLBFinalizerV3(service) | ||
} | ||
|
||
// mergeDefaultBackendServicePortInfoMap merge the PortInfoMap for the default backend service into portInfoMap | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -158,6 +158,7 @@ func newTestControllerWithParamsAndContext(kubeClient kubernetes.Interface, test | |
labels.PodLabelPropagationConfig{}, | ||
true, | ||
false, | ||
false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add tests where this is true? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added a test case to verify combinations of this being turned off etc |
||
make(<-chan struct{}), | ||
klog.TODO(), | ||
) | ||
|
@@ -388,7 +389,7 @@ func TestEnableNEGServiceWithL4ILB(t *testing.T) { | |
if err != nil { | ||
t.Fatalf("Service was not created.(*apiv1.Service) successfully, err: %v", err) | ||
} | ||
expectedPortInfoMap := negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, false, defaultNetwork) | ||
expectedPortInfoMap := negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, false, defaultNetwork, negtypes.L4InternalLB) | ||
// There will be only one entry in the map | ||
for key, val := range expectedPortInfoMap { | ||
prevSyncerKey = manager.getSyncerKey(testServiceNamespace, testServiceName, key, val) | ||
|
@@ -409,7 +410,7 @@ func TestEnableNEGServiceWithL4ILB(t *testing.T) { | |
if err = controller.processService(svcKey); err != nil { | ||
t.Fatalf("Failed to process updated L4 ILB service: %v", err) | ||
} | ||
expectedPortInfoMap = negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, true, defaultNetwork) | ||
expectedPortInfoMap = negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, true, defaultNetwork, negtypes.L4InternalLB) | ||
// There will be only one entry in the map | ||
for key, val := range expectedPortInfoMap { | ||
updatedSyncerKey = manager.getSyncerKey(testServiceNamespace, testServiceName, key, val) | ||
|
@@ -1258,13 +1259,16 @@ func TestMergeVmIpNEGsPortInfo(t *testing.T) { | |
desc string | ||
svc *apiv1.Service | ||
networkInfo *network.NetworkInfo | ||
runL4ILB bool | ||
runL4NetLB bool | ||
wantSvcPortMap negtypes.PortInfoMap | ||
}{ | ||
{ | ||
desc: "ILB subsetting service", | ||
svc: serviceILBWithFinalizer, | ||
networkInfo: defaultNetwork, | ||
wantSvcPortMap: negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, false, defaultNetwork), | ||
runL4ILB: true, | ||
wantSvcPortMap: negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, false, defaultNetwork, negtypes.L4InternalLB), | ||
}, | ||
{ | ||
desc: "ILB legacy service", | ||
|
@@ -1276,14 +1280,28 @@ func TestMergeVmIpNEGsPortInfo(t *testing.T) { | |
desc: "RBS Multinet Service", | ||
svc: newTestRBSMultinetService(controller, true, 80), | ||
networkInfo: secondaryNetwork, | ||
wantSvcPortMap: negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, true, secondaryNetwork), | ||
wantSvcPortMap: negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, true, secondaryNetwork, negtypes.L4ExternalLB), | ||
}, | ||
{ | ||
desc: "RBS non-multinet Service", | ||
svc: newTestRBSMultinetService(controller, true, 80), | ||
svc: newTestRBSService(controller, true, 80, common.NetLBFinalizerV2), | ||
networkInfo: defaultNetwork, | ||
wantSvcPortMap: nil, | ||
}, | ||
{ | ||
desc: "RBS non-multinet Service with NEG", | ||
svc: newTestRBSService(controller, true, 80, common.NetLBFinalizerV3), | ||
networkInfo: defaultNetwork, | ||
runL4NetLB: true, | ||
wantSvcPortMap: negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, true, defaultNetwork, negtypes.L4ExternalLB), | ||
}, | ||
{ | ||
desc: "RBS non-multinet Service with NEG but NEGs not enabled for NetLB", | ||
svc: newTestRBSService(controller, true, 80, common.NetLBFinalizerV3), | ||
networkInfo: defaultNetwork, | ||
runL4NetLB: false, | ||
wantSvcPortMap: nil, | ||
}, | ||
{ | ||
desc: "Service with load balancer class", | ||
svc: serviceWithLoadBalancerClass, | ||
|
@@ -1294,6 +1312,8 @@ func TestMergeVmIpNEGsPortInfo(t *testing.T) { | |
|
||
for _, tc := range testCases { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
controller.runL4ForNetLB = tc.runL4NetLB | ||
controller.runL4ForILB = tc.runL4ILB | ||
portInfoMap := make(negtypes.PortInfoMap) | ||
negUsage := metricscollector.NegServiceState{} | ||
controller.mergeVmIpNEGsPortInfo(tc.svc, types.NamespacedName{Namespace: tc.svc.Namespace, Name: tc.svc.Name}, portInfoMap, &negUsage, tc.networkInfo) | ||
|
@@ -1609,7 +1629,7 @@ func TestEnableNEGServiceWithL4NetLB(t *testing.T) { | |
if err != nil { | ||
t.Fatalf("Service was not created.(*apiv1.Service) successfully, err: %v", err) | ||
} | ||
expectedPortInfoMap := negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, true, networkInfo) | ||
expectedPortInfoMap := negtypes.NewPortInfoMapForVMIPNEG(testServiceNamespace, testServiceName, controller.l4Namer, true, networkInfo, negtypes.L4ExternalLB) | ||
// There will be only one entry in the map | ||
for key, val := range expectedPortInfoMap { | ||
prevSyncerKey = manager.getSyncerKey(testServiceNamespace, testServiceName, key, val) | ||
|
@@ -2020,6 +2040,29 @@ func newTestRBSMultinetService(c *Controller, onlyLocal bool, port int) *apiv1.S | |
return svc | ||
} | ||
|
||
func newTestRBSService(c *Controller, onlyLocal bool, port int, finalizer string) *apiv1.Service { | ||
svc := &apiv1.Service{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: testServiceName, | ||
Namespace: testServiceNamespace, | ||
Annotations: map[string]string{annotations.RBSAnnotationKey: annotations.RBSEnabled}, | ||
Finalizers: []string{finalizer}, | ||
}, | ||
Spec: apiv1.ServiceSpec{ | ||
Type: apiv1.ServiceTypeLoadBalancer, | ||
Ports: []apiv1.ServicePort{ | ||
{Name: "testport", Port: int32(port)}, | ||
}, | ||
}, | ||
} | ||
if onlyLocal { | ||
svc.Spec.ExternalTrafficPolicy = apiv1.ServiceExternalTrafficPolicyTypeLocal | ||
} | ||
|
||
c.client.CoreV1().Services(testServiceNamespace).Create(context.TODO(), svc, metav1.CreateOptions{}) | ||
return svc | ||
} | ||
|
||
func newTestService(c *Controller, negIngress bool, negSvcPorts []int32) *apiv1.Service { | ||
svcAnnotations := map[string]string{} | ||
if negIngress || len(negSvcPorts) > 0 { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do these interact with EnableL4NEG? I think there should be a requirement that EnableL4NEG is enabled too for these new flags