From 0960c0f0402bd6dab31c9b424ef59246fd4003b8 Mon Sep 17 00:00:00 2001 From: Lan Luo Date: Mon, 11 Oct 2021 18:31:24 +0800 Subject: [PATCH] Support NodeLocal DNSCache with AntreaProxy Resolves #2137 Signed-off-by: Lan Luo --- build/yamls/antrea-aks.yml | 12 ++- build/yamls/antrea-eks.yml | 12 ++- build/yamls/antrea-gke.yml | 12 ++- build/yamls/antrea-ipsec.yml | 12 ++- build/yamls/antrea.yml | 12 ++- build/yamls/base/conf/antrea-agent.conf | 4 + cmd/antrea-agent/agent.go | 7 +- cmd/antrea-agent/config.go | 4 + cmd/antrea-agent/options.go | 4 + pkg/agent/proxy/proxier.go | 12 +-- pkg/agent/proxy/proxier_test.go | 112 ++++++++++++++++++------ pkg/agent/proxy/service.go | 4 +- third_party/proxy/service.go | 15 +++- third_party/proxy/util/utils.go | 11 ++- 14 files changed, 171 insertions(+), 62 deletions(-) diff --git a/build/yamls/antrea-aks.yml b/build/yamls/antrea-aks.yml index 350e5665607..e4ab7d84f86 100644 --- a/build/yamls/antrea-aks.yml +++ b/build/yamls/antrea-aks.yml @@ -3948,6 +3948,10 @@ data: # (e.g. 1.2.3.0/24, 1.2.3.4/32). An empty string slice is meant to select all host IPv4/IPv6 addresses. # Note that the option is only valid when proxyAll is true. #nodePortAddresses: [] + # An array of string values to specify a list of Services which should be ignored by AntreaProxy (traffic to these + # Services will not be load-balanced). Values can be a valid ClusterIP (e.g. 10.11.1.2) or a Service name + # with Namespace (e.g. kube-system/kube-dns) + #skipServices: [] antrea-cni.conflist: | { "cniVersion":"0.3.0", @@ -4054,7 +4058,7 @@ metadata: annotations: {} labels: app: antrea - name: antrea-config-b72h88gb7b + name: antrea-config-4d7ch86gch namespace: kube-system --- apiVersion: v1 @@ -4125,7 +4129,7 @@ spec: fieldRef: fieldPath: spec.serviceAccountName - name: ANTREA_CONFIG_MAP_NAME - value: antrea-config-b72h88gb7b + value: antrea-config-4d7ch86gch image: projects.registry.vmware.com/antrea/antrea-ubuntu:latest imagePullPolicy: IfNotPresent livenessProbe: @@ -4176,7 +4180,7 @@ spec: key: node-role.kubernetes.io/master volumes: - configMap: - name: antrea-config-b72h88gb7b + name: antrea-config-4d7ch86gch name: antrea-config - name: antrea-controller-tls secret: @@ -4457,7 +4461,7 @@ spec: operator: Exists volumes: - configMap: - name: antrea-config-b72h88gb7b + name: antrea-config-4d7ch86gch name: antrea-config - hostPath: path: /etc/cni/net.d diff --git a/build/yamls/antrea-eks.yml b/build/yamls/antrea-eks.yml index 54754f9843a..3f1a025027c 100644 --- a/build/yamls/antrea-eks.yml +++ b/build/yamls/antrea-eks.yml @@ -3948,6 +3948,10 @@ data: # (e.g. 1.2.3.0/24, 1.2.3.4/32). An empty string slice is meant to select all host IPv4/IPv6 addresses. # Note that the option is only valid when proxyAll is true. #nodePortAddresses: [] + # An array of string values to specify a list of Services which should be ignored by AntreaProxy (traffic to these + # Services will not be load-balanced). Values can be a valid ClusterIP (e.g. 10.11.1.2) or a Service name + # with Namespace (e.g. kube-system/kube-dns) + #skipServices: [] antrea-cni.conflist: | { "cniVersion":"0.3.0", @@ -4054,7 +4058,7 @@ metadata: annotations: {} labels: app: antrea - name: antrea-config-b72h88gb7b + name: antrea-config-4d7ch86gch namespace: kube-system --- apiVersion: v1 @@ -4125,7 +4129,7 @@ spec: fieldRef: fieldPath: spec.serviceAccountName - name: ANTREA_CONFIG_MAP_NAME - value: antrea-config-b72h88gb7b + value: antrea-config-4d7ch86gch image: projects.registry.vmware.com/antrea/antrea-ubuntu:latest imagePullPolicy: IfNotPresent livenessProbe: @@ -4176,7 +4180,7 @@ spec: key: node-role.kubernetes.io/master volumes: - configMap: - name: antrea-config-b72h88gb7b + name: antrea-config-4d7ch86gch name: antrea-config - name: antrea-controller-tls secret: @@ -4459,7 +4463,7 @@ spec: operator: Exists volumes: - configMap: - name: antrea-config-b72h88gb7b + name: antrea-config-4d7ch86gch name: antrea-config - hostPath: path: /etc/cni/net.d diff --git a/build/yamls/antrea-gke.yml b/build/yamls/antrea-gke.yml index a7f56f47a04..2034cb3601b 100644 --- a/build/yamls/antrea-gke.yml +++ b/build/yamls/antrea-gke.yml @@ -3948,6 +3948,10 @@ data: # (e.g. 1.2.3.0/24, 1.2.3.4/32). An empty string slice is meant to select all host IPv4/IPv6 addresses. # Note that the option is only valid when proxyAll is true. #nodePortAddresses: [] + # An array of string values to specify a list of Services which should be ignored by AntreaProxy (traffic to these + # Services will not be load-balanced). Values can be a valid ClusterIP (e.g. 10.11.1.2) or a Service name + # with Namespace (e.g. kube-system/kube-dns) + #skipServices: [] antrea-cni.conflist: | { "cniVersion":"0.3.0", @@ -4054,7 +4058,7 @@ metadata: annotations: {} labels: app: antrea - name: antrea-config-hfkckg6t57 + name: antrea-config-ct7fm8k579 namespace: kube-system --- apiVersion: v1 @@ -4125,7 +4129,7 @@ spec: fieldRef: fieldPath: spec.serviceAccountName - name: ANTREA_CONFIG_MAP_NAME - value: antrea-config-hfkckg6t57 + value: antrea-config-ct7fm8k579 image: projects.registry.vmware.com/antrea/antrea-ubuntu:latest imagePullPolicy: IfNotPresent livenessProbe: @@ -4176,7 +4180,7 @@ spec: key: node-role.kubernetes.io/master volumes: - configMap: - name: antrea-config-hfkckg6t57 + name: antrea-config-ct7fm8k579 name: antrea-config - name: antrea-controller-tls secret: @@ -4460,7 +4464,7 @@ spec: path: /home/kubernetes/bin name: host-cni-bin - configMap: - name: antrea-config-hfkckg6t57 + name: antrea-config-ct7fm8k579 name: antrea-config - hostPath: path: /etc/cni/net.d diff --git a/build/yamls/antrea-ipsec.yml b/build/yamls/antrea-ipsec.yml index d2e14e6c6da..ecbce68ffb0 100644 --- a/build/yamls/antrea-ipsec.yml +++ b/build/yamls/antrea-ipsec.yml @@ -3953,6 +3953,10 @@ data: # (e.g. 1.2.3.0/24, 1.2.3.4/32). An empty string slice is meant to select all host IPv4/IPv6 addresses. # Note that the option is only valid when proxyAll is true. #nodePortAddresses: [] + # An array of string values to specify a list of Services which should be ignored by AntreaProxy (traffic to these + # Services will not be load-balanced). Values can be a valid ClusterIP (e.g. 10.11.1.2) or a Service name + # with Namespace (e.g. kube-system/kube-dns) + #skipServices: [] antrea-cni.conflist: | { "cniVersion":"0.3.0", @@ -4059,7 +4063,7 @@ metadata: annotations: {} labels: app: antrea - name: antrea-config-4f28b82tdt + name: antrea-config-7tm5f22tt7 namespace: kube-system --- apiVersion: v1 @@ -4139,7 +4143,7 @@ spec: fieldRef: fieldPath: spec.serviceAccountName - name: ANTREA_CONFIG_MAP_NAME - value: antrea-config-4f28b82tdt + value: antrea-config-7tm5f22tt7 image: projects.registry.vmware.com/antrea/antrea-ubuntu:latest imagePullPolicy: IfNotPresent livenessProbe: @@ -4190,7 +4194,7 @@ spec: key: node-role.kubernetes.io/master volumes: - configMap: - name: antrea-config-4f28b82tdt + name: antrea-config-7tm5f22tt7 name: antrea-config - name: antrea-controller-tls secret: @@ -4506,7 +4510,7 @@ spec: operator: Exists volumes: - configMap: - name: antrea-config-4f28b82tdt + name: antrea-config-7tm5f22tt7 name: antrea-config - hostPath: path: /etc/cni/net.d diff --git a/build/yamls/antrea.yml b/build/yamls/antrea.yml index cdc475cd538..994023c84c0 100644 --- a/build/yamls/antrea.yml +++ b/build/yamls/antrea.yml @@ -3953,6 +3953,10 @@ data: # (e.g. 1.2.3.0/24, 1.2.3.4/32). An empty string slice is meant to select all host IPv4/IPv6 addresses. # Note that the option is only valid when proxyAll is true. #nodePortAddresses: [] + # An array of string values to specify a list of Services which should be ignored by AntreaProxy (traffic to these + # Services will not be load-balanced). Values can be a valid ClusterIP (e.g. 10.11.1.2) or a Service name + # with Namespace (e.g. kube-system/kube-dns) + #skipServices: [] antrea-cni.conflist: | { "cniVersion":"0.3.0", @@ -4059,7 +4063,7 @@ metadata: annotations: {} labels: app: antrea - name: antrea-config-bmthb2m52d + name: antrea-config-4g55dbc872 namespace: kube-system --- apiVersion: v1 @@ -4130,7 +4134,7 @@ spec: fieldRef: fieldPath: spec.serviceAccountName - name: ANTREA_CONFIG_MAP_NAME - value: antrea-config-bmthb2m52d + value: antrea-config-4g55dbc872 image: projects.registry.vmware.com/antrea/antrea-ubuntu:latest imagePullPolicy: IfNotPresent livenessProbe: @@ -4181,7 +4185,7 @@ spec: key: node-role.kubernetes.io/master volumes: - configMap: - name: antrea-config-bmthb2m52d + name: antrea-config-4g55dbc872 name: antrea-config - name: antrea-controller-tls secret: @@ -4462,7 +4466,7 @@ spec: operator: Exists volumes: - configMap: - name: antrea-config-bmthb2m52d + name: antrea-config-4g55dbc872 name: antrea-config - hostPath: path: /etc/cni/net.d diff --git a/build/yamls/base/conf/antrea-agent.conf b/build/yamls/base/conf/antrea-agent.conf index 76d6d72b613..0dcd5b4519e 100644 --- a/build/yamls/base/conf/antrea-agent.conf +++ b/build/yamls/base/conf/antrea-agent.conf @@ -190,3 +190,7 @@ antreaProxy: # (e.g. 1.2.3.0/24, 1.2.3.4/32). An empty string slice is meant to select all host IPv4/IPv6 addresses. # Note that the option is only valid when proxyAll is true. #nodePortAddresses: [] + # An array of string values to specify a list of Services which should be ignored by AntreaProxy (traffic to these + # Services will not be load-balanced). Values can be a valid ClusterIP (e.g. 10.11.1.2) or a Service name + # with Namespace (e.g. kube-system/kube-dns) + #skipServices: [] diff --git a/cmd/antrea-agent/agent.go b/cmd/antrea-agent/agent.go index 41fb02c9a78..225ffeb2df2 100644 --- a/cmd/antrea-agent/agent.go +++ b/cmd/antrea-agent/agent.go @@ -203,14 +203,15 @@ func run(o *Options) error { v4Enabled := config.IsIPv4Enabled(nodeConfig, networkConfig.TrafficEncapMode) v6Enabled := config.IsIPv6Enabled(nodeConfig, networkConfig.TrafficEncapMode) proxyAll := o.config.AntreaProxy.ProxyAll + skipServices := o.config.AntreaProxy.SkipServices switch { case v4Enabled && v6Enabled: - proxier = proxy.NewDualStackProxier(nodeConfig.Name, informerFactory, ofClient, routeClient, nodePortAddressesIPv4, nodePortAddressesIPv6, proxyAll) + proxier = proxy.NewDualStackProxier(nodeConfig.Name, informerFactory, ofClient, routeClient, nodePortAddressesIPv4, nodePortAddressesIPv6, proxyAll, skipServices) case v4Enabled: - proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, false, routeClient, nodePortAddressesIPv4, proxyAll) + proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, false, routeClient, nodePortAddressesIPv4, proxyAll, skipServices) case v6Enabled: - proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, true, routeClient, nodePortAddressesIPv6, proxyAll) + proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, true, routeClient, nodePortAddressesIPv6, proxyAll, skipServices) default: return fmt.Errorf("at least one of IPv4 or IPv6 should be enabled") } diff --git a/cmd/antrea-agent/config.go b/cmd/antrea-agent/config.go index fd1c9fe6054..2ab42d9c14b 100644 --- a/cmd/antrea-agent/config.go +++ b/cmd/antrea-agent/config.go @@ -186,6 +186,10 @@ type AntreaProxyConfig struct { // A string array of values which specifies the host IPv4/IPv6 addresses for NodePorts. Values may be valid IP blocks. // (e.g. 1.2.3.0/24, 1.2.3.4/32). An empty string slice is meant to select all host IPv4/IPv6 addresses. NodePortAddresses []string `yaml:"nodePortAddresses,omitempty"` + // An array of string values to specify a list of Services which should be ignored by AntreaProxy (traffic to these + // Services will not be load-balanced). Values can be a valid ClusterIP (e.g. 10.11.1.2) or a Service name + // with Namespace (e.g. kube-system/kube-dns) + SkipServices []string `yaml:"skipServices,omitempty"` } type WireGuardConfig struct { diff --git a/cmd/antrea-agent/options.go b/cmd/antrea-agent/options.go index 077a22e16b4..716497e6029 100644 --- a/cmd/antrea-agent/options.go +++ b/cmd/antrea-agent/options.go @@ -232,6 +232,10 @@ func (o *Options) setDefaults() { } func (o *Options) validateAntreaProxyConfig() error { + if !features.DefaultFeatureGate.Enabled(features.AntreaProxy) && len(o.config.AntreaProxy.SkipServices) > 0 { + klog.InfoS("skipServices will be ignored because AntreaProxy is disabled", "skipServices", o.config.AntreaProxy.SkipServices) + } + if o.config.AntreaProxy.ProxyAll { for _, nodePortAddress := range o.config.AntreaProxy.NodePortAddresses { if _, _, err := net.ParseCIDR(nodePortAddress); err != nil { diff --git a/pkg/agent/proxy/proxier.go b/pkg/agent/proxy/proxier.go index 30b3b66224c..e3eb3470da0 100644 --- a/pkg/agent/proxy/proxier.go +++ b/pkg/agent/proxy/proxier.go @@ -782,7 +782,8 @@ func NewProxier( isIPv6 bool, routeClient route.Interface, nodePortAddresses []net.IP, - proxyAllEnabled bool) *proxier { + proxyAllEnabled bool, + skipServices []string) *proxier { recorder := record.NewBroadcaster().NewRecorder( runtime.NewScheme(), corev1.EventSource{Component: componentName, Host: hostname}, @@ -800,7 +801,7 @@ func NewProxier( endpointsConfig: config.NewEndpointsConfig(informerFactory.Core().V1().Endpoints(), resyncPeriod), serviceConfig: config.NewServiceConfig(informerFactory.Core().V1().Services(), resyncPeriod), endpointsChanges: newEndpointsChangesTracker(hostname, endpointSliceEnabled, isIPv6), - serviceChanges: newServiceChangesTracker(recorder, ipFamily), + serviceChanges: newServiceChangesTracker(recorder, ipFamily, skipServices), serviceMap: k8sproxy.ServiceMap{}, serviceInstalledMap: k8sproxy.ServiceMap{}, endpointsInstalledMap: types.EndpointsMap{}, @@ -866,13 +867,14 @@ func NewDualStackProxier( routeClient route.Interface, nodePortAddressesIPv4 []net.IP, nodePortAddressesIPv6 []net.IP, - proxyAllEnabled bool) *metaProxierWrapper { + proxyAllEnabled bool, + skipServices []string) *metaProxierWrapper { // Create an IPv4 instance of the single-stack proxier. - ipv4Proxier := NewProxier(hostname, informerFactory, ofClient, false, routeClient, nodePortAddressesIPv4, proxyAllEnabled) + ipv4Proxier := NewProxier(hostname, informerFactory, ofClient, false, routeClient, nodePortAddressesIPv4, proxyAllEnabled, skipServices) // Create an IPv6 instance of the single-stack proxier. - ipv6Proxier := NewProxier(hostname, informerFactory, ofClient, true, routeClient, nodePortAddressesIPv6, proxyAllEnabled) + ipv6Proxier := NewProxier(hostname, informerFactory, ofClient, true, routeClient, nodePortAddressesIPv6, proxyAllEnabled, skipServices) // Create a meta-proxier that dispatch calls between the two // single-stack proxier instances. diff --git a/pkg/agent/proxy/proxier_test.go b/pkg/agent/proxy/proxier_test.go index 577f13ca867..b9e4e391203 100644 --- a/pkg/agent/proxy/proxier_test.go +++ b/pkg/agent/proxy/proxier_test.go @@ -114,7 +114,7 @@ func NewFakeProxier(routeClient route.Interface, ofClient openflow.Client, nodeP p := &proxier{ endpointsChanges: newEndpointsChangesTracker(hostname, false, isIPv6), - serviceChanges: newServiceChangesTracker(recorder, ipFamily), + serviceChanges: newServiceChangesTracker(recorder, ipFamily, []string{"kube-system/kube-dns", "192.168.1.2"}), serviceMap: k8sproxy.ServiceMap{}, serviceInstalledMap: k8sproxy.ServiceMap{}, endpointsInstalledMap: types.EndpointsMap{}, @@ -132,7 +132,7 @@ func NewFakeProxier(routeClient route.Interface, ofClient openflow.Client, nodeP return p } -func testClusterIP(t *testing.T, svcIP net.IP, epIP net.IP, isIPv6 bool) { +func testClusterIP(t *testing.T, svcIP net.IP, epIP net.IP, isIPv6 bool, extraSvcs []*corev1.Service, extraEps []*corev1.Endpoints) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockOFClient := ofmock.NewMockClient(ctrl) @@ -145,31 +145,30 @@ func testClusterIP(t *testing.T, svcIP net.IP, epIP net.IP, isIPv6 bool) { Port: "80", Protocol: corev1.ProtocolTCP, } - makeServiceMap(fp, - makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *corev1.Service) { - svc.Spec.ClusterIP = svcIP.String() - svc.Spec.Ports = []corev1.ServicePort{{ + + allServices := append(extraSvcs, makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *corev1.Service) { + svc.Spec.ClusterIP = svcIP.String() + svc.Spec.Ports = []corev1.ServicePort{{ + Name: svcPortName.Port, + Port: int32(svcPort), + Protocol: corev1.ProtocolTCP, + }} + })) + makeServiceMap(fp, allServices...) + + allEps := append(extraEps, makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *corev1.Endpoints) { + ept.Subsets = []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{ + IP: epIP.String(), + }}, + Ports: []corev1.EndpointPort{{ Name: svcPortName.Port, Port: int32(svcPort), Protocol: corev1.ProtocolTCP, - }} - }), - ) - - makeEndpointsMap(fp, - makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *corev1.Endpoints) { - ept.Subsets = []corev1.EndpointSubset{{ - Addresses: []corev1.EndpointAddress{{ - IP: epIP.String(), - }}, - Ports: []corev1.EndpointPort{{ - Name: svcPortName.Port, - Port: int32(svcPort), - Protocol: corev1.ProtocolTCP, - }}, - }} - }), - ) + }}, + }} + })) + makeEndpointsMap(fp, allEps...) groupID, _ := fp.groupCounter.Get(svcPortName, false) mockOFClient.EXPECT().InstallServiceGroup(groupID, false, gomock.Any()).Times(1) @@ -394,11 +393,70 @@ func TestNodePortIPv6ExternalLocal(t *testing.T) { } func TestClusterIPv4(t *testing.T) { - testClusterIP(t, svcIPv4, ep1IPv4, false) + testClusterIP(t, svcIPv4, ep1IPv4, false, []*corev1.Service{}, []*corev1.Endpoints{}) } func TestClusterIPv6(t *testing.T) { - testClusterIP(t, svcIPv6, ep1IPv6, true) + testClusterIP(t, svcIPv6, ep1IPv6, true, []*corev1.Service{}, []*corev1.Endpoints{}) +} + +func TestClusterSkipServices(t *testing.T) { + svc1Port := 53 + svc1PortName := k8sproxy.ServicePortName{ + NamespacedName: makeNamespaceName("kube-system", "kube-dns"), + Port: "53", + Protocol: corev1.ProtocolTCP, + } + svc2Port := 88 + svc2PortName := k8sproxy.ServicePortName{ + NamespacedName: makeNamespaceName("kube-system", "test"), + Port: "88", + Protocol: corev1.ProtocolTCP, + } + svc1 := makeTestService(svc1PortName.Namespace, svc1PortName.Name, func(svc *corev1.Service) { + svc.Spec.ClusterIP = "10.96.10.12" + svc.Spec.Ports = []corev1.ServicePort{{ + Name: svc1PortName.Port, + Port: int32(svc1Port), + Protocol: corev1.ProtocolTCP, + }} + }) + svc2 := makeTestService(svc2PortName.Namespace, svc2PortName.Name, func(svc *corev1.Service) { + svc.Spec.ClusterIP = "192.168.1.2" + svc.Spec.Ports = []corev1.ServicePort{{ + Name: svc2PortName.Port, + Port: int32(svc2Port), + Protocol: corev1.ProtocolTCP, + }} + }) + svcs := []*corev1.Service{svc1, svc2} + + ep1 := makeTestEndpoints(svc1PortName.Namespace, svc1PortName.Name, func(ept *corev1.Endpoints) { + ept.Subsets = []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{ + IP: "172.16.1.2", + }}, + Ports: []corev1.EndpointPort{{ + Name: svc1PortName.Port, + Port: int32(svc1Port), + Protocol: corev1.ProtocolTCP, + }}, + }} + }) + ep2 := makeTestEndpoints(svc2PortName.Namespace, svc2PortName.Name, func(ept *corev1.Endpoints) { + ept.Subsets = []corev1.EndpointSubset{{ + Addresses: []corev1.EndpointAddress{{ + IP: "172.16.1.3", + }}, + Ports: []corev1.EndpointPort{{ + Name: svc2PortName.Port, + Port: int32(svc2Port), + Protocol: corev1.ProtocolTCP, + }}, + }} + }) + eps := []*corev1.Endpoints{ep1, ep2} + testClusterIP(t, svcIPv4, ep1IPv4, false, svcs, eps) } func TestDualStackService(t *testing.T) { @@ -1027,7 +1085,7 @@ func TestMetrics(t *testing.T) { endpointsInstallMetric = metrics.EndpointsInstalledTotalV6.GaugeMetric servicesInstallMetric = metrics.ServicesInstalledTotalV6.GaugeMetric } - testClusterIP(t, net.ParseIP(tc.svcIP), net.ParseIP(tc.epIP), tc.isIPv6) + testClusterIP(t, net.ParseIP(tc.svcIP), net.ParseIP(tc.epIP), tc.isIPv6, []*corev1.Service{}, []*corev1.Endpoints{}) v, err := testutil.GetCounterMetricValue(endpointsUpdateTotalMetric) assert.NoError(t, err) assert.Equal(t, 0, int(v)) diff --git a/pkg/agent/proxy/service.go b/pkg/agent/proxy/service.go index b6fb264e94f..67557e73440 100644 --- a/pkg/agent/proxy/service.go +++ b/pkg/agent/proxy/service.go @@ -31,8 +31,8 @@ type serviceChangesTracker struct { initialized bool } -func newServiceChangesTracker(recorder record.EventRecorder, ipFamily v1.IPFamily) *serviceChangesTracker { - return &serviceChangesTracker{tracker: k8sproxy.NewServiceChangeTracker(types.NewServiceInfo, ipFamily, recorder, nil)} +func newServiceChangesTracker(recorder record.EventRecorder, ipFamily v1.IPFamily, skipServices []string) *serviceChangesTracker { + return &serviceChangesTracker{tracker: k8sproxy.NewServiceChangeTracker(types.NewServiceInfo, ipFamily, recorder, nil, skipServices)} } func (sh *serviceChangesTracker) OnServiceSynced() { diff --git a/third_party/proxy/service.go b/third_party/proxy/service.go index c61b13f198d..d0a7ac178e7 100644 --- a/third_party/proxy/service.go +++ b/third_party/proxy/service.go @@ -267,18 +267,25 @@ type ServiceChangeTracker struct { makeServiceInfo makeServicePortFunc processServiceMapChange processServiceMapChangeFunc ipFamily v1.IPFamily - - recorder record.EventRecorder + recorder record.EventRecorder + // skipServices indicates the service list for which we should skip proxying + // it will be initialized from antrea-agent.conf + skipServices sets.String } // NewServiceChangeTracker initializes a ServiceChangeTracker -func NewServiceChangeTracker(makeServiceInfo makeServicePortFunc, ipFamily v1.IPFamily, recorder record.EventRecorder, processServiceMapChange processServiceMapChangeFunc) *ServiceChangeTracker { +func NewServiceChangeTracker(makeServiceInfo makeServicePortFunc, + ipFamily v1.IPFamily, + recorder record.EventRecorder, + processServiceMapChange processServiceMapChangeFunc, + skipServices []string) *ServiceChangeTracker { return &ServiceChangeTracker{ items: make(map[types.NamespacedName]*serviceChange), makeServiceInfo: makeServiceInfo, recorder: recorder, ipFamily: ipFamily, processServiceMapChange: processServiceMapChange, + skipServices: sets.NewString(skipServices...), } } @@ -358,7 +365,7 @@ func (sct *ServiceChangeTracker) serviceToServiceMap(service *v1.Service) Servic return nil } - if utilproxy.ShouldSkipService(service) { + if utilproxy.ShouldSkipService(service, sct.skipServices) { return nil } diff --git a/third_party/proxy/util/utils.go b/third_party/proxy/util/utils.go index a7de3754a5f..6c1cc03e813 100644 --- a/third_party/proxy/util/utils.go +++ b/third_party/proxy/util/utils.go @@ -46,6 +46,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/tools/record" utilnet "k8s.io/utils/net" @@ -66,7 +67,7 @@ type Resolver interface { } // ShouldSkipService checks if a given service should skip proxying -func ShouldSkipService(service *v1.Service) bool { +func ShouldSkipService(service *v1.Service, skipServices sets.String) bool { // if ClusterIP is "None" or empty, skip proxying if service.Spec.ClusterIP == v1.ClusterIPNone || service.Spec.ClusterIP == "" { klog.V(3).Infof("Skipping service %s in namespace %s due to clusterIP = %q", service.Name, service.Namespace, service.Spec.ClusterIP) @@ -77,6 +78,14 @@ func ShouldSkipService(service *v1.Service) bool { klog.V(3).Infof("Skipping service %s in namespace %s due to Type=ExternalName", service.Name, service.Namespace) return true } + if skipServices.Len() == 0 { + return false + } + if skipServices.Has(service.Namespace+"/"+service.Name) || skipServices.Has(service.Spec.ClusterIP) { + klog.InfoS("Skipping service because it matches skipServices list", "service", klog.KObj(service)) + return true + } + return false }