mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Merge pull request #107684 from aojea/nodePortsOnLocalhost
kube-proxy: only set route_localnet if required
This commit is contained in:
commit
2134e971a6
@ -264,10 +264,13 @@ func NewProxier(ipt utiliptables.Interface,
|
|||||||
healthzServer healthcheck.ProxierHealthUpdater,
|
healthzServer healthcheck.ProxierHealthUpdater,
|
||||||
nodePortAddresses []string,
|
nodePortAddresses []string,
|
||||||
) (*Proxier, error) {
|
) (*Proxier, error) {
|
||||||
// Set the route_localnet sysctl we need for
|
if utilproxy.ContainsIPv4Loopback(nodePortAddresses) {
|
||||||
|
// Set the route_localnet sysctl we need for exposing NodePorts on loopback addresses
|
||||||
|
klog.InfoS("Setting route_localnet=1, use nodePortAddresses to filter loopback addresses for NodePorts to skip it https://issues.k8s.io/90259")
|
||||||
if err := utilproxy.EnsureSysctl(sysctl, sysctlRouteLocalnet, 1); err != nil {
|
if err := utilproxy.EnsureSysctl(sysctl, sysctlRouteLocalnet, 1); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Proxy needs br_netfilter and bridge-nf-call-iptables=1 when containers
|
// Proxy needs br_netfilter and bridge-nf-call-iptables=1 when containers
|
||||||
// are connected to a Linux bridge (but not SDN bridges). Until most
|
// are connected to a Linux bridge (but not SDN bridges). Until most
|
||||||
|
@ -78,6 +78,37 @@ func BuildPortsToEndpointsMap(endpoints *v1.Endpoints) map[string][]string {
|
|||||||
return portsToEndpoints
|
return portsToEndpoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainsIPv4Loopback returns true if the input is empty or one of the CIDR contains an IPv4 loopback address.
|
||||||
|
func ContainsIPv4Loopback(cidrStrings []string) bool {
|
||||||
|
if len(cidrStrings) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// RFC 5735 127.0.0.0/8 - This block is assigned for use as the Internet host loopback address
|
||||||
|
ipv4LoopbackStart := netutils.ParseIPSloppy("127.0.0.0")
|
||||||
|
for _, cidr := range cidrStrings {
|
||||||
|
if IsZeroCIDR(cidr) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
ip, ipnet, err := netutils.ParseCIDRSloppy(cidr)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if netutils.IsIPv6CIDR(ipnet) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip.IsLoopback() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ipnet.Contains(ipv4LoopbackStart) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// IsZeroCIDR checks whether the input CIDR string is either
|
// IsZeroCIDR checks whether the input CIDR string is either
|
||||||
// the IPv4 or IPv6 zero CIDR
|
// the IPv4 or IPv6 zero CIDR
|
||||||
func IsZeroCIDR(cidr string) bool {
|
func IsZeroCIDR(cidr string) bool {
|
||||||
|
@ -1401,3 +1401,68 @@ func TestAddressSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContainsIPv4Loopback(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
cidrStrings []string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all zeros ipv4",
|
||||||
|
cidrStrings: []string{"224.0.0.0/24", "192.168.0.0/16", "fd00:1:d::/64", "0.0.0.0/0"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all zeros ipv4 and invalid cidr",
|
||||||
|
cidrStrings: []string{"invalid.cidr", "192.168.0.0/16", "fd00:1:d::/64", "0.0.0.0/0"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all zeros ipv6", // interpret all zeros equal for IPv4 and IPv6 as Golang stdlib
|
||||||
|
cidrStrings: []string{"224.0.0.0/24", "192.168.0.0/16", "fd00:1:d::/64", "::/0"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ipv4 loopback",
|
||||||
|
cidrStrings: []string{"224.0.0.0/24", "192.168.0.0/16", "fd00:1:d::/64", "127.0.0.0/8"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ipv6 loopback",
|
||||||
|
cidrStrings: []string{"224.0.0.0/24", "192.168.0.0/16", "fd00:1:d::/64", "::1/128"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ipv4 loopback smaller range",
|
||||||
|
cidrStrings: []string{"224.0.0.0/24", "192.168.0.0/16", "fd00:1:d::/64", "127.0.2.0/28"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ipv4 loopback within larger range",
|
||||||
|
cidrStrings: []string{"224.0.0.0/24", "192.168.0.0/16", "fd00:1:d::/64", "64.0.0.0/2"},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "non loop loopback",
|
||||||
|
cidrStrings: []string{"128.0.2.0/28", "224.0.0.0/24", "192.168.0.0/16", "fd00:1:d::/64"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid cidr",
|
||||||
|
cidrStrings: []string{"invalid.ip/invalid.mask"},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := ContainsIPv4Loopback(tt.cidrStrings); got != tt.want {
|
||||||
|
t.Errorf("ContainLoopback() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user