Skip to content

Commit

Permalink
reduce cpu usage of kube-proxy with iptables mode
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyw1990 committed Jul 5, 2021
1 parent b0010c2 commit 1f24a19
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 88 deletions.
10 changes: 5 additions & 5 deletions pkg/proxy/iptables/proxier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1128,9 +1128,9 @@ func TestNodePort(t *testing.T) {
)

itf := net.Interface{Index: 0, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0}
addrs := []net.Addr{utilproxytest.AddrStruct{Val: "127.0.0.1/16"}}
addrs := []net.Addr{&net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(16, 32)}}
itf1 := net.Interface{Index: 1, MTU: 0, Name: "eth1", HardwareAddr: nil, Flags: 0}
addrs1 := []net.Addr{utilproxytest.AddrStruct{Val: "::1/128"}}
addrs1 := []net.Addr{&net.IPNet{IP: net.ParseIP("::1/128"), Mask: net.CIDRMask(128, 128)}}
fp.networkInterfacer.(*utilproxytest.FakeNetwork).AddInterfaceAddr(&itf, addrs)
fp.networkInterfacer.(*utilproxytest.FakeNetwork).AddInterfaceAddr(&itf1, addrs1)
fp.nodePortAddresses = []string{}
Expand Down Expand Up @@ -1180,9 +1180,9 @@ func TestHealthCheckNodePort(t *testing.T) {
)

itf := net.Interface{Index: 0, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0}
addrs := []net.Addr{utilproxytest.AddrStruct{Val: "127.0.0.1/16"}}
addrs := []net.Addr{&net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(16, 32)}}
itf1 := net.Interface{Index: 1, MTU: 0, Name: "eth1", HardwareAddr: nil, Flags: 0}
addrs1 := []net.Addr{utilproxytest.AddrStruct{Val: "::1/128"}}
addrs1 := []net.Addr{&net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)}}
fp.networkInterfacer.(*utilproxytest.FakeNetwork).AddInterfaceAddr(&itf, addrs)
fp.networkInterfacer.(*utilproxytest.FakeNetwork).AddInterfaceAddr(&itf1, addrs1)
fp.nodePortAddresses = []string{"127.0.0.1/16"}
Expand Down Expand Up @@ -1629,7 +1629,7 @@ func onlyLocalNodePorts(t *testing.T, fp *Proxier, ipt *iptablestest.FakeIPTable
)

itf := net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0}
addrs := []net.Addr{utilproxytest.AddrStruct{Val: "10.20.30.51/24"}}
addrs := []net.Addr{&net.IPNet{IP: net.ParseIP("10.20.30.51"), Mask: net.CIDRMask(24, 32)}}
fp.networkInterfacer.(*utilproxytest.FakeNetwork).AddInterfaceAddr(&itf, addrs)
fp.nodePortAddresses = []string{"10.20.30.0/24"}

Expand Down
8 changes: 4 additions & 4 deletions pkg/proxy/ipvs/proxier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1879,9 +1879,9 @@ func TestOnlyLocalNodePorts(t *testing.T) {
)

itf := net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0}
addrs := []net.Addr{proxyutiltest.AddrStruct{Val: "100.101.102.103/24"}}
addrs := []net.Addr{&net.IPNet{IP: net.ParseIP("100.101.102.103"), Mask: net.CIDRMask(24, 32)}}
itf1 := net.Interface{Index: 1, MTU: 0, Name: "eth1", HardwareAddr: nil, Flags: 0}
addrs1 := []net.Addr{proxyutiltest.AddrStruct{Val: "2001:db8::0/64"}}
addrs1 := []net.Addr{&net.IPNet{IP: net.ParseIP("2001:db8::"), Mask: net.CIDRMask(64, 128)}}
fp.networkInterfacer.(*proxyutiltest.FakeNetwork).AddInterfaceAddr(&itf, addrs)
fp.networkInterfacer.(*proxyutiltest.FakeNetwork).AddInterfaceAddr(&itf1, addrs1)
fp.nodePortAddresses = []string{"100.101.102.0/24", "2001:db8::0/64"}
Expand Down Expand Up @@ -1959,9 +1959,9 @@ func TestHealthCheckNodePort(t *testing.T) {
)

