From 1242e8ca203a53d42c5aaa6aed92a0d021fe0caa Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Wed, 24 May 2017 13:52:07 +0200 Subject: [PATCH 1/5] Minor improvement for memory allocations --- pkg/proxy/iptables/proxier.go | 22 ++++++++++++++++++---- pkg/util/iptables/save_restore.go | 4 +++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index 16776973386..a29667cb625 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -156,6 +156,14 @@ type endpointsInfo struct { isLocal bool } +// Returns just the IP part of the endpoint. +func (e *endpointsInfo) IPPart() string { + if index := strings.Index(e.endpoint, ":"); index != -1 { + return e.endpoint[0:index] + } + return e.endpoint +} + func (e *endpointsInfo) String() string { return fmt.Sprintf("%v", *e) } @@ -751,8 +759,7 @@ func getLocalIPs(endpointsMap proxyEndpointsMap) map[types.NamespacedName]sets.S if localIPs[nsn] == nil { localIPs[nsn] = sets.NewString() } - ip := strings.Split(ep.endpoint, ":")[0] // just the IP part - localIPs[nsn].Insert(ip) + localIPs[nsn].Insert(ep.IPPart()) // just the IP part } } } @@ -873,6 +880,13 @@ type endpointServicePair struct { servicePortName proxy.ServicePortName } +func (esp *endpointServicePair) IPPart() string { + if index := strings.Index(esp.endpoint, ":"); index != -1 { + return esp.endpoint[0:index] + } + return esp.endpoint +} + const noConnectionToDelete = "0 flow entries have been deleted" // After a UDP endpoint has been removed, we must flush any pending conntrack entries to it, or else we @@ -881,7 +895,7 @@ const noConnectionToDelete = "0 flow entries have been deleted" func (proxier *Proxier) deleteEndpointConnections(connectionMap map[endpointServicePair]bool) { for epSvcPair := range connectionMap { if svcInfo, ok := proxier.serviceMap[epSvcPair.servicePortName]; ok && svcInfo.protocol == api.ProtocolUDP { - endpointIP := strings.Split(epSvcPair.endpoint, ":")[0] + endpointIP := epSvcPair.endpoint[0:strings.Index(epSvcPair.endpoint, ":")] glog.V(2).Infof("Deleting connection tracking state for service IP %s, endpoint IP %s", svcInfo.clusterIP.String(), endpointIP) err := utilproxy.ExecConntrackTool(proxier.exec, "-D", "--orig-dst", svcInfo.clusterIP.String(), "--dst-nat", endpointIP, "-p", "udp") if err != nil && !strings.Contains(err.Error(), noConnectionToDelete) { @@ -1371,7 +1385,7 @@ func (proxier *Proxier) syncProxyRules() { } // Handle traffic that loops back to the originator with SNAT. writeLine(proxier.natRules, append(args, - "-s", fmt.Sprintf("%s/32", strings.Split(endpoints[i].endpoint, ":")[0]), + "-s", fmt.Sprintf("%s/32", endpoints[i].IPPart()), "-j", string(KubeMarkMasqChain))...) // Update client-affinity lists. if svcInfo.sessionAffinityType == api.ServiceAffinityClientIP { diff --git a/pkg/util/iptables/save_restore.go b/pkg/util/iptables/save_restore.go index 435a54bebd4..6f4eacacab0 100644 --- a/pkg/util/iptables/save_restore.go +++ b/pkg/util/iptables/save_restore.go @@ -52,7 +52,9 @@ func GetChainLines(table Table, save []byte) map[Chain]string { } else if strings.HasPrefix(line, "#") { continue } else if strings.HasPrefix(line, ":") && len(line) > 1 { - chain := Chain(strings.SplitN(line[1:], " ", 2)[0]) + // We assume that the contains space - chain lines have 3 fields, + // space delimited. If there is no space, this line will panic. + chain := Chain(line[1:strings.Index(line, " ")]) chainsMap[chain] = line } } From 070f393bc80189f9e6735e987195edbcab08d1ef Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Wed, 24 May 2017 12:53:11 +0200 Subject: [PATCH 2/5] Precompute probabilities in iptables kube-proxy. --- pkg/proxy/iptables/proxier.go | 92 +++++++++++++++++++----------- pkg/proxy/iptables/proxier_test.go | 1 + 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index a29667cb625..769f959ee17 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -354,6 +354,11 @@ type Proxier struct { healthChecker healthcheck.Server healthzServer healthcheck.HealthzUpdater + // Since converting probabilities (floats) to strings is expensive + // and we are using only probabilities in the format of 1/n, we are + // precomputing some number of those and cache for future reuse. + precomputedProbabilities []string + // The following buffers are used to reuse memory and avoid allocations // that are significantly impacting performance. iptablesData *bytes.Buffer @@ -449,27 +454,28 @@ func NewProxier(ipt utiliptables.Interface, healthChecker := healthcheck.NewServer(hostname, recorder, nil, nil) // use default implementations of deps proxier := &Proxier{ - portsMap: make(map[localPort]closeable), - serviceMap: make(proxyServiceMap), - serviceChanges: newServiceChangeMap(), - endpointsMap: make(proxyEndpointsMap), - endpointsChanges: newEndpointsChangeMap(hostname), - iptables: ipt, - masqueradeAll: masqueradeAll, - masqueradeMark: masqueradeMark, - exec: exec, - clusterCIDR: clusterCIDR, - hostname: hostname, - nodeIP: nodeIP, - portMapper: &listenPortOpener{}, - recorder: recorder, - healthChecker: healthChecker, - healthzServer: healthzServer, - iptablesData: bytes.NewBuffer(nil), - filterChains: bytes.NewBuffer(nil), - filterRules: bytes.NewBuffer(nil), - natChains: bytes.NewBuffer(nil), - natRules: bytes.NewBuffer(nil), + portsMap: make(map[localPort]closeable), + serviceMap: make(proxyServiceMap), + serviceChanges: newServiceChangeMap(), + endpointsMap: make(proxyEndpointsMap), + endpointsChanges: newEndpointsChangeMap(hostname), + iptables: ipt, + masqueradeAll: masqueradeAll, + masqueradeMark: masqueradeMark, + exec: exec, + clusterCIDR: clusterCIDR, + hostname: hostname, + nodeIP: nodeIP, + portMapper: &listenPortOpener{}, + recorder: recorder, + healthChecker: healthChecker, + healthzServer: healthzServer, + precomputedProbabilities: make([]string, 0, 1001), + iptablesData: bytes.NewBuffer(nil), + filterChains: bytes.NewBuffer(nil), + filterRules: bytes.NewBuffer(nil), + natChains: bytes.NewBuffer(nil), + natRules: bytes.NewBuffer(nil), } burstSyncs := 2 glog.V(3).Infof("minSyncPeriod: %v, syncPeriod: %v, burstSyncs: %d", minSyncPeriod, syncPeriod, burstSyncs) @@ -565,6 +571,28 @@ func CleanupLeftovers(ipt utiliptables.Interface) (encounteredError bool) { return encounteredError } +func computeProbability(n int) string { + return fmt.Sprintf("%0.5f", 1.0/float64(n)) +} + +// This assumes proxier.mu is held +func (proxier *Proxier) precomputeProbabilities(numberOfPrecomputed int) { + if len(proxier.precomputedProbabilities) == 0 { + proxier.precomputedProbabilities = append(proxier.precomputedProbabilities, "") + } + for i := len(proxier.precomputedProbabilities); i <= numberOfPrecomputed; i++ { + proxier.precomputedProbabilities = append(proxier.precomputedProbabilities, computeProbability(i)) + } +} + +// This assumes proxier.mu is held +func (proxier *Proxier) probability(n int) string { + if n >= len(proxier.precomputedProbabilities) { + proxier.precomputeProbabilities(n) + } + return proxier.precomputedProbabilities[n] +} + // Sync is called to synchronize the proxier state to iptables as soon as possible. func (proxier *Proxier) Sync() { proxier.syncRunner.Run() @@ -1104,7 +1132,7 @@ func (proxier *Proxier) syncProxyRules() { "-m", "comment", "--comment", fmt.Sprintf(`"%s cluster IP"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", svcInfo.clusterIP.String()), - "--dport", fmt.Sprintf("%d", svcInfo.port), + "--dport", strconv.Itoa(svcInfo.port), } if proxier.masqueradeAll { writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) @@ -1154,7 +1182,7 @@ func (proxier *Proxier) syncProxyRules() { "-m", "comment", "--comment", fmt.Sprintf(`"%s external IP"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", externalIP), - "--dport", fmt.Sprintf("%d", svcInfo.port), + "--dport", strconv.Itoa(svcInfo.port), } // We have to SNAT packets to external IPs. writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) @@ -1180,7 +1208,7 @@ func (proxier *Proxier) syncProxyRules() { "-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", externalIP), - "--dport", fmt.Sprintf("%d", svcInfo.port), + "--dport", strconv.Itoa(svcInfo.port), "-j", "REJECT", ) } @@ -1206,7 +1234,7 @@ func (proxier *Proxier) syncProxyRules() { "-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", ingress.IP), - "--dport", fmt.Sprintf("%d", svcInfo.port), + "--dport", strconv.Itoa(svcInfo.port), } // jump to service firewall chain writeLine(proxier.natRules, append(args, "-j", string(fwChain))...) @@ -1284,7 +1312,7 @@ func (proxier *Proxier) syncProxyRules() { "-A", string(kubeNodePortsChain), "-m", "comment", "--comment", svcNameString, "-m", protocol, "-p", protocol, - "--dport", fmt.Sprintf("%d", svcInfo.nodePort), + "--dport", strconv.Itoa(svcInfo.nodePort), } if !svcInfo.onlyNodeLocalEndpoints { // Nodeports need SNAT, unless they're local. @@ -1307,7 +1335,7 @@ func (proxier *Proxier) syncProxyRules() { "-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString), "-m", "addrtype", "--dst-type", "LOCAL", "-m", protocol, "-p", protocol, - "--dport", fmt.Sprintf("%d", svcInfo.nodePort), + "--dport", strconv.Itoa(svcInfo.nodePort), "-j", "REJECT", ) } @@ -1320,7 +1348,7 @@ func (proxier *Proxier) syncProxyRules() { "-m", "comment", "--comment", fmt.Sprintf(`"%s has no endpoints"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", svcInfo.clusterIP.String()), - "--dport", fmt.Sprintf("%d", svcInfo.port), + "--dport", strconv.Itoa(svcInfo.port), "-j", "REJECT", ) continue @@ -1354,7 +1382,7 @@ func (proxier *Proxier) syncProxyRules() { "-A", string(svcChain), "-m", "comment", "--comment", svcNameString, "-m", "recent", "--name", string(endpointChain), - "--rcheck", "--seconds", fmt.Sprintf("%d", svcInfo.stickyMaxAgeMinutes*60), "--reap", + "--rcheck", "--seconds", strconv.Itoa(svcInfo.stickyMaxAgeMinutes*60), "--reap", "-j", string(endpointChain)) } } @@ -1372,7 +1400,7 @@ func (proxier *Proxier) syncProxyRules() { args = append(args, "-m", "statistic", "--mode", "random", - "--probability", fmt.Sprintf("%0.5f", 1.0/float64(n-i))) + "--probability", proxier.probability(n-i)) } // The final (or only if n == 1) rule is a guaranteed match. args = append(args, "-j", string(endpointChain)) @@ -1419,7 +1447,7 @@ func (proxier *Proxier) syncProxyRules() { args = []string{ "-A", string(svcXlbChain), "-m", "comment", "--comment", - fmt.Sprintf(`"Redirect pods trying to reach external loadbalancer VIP to clusterIP"`), + "\"Redirect pods trying to reach external loadbalancer VIP to clusterIP\"", "-s", proxier.clusterCIDR, "-j", string(svcChain), } @@ -1451,7 +1479,7 @@ func (proxier *Proxier) syncProxyRules() { args = append(args, "-m", "statistic", "--mode", "random", - "--probability", fmt.Sprintf("%0.5f", 1.0/float64(numLocalEndpoints-i))) + "--probability", proxier.probability(numLocalEndpoints-i)) } // The final (or only if n == 1) rule is a guaranteed match. args = append(args, "-j", string(endpointChain)) diff --git a/pkg/proxy/iptables/proxier_test.go b/pkg/proxy/iptables/proxier_test.go index 33f2386c467..99710f0612a 100644 --- a/pkg/proxy/iptables/proxier_test.go +++ b/pkg/proxy/iptables/proxier_test.go @@ -397,6 +397,7 @@ func NewFakeProxier(ipt utiliptables.Interface) *Proxier { portsMap: make(map[localPort]closeable), portMapper: &fakePortOpener{[]*localPort{}}, healthChecker: newFakeHealthChecker(), + precomputedProbabilities: make([]string, 0, 1001), iptablesData: bytes.NewBuffer(nil), filterChains: bytes.NewBuffer(nil), filterRules: bytes.NewBuffer(nil), From 88e3e8f47072f9eefd9eebf1ce727274dcb835c2 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Tue, 23 May 2017 14:58:40 +0200 Subject: [PATCH 3/5] Reuse args slice for generating iptable rules. --- pkg/proxy/iptables/proxier.go | 61 ++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index 769f959ee17..f3e57e2af11 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -1095,6 +1095,20 @@ func (proxier *Proxier) syncProxyRules() { // Accumulate the set of local ports that we will be holding open once this update is complete replacementPortsMap := map[localPort]closeable{} + // We are creating those slices ones here to avoid memory reallocations + // in every loop. Note that reuse the memory, instead of doing: + // slice = + // you should always do one of the below: + // slice = slice[:0] // and then append to it + // slice = append(slice[:0], ...) + endpoints := make([]*endpointsInfo, 0) + endpointChains := make([]utiliptables.Chain, 0) + // To avoid growing this slice, we arbitrarily set its size to 64, + // there is never more than that many arguments for a single line. + // Note that even if we go over 64, it will still be correct - it + // is just for efficiency, not correctness. + args := make([]string, 64) + // Build rules for each service. for svcName, svcInfo := range proxier.serviceMap { protocol := strings.ToLower(string(svcInfo.protocol)) @@ -1127,13 +1141,13 @@ func (proxier *Proxier) syncProxyRules() { } // Capture the clusterIP. - args := []string{ + args = append(args[:0], "-A", string(kubeServicesChain), "-m", "comment", "--comment", fmt.Sprintf(`"%s cluster IP"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", svcInfo.clusterIP.String()), "--dport", strconv.Itoa(svcInfo.port), - } + ) if proxier.masqueradeAll { writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) } @@ -1177,13 +1191,13 @@ func (proxier *Proxier) syncProxyRules() { replacementPortsMap[lp] = socket } } // We're holding the port, so it's OK to install iptables rules. - args := []string{ + args = append(args[:0], "-A", string(kubeServicesChain), "-m", "comment", "--comment", fmt.Sprintf(`"%s external IP"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", externalIP), "--dport", strconv.Itoa(svcInfo.port), - } + ) // We have to SNAT packets to external IPs. writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) @@ -1229,20 +1243,20 @@ func (proxier *Proxier) syncProxyRules() { // This currently works for loadbalancers that preserves source ips. // For loadbalancers which direct traffic to service NodePort, the firewall rules will not apply. - args := []string{ + args = append(args[:0], "-A", string(kubeServicesChain), "-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString), "-m", protocol, "-p", protocol, "-d", fmt.Sprintf("%s/32", ingress.IP), "--dport", strconv.Itoa(svcInfo.port), - } + ) // jump to service firewall chain writeLine(proxier.natRules, append(args, "-j", string(fwChain))...) - args = []string{ + args = append(args[:0], "-A", string(fwChain), "-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcNameString), - } + ) // Each source match rule in the FW chain may jump to either the SVC or the XLB chain chosenChain := svcXlbChain @@ -1308,12 +1322,12 @@ func (proxier *Proxier) syncProxyRules() { replacementPortsMap[lp] = socket } // We're holding the port, so it's OK to install iptables rules. - args := []string{ + args = append(args[:0], "-A", string(kubeNodePortsChain), "-m", "comment", "--comment", svcNameString, "-m", protocol, "-p", protocol, "--dport", strconv.Itoa(svcInfo.nodePort), - } + ) if !svcInfo.onlyNodeLocalEndpoints { // Nodeports need SNAT, unless they're local. writeLine(proxier.natRules, append(args, "-j", string(KubeMarkMasqChain))...) @@ -1359,10 +1373,11 @@ func (proxier *Proxier) syncProxyRules() { // Generate the per-endpoint chains. We do this in multiple passes so we // can group rules together. // These two slices parallel each other - keep in sync - endpoints := make([]*endpointsInfo, 0) - endpointChains := make([]utiliptables.Chain, 0) + endpoints = endpoints[:0] + endpointChains = endpointChains[:0] for _, ep := range proxier.endpointsMap[svcName] { endpoints = append(endpoints, ep) + // TODO: This should be precomputed. endpointChain := servicePortEndpointChainName(svcNameString, protocol, ep.endpoint) endpointChains = append(endpointChains, endpointChain) @@ -1391,10 +1406,10 @@ func (proxier *Proxier) syncProxyRules() { n := len(endpointChains) for i, endpointChain := range endpointChains { // Balancing rules in the per-service chain. - args := []string{ + args = append(args[:0], []string{ "-A", string(svcChain), "-m", "comment", "--comment", svcNameString, - } + }...) if i < (n - 1) { // Each rule is a probabilistic match. args = append(args, @@ -1407,10 +1422,10 @@ func (proxier *Proxier) syncProxyRules() { writeLine(proxier.natRules, args...) // Rules in the per-endpoint chain. - args = []string{ + args = append(args[:0], "-A", string(endpointChain), "-m", "comment", "--comment", svcNameString, - } + ) // Handle traffic that loops back to the originator with SNAT. writeLine(proxier.natRules, append(args, "-s", fmt.Sprintf("%s/32", endpoints[i].IPPart()), @@ -1444,36 +1459,36 @@ func (proxier *Proxier) syncProxyRules() { // Service's ClusterIP instead. This happens whether or not we have local // endpoints; only if clusterCIDR is specified if len(proxier.clusterCIDR) > 0 { - args = []string{ + args = append(args[:0], "-A", string(svcXlbChain), "-m", "comment", "--comment", - "\"Redirect pods trying to reach external loadbalancer VIP to clusterIP\"", + `"Redirect pods trying to reach external loadbalancer VIP to clusterIP"`, "-s", proxier.clusterCIDR, "-j", string(svcChain), - } + ) writeLine(proxier.natRules, args...) } numLocalEndpoints := len(localEndpointChains) if numLocalEndpoints == 0 { // Blackhole all traffic since there are no local endpoints - args := []string{ + args = append(args[:0], "-A", string(svcXlbChain), "-m", "comment", "--comment", fmt.Sprintf(`"%s has no local endpoints"`, svcNameString), "-j", string(KubeMarkDropChain), - } + ) writeLine(proxier.natRules, args...) } else { // Setup probability filter rules only over local endpoints for i, endpointChain := range localEndpointChains { // Balancing rules in the per-service chain. - args := []string{ + args = append(args[:0], "-A", string(svcXlbChain), "-m", "comment", "--comment", fmt.Sprintf(`"Balancing rule %d for %s"`, i, svcNameString), - } + ) if i < (numLocalEndpoints - 1) { // Each rule is a probabilistic match. args = append(args, From c4d51f12a267ebc616520f126ccc6a25b3baeb1b Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Wed, 24 May 2017 14:24:03 +0200 Subject: [PATCH 4/5] Store port endpoint chain names to avoid recomputing it multiple times --- pkg/proxy/iptables/proxier.go | 18 ++- pkg/proxy/iptables/proxier_test.go | 192 ++++++++++++++--------------- 2 files changed, 112 insertions(+), 98 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index f3e57e2af11..98a60b28177 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -154,6 +154,11 @@ type serviceInfo struct { type endpointsInfo struct { endpoint string // TODO: should be an endpointString type isLocal bool + // The following fields we lazily compute and store here for performance + // reasons. If the protocol is the same as you expect it to be, then the + // chainName can be reused, otherwise it should be recomputed. + protocol string + chainName utiliptables.Chain } // Returns just the IP part of the endpoint. @@ -164,6 +169,15 @@ func (e *endpointsInfo) IPPart() string { return e.endpoint } +// Returns the endpoint chain name for a given endpointsInfo. +func (e *endpointsInfo) endpointChain(svcNameString, protocol string) utiliptables.Chain { + if e.protocol != protocol { + e.protocol = protocol + e.chainName = servicePortEndpointChainName(svcNameString, protocol, e.endpoint) + } + return e.chainName +} + func (e *endpointsInfo) String() string { return fmt.Sprintf("%v", *e) } @@ -1375,10 +1389,10 @@ func (proxier *Proxier) syncProxyRules() { // These two slices parallel each other - keep in sync endpoints = endpoints[:0] endpointChains = endpointChains[:0] + var endpointChain utiliptables.Chain for _, ep := range proxier.endpointsMap[svcName] { endpoints = append(endpoints, ep) - // TODO: This should be precomputed. - endpointChain := servicePortEndpointChainName(svcNameString, protocol, ep.endpoint) + endpointChain = ep.endpointChain(svcNameString, protocol) endpointChains = append(endpointChains, endpointChain) // Create the endpoint chain, retaining counters if possible. diff --git a/pkg/proxy/iptables/proxier_test.go b/pkg/proxy/iptables/proxier_test.go index 99710f0612a..5d7fa494386 100644 --- a/pkg/proxy/iptables/proxier_test.go +++ b/pkg/proxy/iptables/proxier_test.go @@ -1293,7 +1293,7 @@ func Test_getLocalIPs(t *testing.T) { // Case[1]: unnamed port endpointsMap: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expected: map[types.NamespacedName]sets.String{}, @@ -1301,7 +1301,7 @@ func Test_getLocalIPs(t *testing.T) { // Case[2]: unnamed port local endpointsMap: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", true}, + {endpoint: "1.1.1.1:11", isLocal: true}, }, }, expected: map[types.NamespacedName]sets.String{ @@ -1311,12 +1311,12 @@ func Test_getLocalIPs(t *testing.T) { // Case[3]: named local and non-local ports for the same IP. endpointsMap: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, - {"1.1.1.2:11", true}, + {endpoint: "1.1.1.1:11", isLocal: false}, + {endpoint: "1.1.1.2:11", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.1:12", false}, - {"1.1.1.2:12", true}, + {endpoint: "1.1.1.1:12", isLocal: false}, + {endpoint: "1.1.1.2:12", isLocal: true}, }, }, expected: map[types.NamespacedName]sets.String{ @@ -1326,21 +1326,21 @@ func Test_getLocalIPs(t *testing.T) { // Case[4]: named local and non-local ports for different IPs. endpointsMap: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, makeServicePortName("ns2", "ep2", "p22"): { - {"2.2.2.2:22", true}, - {"2.2.2.22:22", true}, + {endpoint: "2.2.2.2:22", isLocal: true}, + {endpoint: "2.2.2.22:22", isLocal: true}, }, makeServicePortName("ns2", "ep2", "p23"): { - {"2.2.2.3:23", true}, + {endpoint: "2.2.2.3:23", isLocal: true}, }, makeServicePortName("ns4", "ep4", "p44"): { - {"4.4.4.4:44", true}, - {"4.4.4.5:44", false}, + {endpoint: "4.4.4.4:44", isLocal: true}, + {endpoint: "4.4.4.5:44", isLocal: false}, }, makeServicePortName("ns4", "ep4", "p45"): { - {"4.4.4.6:45", true}, + {endpoint: "4.4.4.6:45", isLocal: true}, }, }, expected: map[types.NamespacedName]sets.String{ @@ -1385,7 +1385,7 @@ func Test_endpointsToEndpointsMap(t *testing.T) { }), expected: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, }, { @@ -1405,7 +1405,7 @@ func Test_endpointsToEndpointsMap(t *testing.T) { }), expected: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "port"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, }, { @@ -1424,7 +1424,7 @@ func Test_endpointsToEndpointsMap(t *testing.T) { }), expected: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, }, { @@ -1453,12 +1453,12 @@ func Test_endpointsToEndpointsMap(t *testing.T) { }), expected: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p1"): { - {"1.1.1.1:11", false}, - {"2.2.2.2:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, + {endpoint: "2.2.2.2:11", isLocal: false}, }, makeServicePortName("ns1", "ep1", "p2"): { - {"1.1.1.1:22", false}, - {"2.2.2.2:22", false}, + {endpoint: "1.1.1.1:22", isLocal: false}, + {endpoint: "2.2.2.2:22", isLocal: false}, }, }, }, { @@ -1478,7 +1478,7 @@ func Test_endpointsToEndpointsMap(t *testing.T) { }), expected: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p1"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, }, { @@ -1498,7 +1498,7 @@ func Test_endpointsToEndpointsMap(t *testing.T) { }), expected: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p2"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, }, { @@ -1518,7 +1518,7 @@ func Test_endpointsToEndpointsMap(t *testing.T) { }), expected: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p1"): { - {"1.1.1.1:22", false}, + {endpoint: "1.1.1.1:22", isLocal: false}, }, }, }} @@ -1932,12 +1932,12 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedStale: []endpointServicePair{}, @@ -1952,12 +1952,12 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", true}, + {endpoint: "1.1.1.1:11", isLocal: true}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", true}, + {endpoint: "1.1.1.1:11", isLocal: true}, }, }, expectedStale: []endpointServicePair{}, @@ -1974,18 +1974,18 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.2:12", false}, + {endpoint: "1.1.1.2:12", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.2:12", false}, + {endpoint: "1.1.1.2:12", isLocal: false}, }, }, expectedStale: []endpointServicePair{}, @@ -2000,24 +2000,24 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", true}, + {endpoint: "1.1.1.1:11", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.1:12", true}, + {endpoint: "1.1.1.1:12", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p13"): { - {"1.1.1.3:13", false}, + {endpoint: "1.1.1.3:13", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", true}, + {endpoint: "1.1.1.1:11", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.1:12", true}, + {endpoint: "1.1.1.1:12", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p13"): { - {"1.1.1.3:13", false}, + {endpoint: "1.1.1.3:13", isLocal: false}, }, }, expectedStale: []endpointServicePair{}, @@ -2036,54 +2036,54 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, - {"1.1.1.2:11", true}, + {endpoint: "1.1.1.1:11", isLocal: false}, + {endpoint: "1.1.1.2:11", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.1:12", false}, - {"1.1.1.2:12", true}, + {endpoint: "1.1.1.1:12", isLocal: false}, + {endpoint: "1.1.1.2:12", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p13"): { - {"1.1.1.3:13", false}, - {"1.1.1.4:13", true}, + {endpoint: "1.1.1.3:13", isLocal: false}, + {endpoint: "1.1.1.4:13", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p14"): { - {"1.1.1.3:14", false}, - {"1.1.1.4:14", true}, + {endpoint: "1.1.1.3:14", isLocal: false}, + {endpoint: "1.1.1.4:14", isLocal: true}, }, makeServicePortName("ns2", "ep2", "p21"): { - {"2.2.2.1:21", false}, - {"2.2.2.2:21", true}, + {endpoint: "2.2.2.1:21", isLocal: false}, + {endpoint: "2.2.2.2:21", isLocal: true}, }, makeServicePortName("ns2", "ep2", "p22"): { - {"2.2.2.1:22", false}, - {"2.2.2.2:22", true}, + {endpoint: "2.2.2.1:22", isLocal: false}, + {endpoint: "2.2.2.2:22", isLocal: true}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, - {"1.1.1.2:11", true}, + {endpoint: "1.1.1.1:11", isLocal: false}, + {endpoint: "1.1.1.2:11", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.1:12", false}, - {"1.1.1.2:12", true}, + {endpoint: "1.1.1.1:12", isLocal: false}, + {endpoint: "1.1.1.2:12", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p13"): { - {"1.1.1.3:13", false}, - {"1.1.1.4:13", true}, + {endpoint: "1.1.1.3:13", isLocal: false}, + {endpoint: "1.1.1.4:13", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p14"): { - {"1.1.1.3:14", false}, - {"1.1.1.4:14", true}, + {endpoint: "1.1.1.3:14", isLocal: false}, + {endpoint: "1.1.1.4:14", isLocal: true}, }, makeServicePortName("ns2", "ep2", "p21"): { - {"2.2.2.1:21", false}, - {"2.2.2.2:21", true}, + {endpoint: "2.2.2.1:21", isLocal: false}, + {endpoint: "2.2.2.2:21", isLocal: true}, }, makeServicePortName("ns2", "ep2", "p22"): { - {"2.2.2.1:22", false}, - {"2.2.2.2:22", true}, + {endpoint: "2.2.2.1:22", isLocal: false}, + {endpoint: "2.2.2.2:22", isLocal: true}, }, }, expectedStale: []endpointServicePair{}, @@ -2102,7 +2102,7 @@ func Test_updateEndpointsMap(t *testing.T) { oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{}, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", true}, + {endpoint: "1.1.1.1:11", isLocal: true}, }, }, expectedStale: []endpointServicePair{}, @@ -2119,7 +2119,7 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", ""): { - {"1.1.1.1:11", true}, + {endpoint: "1.1.1.1:11", isLocal: true}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{}, @@ -2138,17 +2138,17 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, - {"1.1.1.2:11", true}, + {endpoint: "1.1.1.1:11", isLocal: false}, + {endpoint: "1.1.1.2:11", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.1:12", false}, - {"1.1.1.2:12", true}, + {endpoint: "1.1.1.1:12", isLocal: false}, + {endpoint: "1.1.1.2:12", isLocal: true}, }, }, expectedStale: []endpointServicePair{}, @@ -2165,17 +2165,17 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, - {"1.1.1.2:11", true}, + {endpoint: "1.1.1.1:11", isLocal: false}, + {endpoint: "1.1.1.2:11", isLocal: true}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.1:12", false}, - {"1.1.1.2:12", true}, + {endpoint: "1.1.1.1:12", isLocal: false}, + {endpoint: "1.1.1.2:12", isLocal: true}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedStale: []endpointServicePair{{ @@ -2199,15 +2199,15 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.2:12", true}, + {endpoint: "1.1.1.2:12", isLocal: true}, }, }, expectedStale: []endpointServicePair{}, @@ -2224,15 +2224,15 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.2:12", false}, + {endpoint: "1.1.1.2:12", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedStale: []endpointServicePair{{ @@ -2250,12 +2250,12 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11-2"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedStale: []endpointServicePair{{ @@ -2273,12 +2273,12 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:22", false}, + {endpoint: "1.1.1.1:22", isLocal: false}, }, }, expectedStale: []endpointServicePair{{ @@ -2302,39 +2302,39 @@ func Test_updateEndpointsMap(t *testing.T) { }, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, }, makeServicePortName("ns2", "ep2", "p22"): { - {"2.2.2.2:22", true}, - {"2.2.2.22:22", true}, + {endpoint: "2.2.2.2:22", isLocal: true}, + {endpoint: "2.2.2.22:22", isLocal: true}, }, makeServicePortName("ns2", "ep2", "p23"): { - {"2.2.2.3:23", true}, + {endpoint: "2.2.2.3:23", isLocal: true}, }, makeServicePortName("ns4", "ep4", "p44"): { - {"4.4.4.4:44", true}, - {"4.4.4.5:44", true}, + {endpoint: "4.4.4.4:44", isLocal: true}, + {endpoint: "4.4.4.5:44", isLocal: true}, }, makeServicePortName("ns4", "ep4", "p45"): { - {"4.4.4.6:45", true}, + {endpoint: "4.4.4.6:45", isLocal: true}, }, }, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ makeServicePortName("ns1", "ep1", "p11"): { - {"1.1.1.1:11", false}, - {"1.1.1.11:11", false}, + {endpoint: "1.1.1.1:11", isLocal: false}, + {endpoint: "1.1.1.11:11", isLocal: false}, }, makeServicePortName("ns1", "ep1", "p12"): { - {"1.1.1.2:12", false}, + {endpoint: "1.1.1.2:12", isLocal: false}, }, makeServicePortName("ns1", "ep1", "p122"): { - {"1.1.1.2:122", false}, + {endpoint: "1.1.1.2:122", isLocal: false}, }, makeServicePortName("ns3", "ep3", "p33"): { - {"3.3.3.3:33", false}, + {endpoint: "3.3.3.3:33", isLocal: false}, }, makeServicePortName("ns4", "ep4", "p44"): { - {"4.4.4.4:44", true}, + {endpoint: "4.4.4.4:44", isLocal: true}, }, }, expectedStale: []endpointServicePair{{ From 03c255d7c5bd20ab76bfdc1eab62070d271cb6d3 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Wed, 24 May 2017 16:16:39 +0200 Subject: [PATCH 5/5] Store chain names to avoid recomputing them multiple times --- pkg/proxy/iptables/proxier.go | 23 +++++++++++++++------ pkg/proxy/iptables/proxier_test.go | 32 +++++++++++++++--------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index 98a60b28177..6f2f71e5fe6 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -148,6 +148,11 @@ type serviceInfo struct { loadBalancerSourceRanges []string onlyNodeLocalEndpoints bool healthCheckNodePort int + // The following fields are computed and stored for performance reasons. + serviceNameString string + servicePortChainName utiliptables.Chain + serviceFirewallChainName utiliptables.Chain + serviceLBChainName utiliptables.Chain } // internal struct for endpoints information @@ -214,6 +219,13 @@ func newServiceInfo(svcPortName proxy.ServicePortName, port *api.ServicePort, se } } + // Store the following for performance reasons. + protocol := strings.ToLower(string(info.protocol)) + info.serviceNameString = svcPortName.String() + info.servicePortChainName = servicePortChainName(info.serviceNameString, protocol) + info.serviceFirewallChainName = serviceFirewallChainName(info.serviceNameString, protocol) + info.serviceLBChainName = serviceLBChainName(info.serviceNameString, protocol) + return info } @@ -1124,14 +1136,13 @@ func (proxier *Proxier) syncProxyRules() { args := make([]string, 64) // Build rules for each service. + var svcNameString string for svcName, svcInfo := range proxier.serviceMap { protocol := strings.ToLower(string(svcInfo.protocol)) - // Precompute svcNameString; with many services the many calls - // to ServicePortName.String() show up in CPU profiles. - svcNameString := svcName.String() + svcNameString = svcInfo.serviceNameString // Create the per-service chain, retaining counters if possible. - svcChain := servicePortChainName(svcNameString, protocol) + svcChain := svcInfo.servicePortChainName if chain, ok := existingNATChains[svcChain]; ok { writeLine(proxier.natChains, chain) } else { @@ -1139,7 +1150,7 @@ func (proxier *Proxier) syncProxyRules() { } activeNATChains[svcChain] = true - svcXlbChain := serviceLBChainName(svcNameString, protocol) + svcXlbChain := svcInfo.serviceLBChainName if svcInfo.onlyNodeLocalEndpoints { // Only for services request OnlyLocal traffic // create the per-service LB chain, retaining counters if possible. @@ -1243,10 +1254,10 @@ func (proxier *Proxier) syncProxyRules() { } // Capture load-balancer ingress. + fwChain := svcInfo.serviceFirewallChainName for _, ingress := range svcInfo.loadBalancerStatus.Ingress { if ingress.IP != "" { // create service firewall chain - fwChain := serviceFirewallChainName(svcNameString, protocol) if chain, ok := existingNATChains[fwChain]; ok { writeLine(proxier.natChains, chain) } else { diff --git a/pkg/proxy/iptables/proxier_test.go b/pkg/proxy/iptables/proxier_test.go index 5d7fa494386..989c244776e 100644 --- a/pkg/proxy/iptables/proxier_test.go +++ b/pkg/proxy/iptables/proxier_test.go @@ -386,23 +386,23 @@ func NewFakeProxier(ipt utiliptables.Interface) *Proxier { // TODO: Call NewProxier after refactoring out the goroutine // invocation into a Run() method. p := &Proxier{ - exec: &exec.FakeExec{}, - serviceMap: make(proxyServiceMap), - serviceChanges: newServiceChangeMap(), - endpointsMap: make(proxyEndpointsMap), - endpointsChanges: newEndpointsChangeMap(testHostname), - iptables: ipt, - clusterCIDR: "10.0.0.0/24", - hostname: testHostname, - portsMap: make(map[localPort]closeable), - portMapper: &fakePortOpener{[]*localPort{}}, - healthChecker: newFakeHealthChecker(), + exec: &exec.FakeExec{}, + serviceMap: make(proxyServiceMap), + serviceChanges: newServiceChangeMap(), + endpointsMap: make(proxyEndpointsMap), + endpointsChanges: newEndpointsChangeMap(testHostname), + iptables: ipt, + clusterCIDR: "10.0.0.0/24", + hostname: testHostname, + portsMap: make(map[localPort]closeable), + portMapper: &fakePortOpener{[]*localPort{}}, + healthChecker: newFakeHealthChecker(), precomputedProbabilities: make([]string, 0, 1001), - iptablesData: bytes.NewBuffer(nil), - filterChains: bytes.NewBuffer(nil), - filterRules: bytes.NewBuffer(nil), - natChains: bytes.NewBuffer(nil), - natRules: bytes.NewBuffer(nil), + iptablesData: bytes.NewBuffer(nil), + filterChains: bytes.NewBuffer(nil), + filterRules: bytes.NewBuffer(nil), + natChains: bytes.NewBuffer(nil), + natRules: bytes.NewBuffer(nil), } p.syncRunner = async.NewBoundedFrequencyRunner("test-sync-runner", p.syncProxyRules, 0, time.Minute, 1) return p