From 77feb1126e4b8c18d2d593fe6b5267febfc4ddd2 Mon Sep 17 00:00:00 2001 From: Andrew Sy Kim Date: Wed, 27 Nov 2019 13:54:17 -0500 Subject: [PATCH] userspace proxy: 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 --- pkg/proxy/userspace/proxier.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pkg/proxy/userspace/proxier.go b/pkg/proxy/userspace/proxier.go index 7a34529d6ff..0345a553489 100644 --- a/pkg/proxy/userspace/proxier.go +++ b/pkg/proxy/userspace/proxier.go @@ -127,6 +127,7 @@ type Proxier struct { listenIP net.IP iptables iptables.Interface hostIP net.IP + localAddrs []net.IP proxyPorts PortAllocator makeProxySocket ProxySocketFunc exec utilexec.Interface @@ -371,6 +372,14 @@ func (proxier *Proxier) syncProxyRules() { proxier.unmergeService(change.previous, existingPorts) } + localAddrs, err := utilproxy.GetLocalAddrs() + if err != nil { + klog.Errorf("Failed to get local addresses during proxy sync: %s, assuming IPs are not local", err) + } else if len(localAddrs) == 0 { + klog.Warning("No local addresses were found, assuming all external IPs are not local") + } + proxier.localAddrs = localAddrs + proxier.ensurePortals() proxier.cleanupStaleStickySessions() } @@ -725,9 +734,7 @@ func (proxier *Proxier) openPortal(service proxy.ServicePortName, info *ServiceI } func (proxier *Proxier) openOnePortal(portal portal, protocol v1.Protocol, proxyIP net.IP, proxyPort int, name proxy.ServicePortName) error { - if local, err := utilproxy.IsLocalIP(portal.ip.String()); err != nil { - return fmt.Errorf("can't determine if IP %s is local, assuming not: %v", portal.ip, err) - } else if local { + if len(proxier.localAddrs) > 0 && utilproxy.ContainsIP(proxier.localAddrs, portal.ip) { err := proxier.claimNodePort(portal.ip, portal.port, protocol, name) if err != nil { return err @@ -903,10 +910,7 @@ func (proxier *Proxier) closePortal(service proxy.ServicePortName, info *Service func (proxier *Proxier) closeOnePortal(portal portal, protocol v1.Protocol, proxyIP net.IP, proxyPort int, name proxy.ServicePortName) []error { el := []error{} - - if local, err := utilproxy.IsLocalIP(portal.ip.String()); err != nil { - el = append(el, fmt.Errorf("can't determine if IP %s is local, assuming not: %v", portal.ip, err)) - } else if local { + if len(proxier.localAddrs) > 0 && utilproxy.ContainsIP(proxier.localAddrs, portal.ip) { if err := proxier.releaseNodePort(portal.ip, portal.port, protocol, name); err != nil { el = append(el, err) }