itf := net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0}
addrs := []net.Addr{proxyutiltest.AddrStruct{Val: "100.101.102.103/24"}}
addrs := []net.Addr{&net.IPNet{IP: net.ParseIP("100.101.102.103"), Mask: net.CIDRMask(24, 32)}}
itf1 := net.Interface{Index: 1, MTU: 0, Name: "eth1", HardwareAddr: nil, Flags: 0}
addrs1 := []net.Addr{proxyutiltest.AddrStruct{Val: "2001:db8::0/64"}}
addrs1 := []net.Addr{&net.IPNet{IP: net.ParseIP("2001:db8::"), Mask: net.CIDRMask(64, 128)}}
fp.networkInterfacer.(*proxyutiltest.FakeNetwork).AddInterfaceAddr(&itf, addrs)
fp.networkInterfacer.(*proxyutiltest.FakeNetwork).AddInterfaceAddr(&itf1, addrs1)
fp.nodePortAddresses = []string{"100.101.102.0/24", "2001:db8::0/64"}
Expand Down
14 changes: 4 additions & 10 deletions pkg/proxy/util/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,16 @@ import (
// code will forward to net library functions, and unit tests will override the methods
// for testing purposes.
type NetworkInterfacer interface {
Addrs(intf *net.Interface) ([]net.Addr, error)
Interfaces() ([]net.Interface, error)
InterfaceAddrs() ([]net.Addr, error)
}

// RealNetwork implements the NetworkInterfacer interface for production code, just
// wrapping the underlying net library function calls.
type RealNetwork struct{}

// Addrs wraps net.Interface.Addrs(), it's a part of NetworkInterfacer interface.
func (RealNetwork) Addrs(intf *net.Interface) ([]net.Addr, error) {
return intf.Addrs()
}

// Interfaces wraps net.Interfaces(), it's a part of NetworkInterfacer interface.
func (RealNetwork) Interfaces() ([]net.Interface, error) {
return net.Interfaces()
// InterfaceAddrs wraps net.InterfaceAddrs(), it's a part of NetworkInterfacer interface.
func (RealNetwork) InterfaceAddrs() ([]net.Addr, error) {
return net.InterfaceAddrs()
}

var _ NetworkInterfacer = &RealNetwork{}
30 changes: 7 additions & 23 deletions pkg/proxy/util/testing/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,11 @@ func (f *FakeNetwork) AddInterfaceAddr(intf *net.Interface, addrs []net.Addr) {
f.Address[intf.Name] = addrs
}

// Addrs is part of NetworkInterfacer interface.
func (f *FakeNetwork) Addrs(intf *net.Interface) ([]net.Addr, error) {
return f.Address[intf.Name], nil
}

// Interfaces is part of NetworkInterfacer interface.
func (f *FakeNetwork) Interfaces() ([]net.Interface, error) {
return f.NetworkInterfaces, nil
}

// AddrStruct implements the net.Addr for test purpose.
type AddrStruct struct{ Val string }

// Network is part of net.Addr interface.
func (a AddrStruct) Network() string {
return a.Val
}

// String is part of net.Addr interface.
func (a AddrStruct) String() string {
return a.Val
// InterfaceAddrs is part of NetworkInterfacer interface.
func (f *FakeNetwork) InterfaceAddrs() ([]net.Addr, error) {
addrs := make([]net.Addr, 0)
for _, value := range f.Address {
addrs = append(addrs, value...)
}
return addrs, nil
}

var _ net.Addr = &AddrStruct{}
39 changes: 17 additions & 22 deletions pkg/proxy/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,9 @@ func GetNodeAddresses(cidrs []string, nw NetworkInterfacer) (sets.String, error)
}
}

itfs, err := nw.Interfaces()
addrs, err := nw.InterfaceAddrs()
if err != nil {
return nil, fmt.Errorf("error listing all interfaces from host, error: %v", err)
return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %v", err)
}

// Second round of iteration to parse IPs based on cidr.
Expand All @@ -221,29 +221,24 @@ func GetNodeAddresses(cidrs []string, nw NetworkInterfacer) (sets.String, error)
}

