iptables proxier: get local addresses only once per sync loop

This avoids fetching all local network interfaces everytime we sync an
external IP. For clusters with many external IPs this gets really
expensive. This change caches all local addresses once per sync.

Signed-off-by: Andrew Sy Kim <kiman@vmware.com>
This commit is contained in:
Andrew Sy Kim 2019-11-27 13:50:49 -05:00 committed by andrewsykim
parent 9e5a06c3ed
commit 313c3b81e3

View File

@ -796,6 +796,13 @@ func (proxier *Proxier) syncProxyRules() {
klog.V(4).Infof("syncProxyRules took %v", time.Since(start))
}()
localAddrs, err := utilproxy.GetLocalAddrs()
if err != nil {
klog.Errorf("Failed to get local addresses during proxy sync: %v, assuming external IPs are not local", err)
} else if len(localAddrs) == 0 {
klog.Warning("No local addresses found, assuming all external IPs are not local")
}
// We assume that if this was called, we really want to sync them,
// even if nothing changed in the meantime. In other words, callers are
// responsible for detecting no-op changes and not calling this function.
@ -848,7 +855,7 @@ func (proxier *Proxier) syncProxyRules() {
// This will be a map of chain name to chain with rules as stored in iptables-save/iptables-restore
existingFilterChains := make(map[utiliptables.Chain][]byte)
proxier.existingFilterChainsData.Reset()
err := proxier.iptables.SaveInto(utiliptables.TableFilter, proxier.existingFilterChainsData)
err = proxier.iptables.SaveInto(utiliptables.TableFilter, proxier.existingFilterChainsData)
if err != nil { // if we failed to get any rules
klog.Errorf("Failed to execute iptables-save, syncing all rules: %v", err)
} else { // otherwise parse the output
@ -1030,9 +1037,7 @@ func (proxier *Proxier) syncProxyRules() {
// If the "external" IP happens to be an IP that is local to this
// machine, hold the local port open so no other process can open it
// (because the socket might open but it would never work).
if local, err := utilproxy.IsLocalIP(externalIP); err != nil {
klog.Errorf("can't determine if IP is local, assuming not: %v", err)
} else if local && (svcInfo.Protocol() != v1.ProtocolSCTP) {
if len(localAddrs) > 0 && (svcInfo.Protocol() != v1.ProtocolSCTP) && utilproxy.ContainsIP(localAddrs, net.ParseIP(externalIP)) {
lp := utilproxy.LocalPort{
Description: "externalIP for " + svcNameString,
IP: externalIP,