From 5464c39333bc348b58c42be07fe4e2d0c426a379 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Thu, 18 May 2017 11:55:43 +0200 Subject: [PATCH] Reuse buffer for getting iptables contents --- pkg/proxy/iptables/proxier.go | 15 +++++++++++---- pkg/proxy/iptables/proxier_test.go | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index c6aedbf1447..faee0d34f83 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -302,6 +302,10 @@ type Proxier struct { recorder record.EventRecorder healthChecker healthcheck.Server healthzServer healthcheck.HealthzUpdater + + // The following buffers are used to reuse memory and avoid allocations + // that are significantly impacting performance. + iptablesLines *bytes.Buffer } type localPort struct { @@ -417,6 +421,7 @@ func NewProxier(ipt utiliptables.Interface, recorder: recorder, healthChecker: healthChecker, healthzServer: healthzServer, + iptablesLines: bytes.NewBuffer(nil), }, nil } @@ -976,19 +981,21 @@ func (proxier *Proxier) syncProxyRules(reason syncReason) { // Get iptables-save output so we can check for existing chains and rules. // This will be a map of chain name to chain with rules as stored in iptables-save/iptables-restore existingFilterChains := make(map[utiliptables.Chain]string) - iptablesSaveRaw, err := proxier.iptables.Save(utiliptables.TableFilter) + proxier.iptablesLines.Reset() + err := proxier.iptables.SaveInto(utiliptables.TableFilter, proxier.iptablesLines) if err != nil { // if we failed to get any rules glog.Errorf("Failed to execute iptables-save, syncing all rules: %v", err) } else { // otherwise parse the output - existingFilterChains = utiliptables.GetChainLines(utiliptables.TableFilter, iptablesSaveRaw) + existingFilterChains = utiliptables.GetChainLines(utiliptables.TableFilter, proxier.iptablesLines.Bytes()) } existingNATChains := make(map[utiliptables.Chain]string) - iptablesSaveRaw, err = proxier.iptables.Save(utiliptables.TableNAT) + proxier.iptablesLines.Reset() + err = proxier.iptables.SaveInto(utiliptables.TableNAT, proxier.iptablesLines) if err != nil { // if we failed to get any rules glog.Errorf("Failed to execute iptables-save, syncing all rules: %v", err) } else { // otherwise parse the output - existingNATChains = utiliptables.GetChainLines(utiliptables.TableNAT, iptablesSaveRaw) + existingNATChains = utiliptables.GetChainLines(utiliptables.TableNAT, proxier.iptablesLines.Bytes()) } filterChains := bytes.NewBuffer(nil) diff --git a/pkg/proxy/iptables/proxier_test.go b/pkg/proxy/iptables/proxier_test.go index b49b1929b87..b037ca68efc 100644 --- a/pkg/proxy/iptables/proxier_test.go +++ b/pkg/proxy/iptables/proxier_test.go @@ -17,6 +17,7 @@ limitations under the License. package iptables import ( + "bytes" "reflect" "strconv" "testing" @@ -394,6 +395,7 @@ func NewFakeProxier(ipt utiliptables.Interface) *Proxier { portsMap: make(map[localPort]closeable), portMapper: &fakePortOpener{[]*localPort{}}, healthChecker: newFakeHealthChecker(), + iptablesLines: bytes.NewBuffer(nil), } }