_, ipNet, _ := net.ParseCIDR(cidr)
for _, itf := range itfs {
addrs, err := nw.Addrs(&itf)
if err != nil {
return nil, fmt.Errorf("error getting address from interface %s, error: %v", itf.Name, err)
for _, addr := range addrs {
var ip net.IP
// nw.InterfaceAddrs may return net.IPAddr or net.IPNet on windows, and it will return net.IPNet on linux.
switch v := addr.(type) {
case *net.IPAddr:
ip = v.IP
case *net.IPNet:
ip = v.IP
default:
continue
}

for _, addr := range addrs {
if addr == nil {
continue
if ipNet.Contains(ip) {
if utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) {
uniqueAddressList.Insert(ip.String())
}

ip, _, err := net.ParseCIDR(addr.String())
if err != nil {
return nil, fmt.Errorf("error parsing CIDR for interface %s, error: %v", itf.Name, err)
}

if ipNet.Contains(ip) {
if utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) {
uniqueAddressList.Insert(ip.String())
}
if !utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) {
uniqueAddressList.Insert(ip.String())
}
if !utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) {
uniqueAddressList.Insert(ip.String())
}
}
}
Expand Down
48 changes: 24 additions & 24 deletions pkg/proxy/util/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "10.20.30.51/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("10.20.30.51"), Mask: net.CIDRMask(24, 32)}},
},
{
itf: net.Interface{Index: 2, MTU: 0, Name: "eth1", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "100.200.201.1/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("100.200.201.1"), Mask: net.CIDRMask(24, 32)}},
},
},
expected: sets.NewString("10.20.30.51"),
Expand All @@ -432,11 +432,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "10.20.30.51/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("10.20.30.51"), Mask: net.CIDRMask(24, 32)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "127.0.0.1/8"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(8, 32)}},
},
},
expected: sets.NewString("0.0.0.0/0"),
Expand All @@ -447,11 +447,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "2001:db8::1/32"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("2001:db8::1"), Mask: net.CIDRMask(32, 128)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "::1/128"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)}},
},
},
expected: sets.NewString("2001:db8::1", "::1"),
Expand All @@ -462,11 +462,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "2001:db8::1/32"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("2001:db8::1"), Mask: net.CIDRMask(32, 128)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "::1/128"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)}},
},
},
expected: sets.NewString("::/0"),
Expand All @@ -477,11 +477,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "10.20.30.51/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("10.20.30.51"), Mask: net.CIDRMask(24, 32)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "127.0.0.1/8"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(8, 32)}},
},
},
expected: sets.NewString("127.0.0.1"),
Expand All @@ -492,7 +492,7 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "127.0.1.1/8"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("127.0.1.1"), Mask: net.CIDRMask(8, 32)}},
},
},
expected: sets.NewString("127.0.1.1"),
Expand All @@ -503,11 +503,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "10.20.30.51/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("10.20.30.51"), Mask: net.CIDRMask(24, 32)}},
},
{
itf: net.Interface{Index: 2, MTU: 0, Name: "eth1", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "100.200.201.1/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("100.200.201.1"), Mask: net.CIDRMask(24, 32)}},
},
},
expected: sets.NewString("10.20.30.51", "100.200.201.1"),
Expand All @@ -518,11 +518,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "192.168.1.2/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("192.168.1.2"), Mask: net.CIDRMask(24, 32)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "127.0.0.1/8"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(8, 32)}},
},
},
expected: nil,
Expand All @@ -534,11 +534,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "192.168.1.2/24"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("192.168.1.2"), Mask: net.CIDRMask(24, 32)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "127.0.0.1/8"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(8, 32)}},
},
},
expected: sets.NewString("0.0.0.0/0", "::/0"),
Expand All @@ -549,11 +549,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "2001:db8::1/32"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("2001:db8::1"), Mask: net.CIDRMask(32, 128)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "::1/128"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)}},
},
},
expected: sets.NewString("0.0.0.0/0", "::/0"),
Expand All @@ -564,7 +564,7 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "1.2.3.4/30"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("1.2.3.4"), Mask: net.CIDRMask(30, 32)}},
},
},
expected: sets.NewString("0.0.0.0/0"),
Expand All @@ -575,11 +575,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "1.2.3.4/30"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("1.2.3.4"), Mask: net.CIDRMask(30, 32)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "::1/128"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)}},
},
},
expected: sets.NewString("0.0.0.0/0", "::1"),
Expand All @@ -590,11 +590,11 @@ func TestGetNodeAddresses(t *testing.T) {
itfAddrsPairs: []InterfaceAddrsPair{
{
itf: net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "1.2.3.4/30"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("1.2.3.4"), Mask: net.CIDRMask(30, 32)}},
},
{
itf: net.Interface{Index: 1, MTU: 0, Name: "lo", HardwareAddr: nil, Flags: 0},
addrs: []net.Addr{fake.AddrStruct{Val: "::1/128"}},
addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("::1"), Mask: net.CIDRMask(128, 128)}},
},
},
expected: sets.NewString("::/0", "1.2.3.4"),
Expand Down

0 comments on commit 1f24a19

Please sign in to comment.