mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Warn users with bad --nodeport-addresses
If users don't pass any --nodeport-addresses, suggest they should pass `--nodeport-addresses primary`, to avoid accepting NodePort connections on all interfaces. If users pass a single-stack --nodeport-addresses in what looks like a dual-stack cluster, warn them that they probably ought to be passing a dual-stack --nodeport-addresses.
This commit is contained in:
parent
0b599aa8e3
commit
fde1af55d2
@ -661,6 +661,11 @@ func newProxyServer(logger klog.Logger, config *kubeproxyconfig.KubeProxyConfigu
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = checkBadConfig(s)
|
||||
if err != nil {
|
||||
logger.Error(err, "Kube-proxy configuration may be incomplete or incorrect")
|
||||
}
|
||||
|
||||
ipv4Supported, ipv6Supported, dualStackSupported, err := s.platformCheckSupported()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -672,7 +677,7 @@ func newProxyServer(logger klog.Logger, config *kubeproxyconfig.KubeProxyConfigu
|
||||
logger.Info("kube-proxy running in single-stack mode", "ipFamily", s.PrimaryIPFamily)
|
||||
}
|
||||
|
||||
err, fatal := checkIPConfig(s, dualStackSupported)
|
||||
err, fatal := checkBadIPConfig(s, dualStackSupported)
|
||||
if err != nil {
|
||||
if fatal {
|
||||
return nil, fmt.Errorf("kube-proxy configuration is incorrect: %v", err)
|
||||
@ -688,8 +693,42 @@ func newProxyServer(logger klog.Logger, config *kubeproxyconfig.KubeProxyConfigu
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// checkIPConfig confirms that s has proper configuration for its primary IP family.
|
||||
func checkIPConfig(s *ProxyServer, dualStackSupported bool) (error, bool) {
|
||||
// checkBadConfig checks for bad/deprecated configuation
|
||||
func checkBadConfig(s *ProxyServer) error {
|
||||
var errors []error
|
||||
|
||||
// At this point we haven't seen any actual Services or EndpointSlices, so we
|
||||
// don't really know if the cluster is expected to be single- or dual-stack. But
|
||||
// we can at least take note of whether there is any explicitly-dual-stack
|
||||
// configuration.
|
||||
anyDualStackConfig := false
|
||||
clusterCIDRs := strings.Split(s.Config.ClusterCIDR, ",")
|
||||
for _, config := range [][]string{clusterCIDRs, s.Config.NodePortAddresses, s.Config.IPVS.ExcludeCIDRs, s.podCIDRs} {
|
||||
if dual, _ := netutils.IsDualStackCIDRStrings(config); dual {
|
||||
anyDualStackConfig = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Warn if NodePortAddresses does not limit connections on all IP families that
|
||||
// seem to be in use.
|
||||
cidrsByFamily := proxyutil.MapCIDRsByIPFamily(s.Config.NodePortAddresses)
|
||||
if len(s.Config.NodePortAddresses) == 0 {
|
||||
errors = append(errors, fmt.Errorf("nodePortAddresses is unset; NodePort connections will be accepted on all local IPs. Consider using `--nodeport-addresses primary`"))
|
||||
} else if anyDualStackConfig && len(cidrsByFamily[s.PrimaryIPFamily]) == len(s.Config.NodePortAddresses) {
|
||||
errors = append(errors, fmt.Errorf("cluster appears to be dual-stack but nodePortAddresses contains only %s addresses; NodePort connections will be accepted on all local %s IPs", s.PrimaryIPFamily, proxyutil.OtherIPFamily(s.PrimaryIPFamily)))
|
||||
} else if len(cidrsByFamily[s.PrimaryIPFamily]) == 0 {
|
||||
errors = append(errors, fmt.Errorf("cluster appears to be %s-primary but nodePortAddresses contains only %s addresses; NodePort connections will be accepted on all local %s IPs", s.PrimaryIPFamily, proxyutil.OtherIPFamily(s.PrimaryIPFamily), s.PrimaryIPFamily))
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(errors)
|
||||
}
|
||||
|
||||
// checkBadIPConfig checks for bad configuration relative to s.PrimaryIPFamily.
|
||||
// Historically, we did not check most of the config options, so we cannot retroactively
|
||||
// make IP family mismatches in those options be fatal. When we add new options to check
|
||||
// here, we should make problems with those options be fatal.
|
||||
func checkBadIPConfig(s *ProxyServer, dualStackSupported bool) (err error, fatal bool) {
|
||||
var errors []error
|
||||
var badFamily netutils.IPFamily
|
||||
|
||||
@ -706,11 +745,6 @@ func checkIPConfig(s *ProxyServer, dualStackSupported bool) (error, bool) {
|
||||
clusterType = fmt.Sprintf("%s-only", s.PrimaryIPFamily)
|
||||
}
|
||||
|
||||
// Historically, we did not check most of the config options, so we cannot
|
||||
// retroactively make IP family mismatches in those options be fatal. When we add
|
||||
// new options to check here, we should make problems with those options be fatal.
|
||||
fatal := false
|
||||
|
||||
if s.Config.ClusterCIDR != "" {
|
||||
clusterCIDRs := strings.Split(s.Config.ClusterCIDR, ",")
|
||||
if badCIDRs(clusterCIDRs, badFamily) {
|
||||
@ -722,10 +756,6 @@ func checkIPConfig(s *ProxyServer, dualStackSupported bool) (error, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
if badCIDRs(s.Config.NodePortAddresses, badFamily) {
|
||||
errors = append(errors, fmt.Errorf("cluster is %s but nodePortAddresses contains only IPv%s addresses", clusterType, badFamily))
|
||||
}
|
||||
|
||||
if badCIDRs(s.podCIDRs, badFamily) {
|
||||
errors = append(errors, fmt.Errorf("cluster is %s but node.spec.podCIDRs contains only IPv%s addresses", clusterType, badFamily))
|
||||
if s.Config.DetectLocalMode == kubeproxyconfig.LocalModeNodeCIDR {
|
||||
@ -753,6 +783,9 @@ func checkIPConfig(s *ProxyServer, dualStackSupported bool) (error, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// Note that s.Config.NodePortAddresses gets checked as part of checkBadConfig()
|
||||
// so it doesn't need to be checked here.
|
||||
|
||||
return utilerrors.NewAggregate(errors), fatal
|
||||
}
|
||||
|
||||
|
@ -849,7 +849,81 @@ func Test_detectNodeIPs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_checkIPConfig(t *testing.T) {
|
||||
func Test_checkBadConfig(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
proxy *ProxyServer
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
name: "single-stack NodePortAddresses with single-stack config",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
ClusterCIDR: "10.0.0.0/8",
|
||||
NodePortAddresses: []string{"192.168.0.0/24"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv4Protocol,
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
name: "dual-stack NodePortAddresses with dual-stack config",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
ClusterCIDR: "10.0.0.0/8,fd09::/64",
|
||||
NodePortAddresses: []string{"192.168.0.0/24", "fd03::/64"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv4Protocol,
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
name: "empty NodePortAddresses",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
NodePortAddresses: []string{},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv4Protocol,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
name: "single-stack NodePortAddresses with dual-stack config",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
ClusterCIDR: "10.0.0.0/8,fd09::/64",
|
||||
NodePortAddresses: []string{"192.168.0.0/24"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv4Protocol,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
name: "wrong-single-stack NodePortAddresses",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
ClusterCIDR: "fd09::/64",
|
||||
NodePortAddresses: []string{"192.168.0.0/24"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv6Protocol,
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
err := checkBadConfig(c.proxy)
|
||||
if err != nil && !c.err {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
} else if err == nil && c.err {
|
||||
t.Errorf("unexpected lack of error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_checkBadIPConfig(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
proxy *ProxyServer
|
||||
@ -929,53 +1003,6 @@ func Test_checkIPConfig(t *testing.T) {
|
||||
dsFatal: false,
|
||||
},
|
||||
|
||||
{
|
||||
name: "ok single-stack nodePortAddresses",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
NodePortAddresses: []string{"10.0.0.0/8", "192.168.0.0/24"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv4Protocol,
|
||||
},
|
||||
ssErr: false,
|
||||
dsErr: false,
|
||||
},
|
||||
{
|
||||
name: "ok dual-stack nodePortAddresses",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
NodePortAddresses: []string{"10.0.0.0/8", "fd01:2345::/64", "fd01:abcd::/64"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv4Protocol,
|
||||
},
|
||||
ssErr: false,
|
||||
dsErr: false,
|
||||
},
|
||||
{
|
||||
name: "ok reversed dual-stack nodePortAddresses",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
NodePortAddresses: []string{"fd01:2345::/64", "fd01:abcd::/64", "10.0.0.0/8"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv4Protocol,
|
||||
},
|
||||
ssErr: false,
|
||||
dsErr: false,
|
||||
},
|
||||
{
|
||||
name: "wrong-family nodePortAddresses",
|
||||
proxy: &ProxyServer{
|
||||
Config: &kubeproxyconfig.KubeProxyConfiguration{
|
||||
NodePortAddresses: []string{"10.0.0.0/8"},
|
||||
},
|
||||
PrimaryIPFamily: v1.IPv6Protocol,
|
||||
},
|
||||
ssErr: true,
|
||||
ssFatal: false,
|
||||
dsErr: true,
|
||||
dsFatal: false,
|
||||
},
|
||||
|
||||
{
|
||||
name: "ok single-stack node.spec.podCIDRs",
|
||||
proxy: &ProxyServer{
|
||||
@ -1133,7 +1160,7 @@ func Test_checkIPConfig(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
err, fatal := checkIPConfig(c.proxy, false)
|
||||
err, fatal := checkBadIPConfig(c.proxy, false)
|
||||
if err != nil && !c.ssErr {
|
||||
t.Errorf("unexpected error in single-stack case: %v", err)
|
||||
} else if err == nil && c.ssErr {
|
||||
@ -1142,7 +1169,7 @@ func Test_checkIPConfig(t *testing.T) {
|
||||
t.Errorf("expected fatal=%v, got %v", c.ssFatal, fatal)
|
||||
}
|
||||
|
||||
err, fatal = checkIPConfig(c.proxy, true)
|
||||
err, fatal = checkBadIPConfig(c.proxy, true)
|
||||
if err != nil && !c.dsErr {
|
||||
t.Errorf("unexpected error in dual-stack case: %v", err)
|
||||
} else if err == nil && c.dsErr {
|
||||
|
Loading…
Reference in New Issue
Block a user