From 4f284484a0699d568da9dfc5078096cfbf640862 Mon Sep 17 00:00:00 2001 From: Lin Yang Date: Wed, 7 Aug 2024 18:43:55 +0800 Subject: [PATCH] feat: for k8s version >= 1.21, only use endpoints for headless service without selector (#324) Signed-off-by: Lin Yang --- pkg/gateway/processor/mock_processor_generated.go | 12 ++++++------ .../processor/triggers/k8s/endpoints_trigger.go | 4 ++-- pkg/gateway/processor/types.go | 2 +- pkg/gateway/processor/v2/backends.go | 6 ++---- pkg/gateway/processor/v2/triggers.go | 6 ++---- pkg/gateway/processor/v2/utils.go | 7 +++++++ 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/pkg/gateway/processor/mock_processor_generated.go b/pkg/gateway/processor/mock_processor_generated.go index a5916713f..4b9e49541 100644 --- a/pkg/gateway/processor/mock_processor_generated.go +++ b/pkg/gateway/processor/mock_processor_generated.go @@ -133,18 +133,18 @@ func (mr *MockProcessorMockRecorder) IsFilterReferred(arg0 interface{}) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsFilterReferred", reflect.TypeOf((*MockProcessor)(nil).IsFilterReferred), arg0) } -// IsHeadlessService mocks base method. -func (m *MockProcessor) IsHeadlessService(arg0 types.NamespacedName) bool { +// IsHeadlessServiceWithoutSelector mocks base method. +func (m *MockProcessor) IsHeadlessServiceWithoutSelector(arg0 types.NamespacedName) bool { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsHeadlessService", arg0) + ret := m.ctrl.Call(m, "IsHeadlessServiceWithoutSelector", arg0) ret0, _ := ret[0].(bool) return ret0 } -// IsHeadlessService indicates an expected call of IsHeadlessService. -func (mr *MockProcessorMockRecorder) IsHeadlessService(arg0 interface{}) *gomock.Call { +// IsHeadlessServiceWithoutSelector indicates an expected call of IsHeadlessServiceWithoutSelector. +func (mr *MockProcessorMockRecorder) IsHeadlessServiceWithoutSelector(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsHeadlessService", reflect.TypeOf((*MockProcessor)(nil).IsHeadlessService), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsHeadlessServiceWithoutSelector", reflect.TypeOf((*MockProcessor)(nil).IsHeadlessServiceWithoutSelector), arg0) } // IsRoutableLocalTargetServices mocks base method. diff --git a/pkg/gateway/processor/triggers/k8s/endpoints_trigger.go b/pkg/gateway/processor/triggers/k8s/endpoints_trigger.go index 705053a28..cf27793fe 100644 --- a/pkg/gateway/processor/triggers/k8s/endpoints_trigger.go +++ b/pkg/gateway/processor/triggers/k8s/endpoints_trigger.go @@ -21,7 +21,7 @@ func (p *EndpointsTrigger) Insert(obj interface{}, processor processor.Processor key := client.ObjectKeyFromObject(ep) if processor.UseEndpointSlices() { - return processor.IsHeadlessService(key) && processor.IsRoutableService(key) + return processor.IsHeadlessServiceWithoutSelector(key) && processor.IsRoutableService(key) } else { return processor.IsRoutableService(key) } @@ -38,7 +38,7 @@ func (p *EndpointsTrigger) Delete(obj interface{}, processor processor.Processor key := client.ObjectKeyFromObject(ep) if processor.UseEndpointSlices() { - return processor.IsHeadlessService(key) && processor.IsRoutableService(key) + return processor.IsHeadlessServiceWithoutSelector(key) && processor.IsRoutableService(key) } else { return processor.IsRoutableService(key) } diff --git a/pkg/gateway/processor/types.go b/pkg/gateway/processor/types.go index cc5c3f72d..a3b41002e 100644 --- a/pkg/gateway/processor/types.go +++ b/pkg/gateway/processor/types.go @@ -46,7 +46,7 @@ type Processor interface { BuildConfigs() IsEffectiveRoute(parentRefs []gwv1.ParentReference) bool IsRoutableService(service client.ObjectKey) bool - IsHeadlessService(key client.ObjectKey) bool + IsHeadlessServiceWithoutSelector(key client.ObjectKey) bool IsEffectiveTargetRef(policy client.Object, targetRef gwv1alpha2.NamespacedPolicyTargetReference) bool IsRoutableTargetService(policy client.Object, targetRef gwv1alpha2.NamespacedPolicyTargetReference) bool IsRoutableNamespacedTargetServices(policy client.Object, targetRefs []gwv1alpha2.NamespacedPolicyTargetReference) bool diff --git a/pkg/gateway/processor/v2/backends.go b/pkg/gateway/processor/v2/backends.go index 912d38835..38a44bd32 100644 --- a/pkg/gateway/processor/v2/backends.go +++ b/pkg/gateway/processor/v2/backends.go @@ -11,8 +11,6 @@ import ( discoveryv1 "k8s.io/api/discovery/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/flomesh-io/fsm/pkg/k8s" ) func (c *ConfigGenerator) processBackends() []interface{} { @@ -49,8 +47,8 @@ func (c *ConfigGenerator) processBackends() []interface{} { } func (c *ConfigGenerator) calculateEndpoints(svc *corev1.Service, port *int32) []fgwv2.BackendTarget { - // If the Service is headless, use the Endpoints to get the list of backends - if k8s.IsHeadlessService(*svc) { + // If the Service is headless and has no selector, use Endpoints to get the list of backends + if isHeadlessServiceWithoutSelector(svc) { return c.upstreamsByEndpoints(svc, port) } diff --git a/pkg/gateway/processor/v2/triggers.go b/pkg/gateway/processor/v2/triggers.go index 135e23e8c..23c96edd7 100644 --- a/pkg/gateway/processor/v2/triggers.go +++ b/pkg/gateway/processor/v2/triggers.go @@ -7,8 +7,6 @@ import ( corev1 "k8s.io/api/core/v1" - "github.com/flomesh-io/fsm/pkg/k8s" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/fields" @@ -287,14 +285,14 @@ func (c *GatewayProcessor) isFilterReferredByGRPCRoute(filter client.ObjectKey) return len(list.Items) > 0 } -func (c *GatewayProcessor) IsHeadlessService(key client.ObjectKey) bool { +func (c *GatewayProcessor) IsHeadlessServiceWithoutSelector(key client.ObjectKey) bool { service, err := c.getServiceFromCache(key) if err != nil { log.Error().Msgf("failed to get service from processor: %v", err) return false } - return k8s.IsHeadlessService(*service) + return isHeadlessServiceWithoutSelector(service) } func (c *GatewayProcessor) getServiceFromCache(key client.ObjectKey) (*corev1.Service, error) { diff --git a/pkg/gateway/processor/v2/utils.go b/pkg/gateway/processor/v2/utils.go index fe7feee4b..59c1ef12f 100644 --- a/pkg/gateway/processor/v2/utils.go +++ b/pkg/gateway/processor/v2/utils.go @@ -1,8 +1,11 @@ package v2 import ( + corev1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" + "github.com/flomesh-io/fsm/pkg/k8s" + fgwv2 "github.com/flomesh-io/fsm/pkg/gateway/fgw" gwv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -28,3 +31,7 @@ func backendWeight(bk gwv1.BackendRef) int32 { return 1 } + +func isHeadlessServiceWithoutSelector(service *corev1.Service) bool { + return k8s.IsHeadlessService(*service) && len(service.Spec.Selector) == 0 +}