From da14a12fe5e196e501c842e7b9e3d22040e822a9 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 6 Apr 2022 08:34:08 -0400 Subject: [PATCH] proxy/iptables: move endpoint chain rule creation to the end Part of reorganizing the syncProxyRules loop to do: 1. figure out what chains are needed, mark them in activeNATChains 2. write servicePort jump rules to KUBE-SERVICES/KUBE-NODEPORTS 3. write servicePort-specific chains (SVC, SVL, EXT, FW, SEP) This fixes the handling of the endpoint chains. Previously they were handled entirely at the top of the loop. Now we record which ones are in use at the top but don't create them and fill them in until the bottom. --- pkg/proxy/iptables/proxier.go | 62 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index aea8d91c94d..b619ec7ea18 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -984,42 +984,18 @@ func (proxier *Proxier) syncProxyRules() { protocol := strings.ToLower(string(svcInfo.Protocol())) svcPortNameString := svcInfo.nameString - allEndpoints := proxier.endpointsMap[svcName] - // Figure out the endpoints for Cluster and Local traffic policy. // allLocallyReachableEndpoints is the set of all endpoints that can be routed to // from this node, given the service's traffic policies. hasEndpoints is true // if the service has any usable endpoints on any node, not just this one. + allEndpoints := proxier.endpointsMap[svcName] clusterEndpoints, localEndpoints, allLocallyReachableEndpoints, hasEndpoints := proxy.CategorizeEndpoints(allEndpoints, svcInfo, proxier.nodeLabels) - // Generate the per-endpoint chains. + // Note the endpoint chains that will be used for _, ep := range allLocallyReachableEndpoints { - epInfo, ok := ep.(*endpointsInfo) - if !ok { - klog.ErrorS(err, "Failed to cast endpointsInfo", "endpointsInfo", ep) - continue + if epInfo, ok := ep.(*endpointsInfo); ok { + activeNATChains[epInfo.ChainName] = true } - - endpointChain := epInfo.ChainName - - // Create the endpoint chain - proxier.natChains.Write(utiliptables.MakeChainLine(endpointChain)) - activeNATChains[endpointChain] = true - - args = append(args[:0], "-A", string(endpointChain)) - args = proxier.appendServiceCommentLocked(args, svcPortNameString) - // Handle traffic that loops back to the originator with SNAT. - proxier.natRules.Write( - args, - "-s", epInfo.IP(), - "-j", string(kubeMarkMasqChain)) - // Update client-affinity lists. - if svcInfo.SessionAffinityType() == v1.ServiceAffinityClientIP { - args = append(args, "-m", "recent", "--name", string(endpointChain), "--set") - } - // DNAT to final destination. - args = append(args, "-m", protocol, "-p", protocol, "-j", "DNAT", "--to-destination", epInfo.Endpoint) - proxier.natRules.Write(args) } // These chains represent the sets of endpoints to use when internal or @@ -1370,6 +1346,36 @@ func (proxier *Proxier) syncProxyRules() { // Write rules jumping from localPolicyChain to localEndpointChains proxier.writeServiceToEndpointRules(svcPortNameString, svcInfo, localPolicyChain, localEndpoints, args) } + + // Generate the per-endpoint chains. + for _, ep := range allLocallyReachableEndpoints { + epInfo, ok := ep.(*endpointsInfo) + if !ok { + klog.ErrorS(err, "Failed to cast endpointsInfo", "endpointsInfo", ep) + continue + } + + endpointChain := epInfo.ChainName + + // Create the endpoint chain + proxier.natChains.Write(utiliptables.MakeChainLine(endpointChain)) + activeNATChains[endpointChain] = true + + args = append(args[:0], "-A", string(endpointChain)) + args = proxier.appendServiceCommentLocked(args, svcPortNameString) + // Handle traffic that loops back to the originator with SNAT. + proxier.natRules.Write( + args, + "-s", epInfo.IP(), + "-j", string(kubeMarkMasqChain)) + // Update client-affinity lists. + if svcInfo.SessionAffinityType() == v1.ServiceAffinityClientIP { + args = append(args, "-m", "recent", "--name", string(endpointChain), "--set") + } + // DNAT to final destination. + args = append(args, "-m", protocol, "-p", protocol, "-j", "DNAT", "--to-destination", epInfo.Endpoint) + proxier.natRules.Write(args) + } } // Delete chains no longer in use. Since "iptables-save" can take several seconds