diff --git a/pkg/proxy/iptables/number_generated_rules_test.go b/pkg/proxy/iptables/number_generated_rules_test.go index 959b3f165cb..dd318d20814 100644 --- a/pkg/proxy/iptables/number_generated_rules_test.go +++ b/pkg/proxy/iptables/number_generated_rules_test.go @@ -162,7 +162,7 @@ func TestNumberIptablesRules(t *testing.T) { services: 1, epPerService: 1, expectedFilterRules: 5, - expectedNatRules: 17, + expectedNatRules: 18, }, { name: "1 Services 2 EndpointPerService - LoadBalancer", @@ -177,7 +177,7 @@ func TestNumberIptablesRules(t *testing.T) { services: 1, epPerService: 2, expectedFilterRules: 5, - expectedNatRules: 20, + expectedNatRules: 21, }, { name: "1 Services 10 EndpointPerService - LoadBalancer", @@ -192,7 +192,7 @@ func TestNumberIptablesRules(t *testing.T) { services: 1, epPerService: 10, expectedFilterRules: 5, - expectedNatRules: 44, + expectedNatRules: 45, }, { name: "10 Services 0 EndpointsPerService - LoadBalancer", @@ -222,7 +222,7 @@ func TestNumberIptablesRules(t *testing.T) { services: 10, epPerService: 1, expectedFilterRules: 14, - expectedNatRules: 125, + expectedNatRules: 135, }, { name: "10 Services 2 EndpointPerService - LoadBalancer", @@ -237,7 +237,7 @@ func TestNumberIptablesRules(t *testing.T) { services: 10, epPerService: 2, expectedFilterRules: 14, - expectedNatRules: 155, + expectedNatRules: 165, }, { name: "10 Services 10 EndpointPerService - LoadBalancer", @@ -252,7 +252,7 @@ func TestNumberIptablesRules(t *testing.T) { services: 10, epPerService: 10, expectedFilterRules: 14, - expectedNatRules: 395, + expectedNatRules: 405, }, } diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index 2f3862f5799..d286c84323b 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -314,7 +314,10 @@ func NewProxier(ctx context.Context, networkInterfacer: proxyutil.RealNetwork{}, conntrackTCPLiberal: conntrackTCPLiberal, logger: logger, - nfAcctCounters: map[string]bool{metrics.IPTablesCTStateInvalidDroppedNFAcctCounter: false}, + nfAcctCounters: map[string]bool{ + metrics.IPTablesCTStateInvalidDroppedNFAcctCounter: false, + metrics.LocalhostNodePortAcceptedNFAcctCounter: false, + }, } burstSyncs := 2 @@ -1183,6 +1186,16 @@ func (proxier *Proxier) syncProxyRules() { // Jump to the external destination chain. For better or for // worse, nodeports are not subect to loadBalancerSourceRanges, // and we can't change that. + if proxier.localhostNodePorts && proxier.ipFamily == v1.IPv4Protocol && proxier.nfAcctCounters[metrics.LocalhostNodePortAcceptedNFAcctCounter] { + natRules.Write( + "-A", string(kubeNodePortsChain), + "-m", "comment", "--comment", svcPortNameString, + "-m", protocol, "-p", protocol, + "-d", "127.0.0.0/8", + "--dport", strconv.Itoa(svcInfo.NodePort()), + "-m", "nfacct", "--nfacct-name", metrics.LocalhostNodePortAcceptedNFAcctCounter, + "-j", string(externalTrafficChain)) + } natRules.Write( "-A", string(kubeNodePortsChain), "-m", "comment", "--comment", svcPortNameString, diff --git a/pkg/proxy/iptables/proxier_test.go b/pkg/proxy/iptables/proxier_test.go index 2f3ac06b857..8323922fb1d 100644 --- a/pkg/proxy/iptables/proxier_test.go +++ b/pkg/proxy/iptables/proxier_test.go @@ -113,6 +113,7 @@ func NewFakeProxier(ipt utiliptables.Interface) *Proxier { networkInterfacer.AddInterfaceAddr(&itf1, addrs1) p := &Proxier{ + ipFamily: ipfamily, svcPortMap: make(proxy.ServicePortMap), serviceChanges: proxy.NewServiceChangeTracker(newServiceInfo, ipfamily, nil, nil), endpointsMap: make(proxy.EndpointsMap), @@ -137,6 +138,7 @@ func NewFakeProxier(ipt utiliptables.Interface) *Proxier { networkInterfacer: networkInterfacer, nfAcctCounters: map[string]bool{ metrics.IPTablesCTStateInvalidDroppedNFAcctCounter: true, + metrics.LocalhostNodePortAcceptedNFAcctCounter: true, }, } p.setInitialized(true) @@ -1746,8 +1748,11 @@ func TestOverallIPTablesRules(t *testing.T) { :KUBE-SVC-NUKIZ6OKUXPJNT4C - [0:0] :KUBE-SVC-X27LE4BHSL4DOUIK - [0:0] :KUBE-SVC-XPGD46QRK7WJZT7O - [0:0] + -A KUBE-NODEPORTS -m comment --comment ns2/svc2:p80 -m tcp -p tcp -d 127.0.0.0/8 --dport 3001 -m nfacct --nfacct-name localhost_nps_accepted_pkts -j KUBE-EXT-GNZBNJ2PO5MGZ6GT -A KUBE-NODEPORTS -m comment --comment ns2/svc2:p80 -m tcp -p tcp --dport 3001 -j KUBE-EXT-GNZBNJ2PO5MGZ6GT + -A KUBE-NODEPORTS -m comment --comment ns3/svc3:p80 -m tcp -p tcp -d 127.0.0.0/8 --dport 3003 -m nfacct --nfacct-name localhost_nps_accepted_pkts -j KUBE-EXT-X27LE4BHSL4DOUIK -A KUBE-NODEPORTS -m comment --comment ns3/svc3:p80 -m tcp -p tcp --dport 3003 -j KUBE-EXT-X27LE4BHSL4DOUIK + -A KUBE-NODEPORTS -m comment --comment ns5/svc5:p80 -m tcp -p tcp -d 127.0.0.0/8 --dport 3002 -m nfacct --nfacct-name localhost_nps_accepted_pkts -j KUBE-EXT-NUKIZ6OKUXPJNT4C -A KUBE-NODEPORTS -m comment --comment ns5/svc5:p80 -m tcp -p tcp --dport 3002 -j KUBE-EXT-NUKIZ6OKUXPJNT4C -A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 -j KUBE-SVC-XPGD46QRK7WJZT7O -A KUBE-SERVICES -m comment --comment "ns2/svc2:p80 cluster IP" -m tcp -p tcp -d 172.30.0.42 --dport 80 -j KUBE-SVC-GNZBNJ2PO5MGZ6GT diff --git a/pkg/proxy/metrics/metrics.go b/pkg/proxy/metrics/metrics.go index 41377b666a4..15682f25eaa 100644 --- a/pkg/proxy/metrics/metrics.go +++ b/pkg/proxy/metrics/metrics.go @@ -266,6 +266,15 @@ var ( }, []string{"traffic_policy"}, ) + + // localhostNodePortsAcceptedPacketsDescription describe the metrics for the number of packets accepted + // by iptables which were destined for nodeports on loopback interface. + localhostNodePortsAcceptedPacketsDescription = metrics.NewDesc( + "kubeproxy_iptables_localhost_nodeports_accepted_packets_total", + "Number of packets accepted on nodeports of loopback interface", + nil, nil, metrics.ALPHA, "") + LocalhostNodePortAcceptedNFAcctCounter = "localhost_nps_accepted_pkts" + localhostNodePortsAcceptedMetricsCollector = newNFAcctMetricCollector(LocalhostNodePortAcceptedNFAcctCounter, localhostNodePortsAcceptedPacketsDescription) ) var registerMetricsOnce sync.Once @@ -291,6 +300,7 @@ func RegisterMetrics(mode kubeproxyconfig.ProxyMode) { switch mode { case kubeproxyconfig.ProxyModeIPTables: legacyregistry.CustomMustRegister(iptablesCTStateInvalidDroppedMetricCollector) + legacyregistry.CustomMustRegister(localhostNodePortsAcceptedMetricsCollector) legacyregistry.MustRegister(SyncFullProxyRulesLatency) legacyregistry.MustRegister(SyncPartialProxyRulesLatency) legacyregistry.MustRegister(IPTablesRestoreFailuresTotal)