mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
kubeadm --pod-network-cidr supports a comma separated list of pod
CIDRs. This is a necesary change for dual-stack.
This commit is contained in:
parent
ec77598906
commit
3ac7ae60cc
@ -21,6 +21,7 @@ go_library(
|
||||
"//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -40,6 +40,7 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// ValidateInitConfiguration validates an InitConfiguration object and collects all encountered errors
|
||||
@ -48,6 +49,7 @@ func ValidateInitConfiguration(c *kubeadm.InitConfiguration) field.ErrorList {
|
||||
allErrs = append(allErrs, ValidateNodeRegistrationOptions(&c.NodeRegistration, field.NewPath("nodeRegistration"))...)
|
||||
allErrs = append(allErrs, ValidateBootstrapTokens(c.BootstrapTokens, field.NewPath("bootstrapTokens"))...)
|
||||
allErrs = append(allErrs, ValidateClusterConfiguration(&c.ClusterConfiguration)...)
|
||||
// TODO(Arvinderpal): update advertiseAddress validation for dual-stack once it's implemented.
|
||||
allErrs = append(allErrs, ValidateAPIEndpoint(&c.LocalAPIEndpoint, field.NewPath("localAPIEndpoint"))...)
|
||||
// TODO: Maybe validate that .CertificateKey is a valid hex encoded AES key
|
||||
return allErrs
|
||||
@ -56,7 +58,7 @@ func ValidateInitConfiguration(c *kubeadm.InitConfiguration) field.ErrorList {
|
||||
// ValidateClusterConfiguration validates an ClusterConfiguration object and collects all encountered errors
|
||||
func ValidateClusterConfiguration(c *kubeadm.ClusterConfiguration) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
|
||||
allErrs = append(allErrs, ValidateNetworking(c, field.NewPath("networking"))...)
|
||||
allErrs = append(allErrs, ValidateAPIServer(&c.APIServer, field.NewPath("apiServer"))...)
|
||||
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificatesDir"))...)
|
||||
allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("featureGates"))...)
|
||||
@ -369,30 +371,53 @@ func ValidateHostPort(endpoint string, fldPath *field.Path) field.ErrorList {
|
||||
}
|
||||
|
||||
// ValidateIPNetFromString validates network portion of ip address
|
||||
func ValidateIPNetFromString(subnet string, minAddrs int64, fldPath *field.Path) field.ErrorList {
|
||||
func ValidateIPNetFromString(subnetStr string, minAddrs int64, isDualStack bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
_, svcSubnet, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnet, "couldn't parse subnet"))
|
||||
return allErrs
|
||||
}
|
||||
numAddresses := ipallocator.RangeSize(svcSubnet)
|
||||
if numAddresses < minAddrs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnet, "subnet is too small"))
|
||||
if isDualStack {
|
||||
subnets, err := utilnet.ParseCIDRs(strings.Split(subnetStr, ","))
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, err.Error()))
|
||||
} else {
|
||||
areDualStackCIDRs, err := utilnet.IsDualStackCIDRs(subnets)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnets, err.Error()))
|
||||
} else if !areDualStackCIDRs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected at least one IP from each family (v4 or v6) for dual-stack networking"))
|
||||
}
|
||||
for _, s := range subnets {
|
||||
numAddresses := ipallocator.RangeSize(s)
|
||||
if numAddresses < minAddrs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, s, "subnet is too small"))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, svcSubnet, err := net.ParseCIDR(subnetStr)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "couldn't parse subnet"))
|
||||
return allErrs
|
||||
}
|
||||
numAddresses := ipallocator.RangeSize(svcSubnet)
|
||||
if numAddresses < minAddrs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "subnet is too small"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateNetworking validates networking configuration
|
||||
func ValidateNetworking(c *kubeadm.Networking, fldPath *field.Path) field.ErrorList {
|
||||
func ValidateNetworking(c *kubeadm.ClusterConfiguration, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
dnsDomainFldPath := field.NewPath("dnsDomain")
|
||||
for _, err := range validation.IsDNS1123Subdomain(c.DNSDomain) {
|
||||
allErrs = append(allErrs, field.Invalid(dnsDomainFldPath, c.DNSDomain, err))
|
||||
for _, err := range validation.IsDNS1123Subdomain(c.Networking.DNSDomain) {
|
||||
allErrs = append(allErrs, field.Invalid(dnsDomainFldPath, c.Networking.DNSDomain, err))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateIPNetFromString(c.ServiceSubnet, constants.MinimumAddressesInServiceSubnet, field.NewPath("serviceSubnet"))...)
|
||||
if len(c.PodSubnet) != 0 {
|
||||
allErrs = append(allErrs, ValidateIPNetFromString(c.PodSubnet, constants.MinimumAddressesInServiceSubnet, field.NewPath("podSubnet"))...)
|
||||
// check if dual-stack feature-gate is enabled
|
||||
isDualStack := features.Enabled(c.FeatureGates, features.IPv6DualStack)
|
||||
// TODO(Arvinderpal): use isDualStack flag once list of service CIDRs is supported (PR: #79386)
|
||||
allErrs = append(allErrs, ValidateIPNetFromString(c.Networking.ServiceSubnet, constants.MinimumAddressesInServiceSubnet, false /*isDualStack*/, field.NewPath("serviceSubnet"))...)
|
||||
if len(c.Networking.PodSubnet) != 0 {
|
||||
allErrs = append(allErrs, ValidateIPNetFromString(c.Networking.PodSubnet, constants.MinimumAddressesInServiceSubnet, isDualStack, field.NewPath("podSubnet"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@ -455,7 +480,6 @@ func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) fie
|
||||
fmt.Sprintf("%s is not a valid feature name.", k)))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
@ -194,29 +194,43 @@ func TestValidateIPFromString(t *testing.T) {
|
||||
|
||||
func TestValidateIPNetFromString(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
subnet string
|
||||
minaddrs int64
|
||||
expected bool
|
||||
name string
|
||||
subnet string
|
||||
minaddrs int64
|
||||
checkDualStack bool
|
||||
expected bool
|
||||
}{
|
||||
{"invalid missing CIDR", "", 0, false},
|
||||
{"invalid CIDR missing decimal points in IPv4 address and / mask", "1234", 0, false},
|
||||
{"invalid CIDR use of letters instead of numbers and / mask", "abc", 0, false},
|
||||
{"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4", 0, false},
|
||||
{"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1", 0, false},
|
||||
{"valid, but IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29", 10, false},
|
||||
{"valid, but IPv6 CIDR too small. At least 10 addresses needed", "2001:db8::/125", 10, false},
|
||||
{"valid IPv4 CIDR", "10.0.0.16/12", 10, true},
|
||||
{"valid IPv6 CIDR", "2001:db8::/98", 10, true},
|
||||
{"invalid missing CIDR", "", 0, false, false},
|
||||
{"invalid CIDR missing decimal points in IPv4 address and / mask", "1234", 0, false, false},
|
||||
{"invalid CIDR use of letters instead of numbers and / mask", "abc", 0, false, false},
|
||||
{"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4", 0, false, false},
|
||||
{"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1", 0, false, false},
|
||||
{"valid, but IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29", 10, false, false},
|
||||
{"valid, but IPv6 CIDR too small. At least 10 addresses needed", "2001:db8::/125", 10, false, false},
|
||||
{"valid IPv4 CIDR", "10.0.0.16/12", 10, false, true},
|
||||
{"valid IPv6 CIDR", "2001:db8::/98", 10, false, true},
|
||||
// dual-stack:
|
||||
{"invalid missing CIDR", "", 0, true, false},
|
||||
{"invalid only an IPv4 CIDR specified", "10.0.0.16/12", 10, true, false},
|
||||
{"invalid only an IPv6 CIDR specified", "2001:db8::/98", 10, true, false},
|
||||
{"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4,2001:db8::/98", 0, true, false},
|
||||
{"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1,10.0.0.16/12", 0, true, false},
|
||||
{"valid, but IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29,2001:db8::/98", 10, true, false},
|
||||
{"valid, but IPv6 CIDR too small. At least 10 addresses needed", "10.0.0.16/12,2001:db8::/125", 10, true, false},
|
||||
{"valid, but only IPv4 family addresses specified. IPv6 CIDR is necessary.", "10.0.0.16/12,192.168.0.0/16", 10, true, false},
|
||||
{"valid, but only IPv6 family addresses specified. IPv4 CIDR is necessary.", "2001:db8::/98,2005:db8::/98", 10, true, false},
|
||||
{"valid IPv4 and IPv6 CIDR", "10.0.0.16/12,2001:db8::/98", 10, true, true},
|
||||
{"valid IPv6 and IPv4 CIDR", "10.0.0.16/12,2001:db8::/98", 10, true, true},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, nil)
|
||||
actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, rt.checkDualStack, nil)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"%s test case failed :\n\texpected: %t\n\t actual: %t",
|
||||
"%s test case failed :\n\texpected: %t\n\t actual: %t\n\t err(s): %v\n\t",
|
||||
rt.name,
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -292,6 +292,7 @@ func getControllerManagerCommand(cfg *kubeadmapi.ClusterConfiguration) []string
|
||||
// Let the controller-manager allocate Node CIDRs for the Pod network.
|
||||
// Each node will get a subspace of the address CIDR provided with --pod-network-cidr.
|
||||
if cfg.Networking.PodSubnet != "" {
|
||||
// TODO(Arvinderpal): Needs to be fixed once PR #73977 lands. Should be a list of maskSizes.
|
||||
maskSize := calcNodeCidrSize(cfg.Networking.PodSubnet)
|
||||
defaultArguments["allocate-node-cidrs"] = "true"
|
||||
defaultArguments["cluster-cidr"] = cfg.Networking.PodSubnet
|
||||
|
@ -908,7 +908,11 @@ func RunInitNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigura
|
||||
FileAvailableCheck{Path: kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.Etcd, manifestsDir)},
|
||||
HTTPProxyCheck{Proto: "https", Host: cfg.LocalAPIEndpoint.AdvertiseAddress},
|
||||
HTTPProxyCIDRCheck{Proto: "https", CIDR: cfg.Networking.ServiceSubnet},
|
||||
HTTPProxyCIDRCheck{Proto: "https", CIDR: cfg.Networking.PodSubnet},
|
||||
}
|
||||
|
||||
cidrs := strings.Split(cfg.Networking.PodSubnet, ",")
|
||||
for _, cidr := range cidrs {
|
||||
checks = append(checks, HTTPProxyCIDRCheck{Proto: "https", CIDR: cidr})
|
||||
}
|
||||
|
||||
if !isSecondaryControlPlane {
|
||||
|
Loading…
Reference in New Issue
Block a user