kubeadm: validate node-cidr-mask are correct

This commit is contained in:
Antonio Ojea 2020-10-22 16:41:46 +02:00
parent 7fc6b4157b
commit 4e14d1b9a3
2 changed files with 55 additions and 9 deletions

View File

@ -432,7 +432,11 @@ func ValidatePodSubnetNodeMask(subnetStr string, c *kubeadm.ClusterConfiguration
mask := podSubnet.Mask
maskSize, _ := mask.Size()
// obtain node-cidr-mask
nodeMask := getClusterNodeMask(c, utilnet.IsIPv6(podSubnet.IP))
nodeMask, err := getClusterNodeMask(c, utilnet.IsIPv6(podSubnet.IP))
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, podSubnet.String(), err.Error()))
continue
}
// the pod subnet mask needs to allow one or multiple node-masks
// i.e. if it has a /24 the node mask must be between 24 and 32 for ipv4
if maskSize > nodeMask {
@ -447,13 +451,14 @@ func ValidatePodSubnetNodeMask(subnetStr string, c *kubeadm.ClusterConfiguration
// getClusterNodeMask returns the corresponding node-cidr-mask
// based on the Cluster configuration and the IP family
// Default is 24 for IPv4 and 64 for IPv6
func getClusterNodeMask(c *kubeadm.ClusterConfiguration, isIPv6 bool) int {
func getClusterNodeMask(c *kubeadm.ClusterConfiguration, isIPv6 bool) (int, error) {
// defaultNodeMaskCIDRIPv4 is default mask size for IPv4 node cidr for use by the controller manager
const defaultNodeMaskCIDRIPv4 = 24
// DefaultNodeMaskCIDRIPv6 is default mask size for IPv6 node cidr for use by the controller manager
const defaultNodeMaskCIDRIPv6 = 64
var maskSize int
var maskArg string
var err error
isDualStack := features.Enabled(c.FeatureGates, features.IPv6DualStack)
if isDualStack && isIPv6 {
@ -466,13 +471,17 @@ func getClusterNodeMask(c *kubeadm.ClusterConfiguration, isIPv6 bool) int {
if v, ok := c.ControllerManager.ExtraArgs[maskArg]; ok && v != "" {
// assume it is an integer, if not it will fail later
maskSize, _ = strconv.Atoi(v)
maskSize, err = strconv.Atoi(v)
if err != nil {
errors.Wrapf(err, "could not parse the value of the kube-controller-manager flag %s as an integer: %v", maskArg, err)
return 0, err
}
} else if isIPv6 {
maskSize = defaultNodeMaskCIDRIPv6
} else {
maskSize = defaultNodeMaskCIDRIPv4
}
return maskSize
return maskSize, nil
}
// ValidateNetworking validates networking configuration

View File

@ -1130,10 +1130,11 @@ func TestValidateEtcd(t *testing.T) {
func TestGetClusterNodeMask(t *testing.T) {
tests := []struct {
name string
cfg *kubeadmapi.ClusterConfiguration
isIPv6 bool
expectedMask int
name string
cfg *kubeadmapi.ClusterConfiguration
isIPv6 bool
expectedMask int
expectedError bool
}{
{
name: "ipv4 default mask",
@ -1151,6 +1152,16 @@ func TestGetClusterNodeMask(t *testing.T) {
isIPv6: false,
expectedMask: 23,
},
{
name: "ipv4 wrong mask",
cfg: &kubeadmapi.ClusterConfiguration{
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "aa23"},
},
},
isIPv6: false,
expectedError: true,
},
{
name: "ipv6 default mask",
cfg: &kubeadmapi.ClusterConfiguration{},
@ -1216,6 +1227,17 @@ func TestGetClusterNodeMask(t *testing.T) {
isIPv6: false,
expectedMask: 23,
},
{
name: "dual ipv4 wrong mask",
cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size-ipv4": "aa"},
},
},
isIPv6: false,
expectedError: true,
},
{
name: "dual ipv6 default mask and legacy flag",
cfg: &kubeadmapi.ClusterConfiguration{
@ -1238,10 +1260,25 @@ func TestGetClusterNodeMask(t *testing.T) {
isIPv6: true,
expectedMask: 83,
},
{
name: "dual ipv6 custom mask and wrong flag",
cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "23", "node-cidr-mask-size-ipv6": "a83"},
},
},
isIPv6: true,
expectedError: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if mask := getClusterNodeMask(test.cfg, test.isIPv6); mask != test.expectedMask {
mask, err := getClusterNodeMask(test.cfg, test.isIPv6)
if (err == nil) == test.expectedError {
t.Errorf("expected error: %v, got %v", test.expectedError, err)
}
if mask != test.expectedMask {
t.Errorf("expected mask: %d, got %d", test.expectedMask, mask)
}
})