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 <kiman@vmware.com>
This commit is contained in:
Andrew Sy Kim 2019-11-27 13:54:17 -05:00 committed by andrewsykim
parent 126bf5a231
commit 77feb1126e

View File

@ -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)
}