Merge pull request #104770 from pacoxu/dual-stack-ga-kubeadm

cleanup: DualStack GA for kubeadm
This commit is contained in:
Kubernetes Prow Robot 2021-09-28 03:42:42 -07:00 committed by GitHub
commit bf000e8770
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 71 additions and 308 deletions

View File

@ -375,7 +375,7 @@ func ValidateHostPort(endpoint string, fldPath *field.Path) field.ErrorList {
} }
// ValidateIPNetFromString validates network portion of ip address // ValidateIPNetFromString validates network portion of ip address
func ValidateIPNetFromString(subnetStr string, minAddrs int64, isDualStack bool, fldPath *field.Path) field.ErrorList { func ValidateIPNetFromString(subnetStr string, minAddrs int64, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
subnets, err := netutils.ParseCIDRs(strings.Split(subnetStr, ",")) subnets, err := netutils.ParseCIDRs(strings.Split(subnetStr, ","))
if err != nil { if err != nil {
@ -384,19 +384,16 @@ func ValidateIPNetFromString(subnetStr string, minAddrs int64, isDualStack bool,
} }
switch { switch {
// if DualStack only 2 CIDRs allowed // if DualStack only 2 CIDRs allowed
case isDualStack && len(subnets) > 2: case len(subnets) > 2:
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected one (IPv4 or IPv6) CIDR or two CIDRs from each family for dual-stack networking")) allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected one (IPv4 or IPv6) CIDR or two CIDRs from each family for dual-stack networking"))
// if DualStack and there are 2 CIDRs validate if there is at least one of each IP family // if DualStack and there are 2 CIDRs validate if there is at least one of each IP family
case isDualStack && len(subnets) == 2: case len(subnets) == 2:
areDualStackCIDRs, err := netutils.IsDualStackCIDRs(subnets) areDualStackCIDRs, err := netutils.IsDualStackCIDRs(subnets)
if err != nil { if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, err.Error())) allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, err.Error()))
} else if !areDualStackCIDRs { } else if !areDualStackCIDRs {
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected one (IPv4 or IPv6) CIDR or two CIDRs from each family for dual-stack networking")) allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected one (IPv4 or IPv6) CIDR or two CIDRs from each family for dual-stack networking"))
} }
// if not DualStack only one CIDR allowed
case !isDualStack && len(subnets) > 1:
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "only one CIDR allowed for single-stack networking"))
} }
// validate the subnet/s // validate the subnet/s
for _, s := range subnets { for _, s := range subnets {
@ -470,14 +467,11 @@ func getClusterNodeMask(c *kubeadm.ClusterConfiguration, isIPv6 bool) (int, erro
var maskSize int var maskSize int
var maskArg string var maskArg string
var err error var err error
isDualStack := features.Enabled(c.FeatureGates, features.IPv6DualStack)
if isDualStack && isIPv6 { if isIPv6 {
maskArg = "node-cidr-mask-size-ipv6" maskArg = "node-cidr-mask-size-ipv6"
} else if isDualStack && !isIPv6 {
maskArg = "node-cidr-mask-size-ipv4"
} else { } else {
maskArg = "node-cidr-mask-size" maskArg = "node-cidr-mask-size-ipv4"
} }
if v, ok := c.ControllerManager.ExtraArgs[maskArg]; ok && v != "" { if v, ok := c.ControllerManager.ExtraArgs[maskArg]; ok && v != "" {
@ -513,16 +507,14 @@ func ValidateNetworking(c *kubeadm.ClusterConfiguration, fldPath *field.Path) fi
for _, err := range validation.IsDNS1123Subdomain(c.Networking.DNSDomain) { for _, err := range validation.IsDNS1123Subdomain(c.Networking.DNSDomain) {
allErrs = append(allErrs, field.Invalid(dnsDomainFldPath, c.Networking.DNSDomain, err)) allErrs = append(allErrs, field.Invalid(dnsDomainFldPath, c.Networking.DNSDomain, err))
} }
// check if dual-stack feature-gate is enabled
isDualStack := features.Enabled(c.FeatureGates, features.IPv6DualStack)
if len(c.Networking.ServiceSubnet) != 0 { if len(c.Networking.ServiceSubnet) != 0 {
allErrs = append(allErrs, ValidateIPNetFromString(c.Networking.ServiceSubnet, constants.MinimumAddressesInServiceSubnet, isDualStack, field.NewPath("serviceSubnet"))...) allErrs = append(allErrs, ValidateIPNetFromString(c.Networking.ServiceSubnet, constants.MinimumAddressesInServiceSubnet, field.NewPath("serviceSubnet"))...)
// Service subnet was already validated, we need to validate now the subnet size // Service subnet was already validated, we need to validate now the subnet size
allErrs = append(allErrs, ValidateServiceSubnetSize(c.Networking.ServiceSubnet, field.NewPath("serviceSubnet"))...) allErrs = append(allErrs, ValidateServiceSubnetSize(c.Networking.ServiceSubnet, field.NewPath("serviceSubnet"))...)
} }
if len(c.Networking.PodSubnet) != 0 { if len(c.Networking.PodSubnet) != 0 {
allErrs = append(allErrs, ValidateIPNetFromString(c.Networking.PodSubnet, constants.MinimumAddressesInPodSubnet, isDualStack, field.NewPath("podSubnet"))...) allErrs = append(allErrs, ValidateIPNetFromString(c.Networking.PodSubnet, constants.MinimumAddressesInPodSubnet, field.NewPath("podSubnet"))...)
if c.ControllerManager.ExtraArgs["allocate-node-cidrs"] != "false" { if c.ControllerManager.ExtraArgs["allocate-node-cidrs"] != "false" {
// Pod subnet was already validated, we need to validate now against the node-mask // Pod subnet was already validated, we need to validate now against the node-mask
allErrs = append(allErrs, ValidatePodSubnetNodeMask(c.Networking.PodSubnet, c, field.NewPath("podSubnet"))...) allErrs = append(allErrs, ValidatePodSubnetNodeMask(c.Networking.PodSubnet, c, field.NewPath("podSubnet"))...)

View File

@ -28,7 +28,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
) )
func TestValidateToken(t *testing.T) { func TestValidateToken(t *testing.T) {
@ -187,41 +186,28 @@ func TestValidateIPFromString(t *testing.T) {
func TestValidateIPNetFromString(t *testing.T) { func TestValidateIPNetFromString(t *testing.T) {
var tests = []struct { var tests = []struct {
name string name string
subnet string subnet string
minaddrs int64 minaddrs int64
checkDualStack bool expected bool
expected bool
}{ }{
{"invalid missing CIDR", "", 0, false, false},
{"invalid CIDR", "a", 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},
{"invalid multiple CIDR provided in a single stack cluster", "2001:db8::1/64,1.2.3.4/24", 0, false, false},
{"invalid multiple CIDR provided in a single stack cluster and one invalid subnet", "2001:db8::1/64,a", 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: // dual-stack:
{"invalid missing CIDR", "", 0, true, false}, {"invalid missing CIDR", "", 0, false},
{"valid dual-stack enabled but only an IPv4 CIDR specified", "10.0.0.16/12", 10, true, true}, {"valid dual-stack enabled but only an IPv4 CIDR specified", "10.0.0.16/12", 10, true},
{"valid dual-stack enabled but only an IPv6 CIDR specified", "2001:db8::/98", 10, true, true}, {"valid dual-stack enabled but only an IPv6 CIDR specified", "2001:db8::/98", 10, true},
{"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4,2001:db8::/98", 0, true, false}, {"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4,2001:db8::/98", 0, false},
{"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1,10.0.0.16/12", 0, true, false}, {"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1,10.0.0.16/12", 0, 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 IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29,2001:db8::/98", 10, 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 IPv6 CIDR too small. At least 10 addresses needed", "10.0.0.16/12,2001:db8::/125", 10, 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 IPv4 family addresses specified. IPv6 CIDR is necessary.", "10.0.0.16/12,192.168.0.0/16", 10, false},
{"valid, but only IPv6 family addresses specified. IPv4 CIDR is necessary.", "2001:db8::/98,2005:db8::/98", 10, true, false}, {"valid, but only IPv6 family addresses specified. IPv4 CIDR is necessary.", "2001:db8::/98,2005:db8::/98", 10, false},
{"valid IPv4 and IPv6 CIDR", "10.0.0.16/12,2001:db8::/98", 10, true, true}, {"valid IPv4 and IPv6 CIDR", "10.0.0.16/12,2001:db8::/98", 10, true},
{"valid IPv6 and IPv4 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},
{"invalid IPv6 and IPv4 CIDR with more than 2 subnets", "10.0.0.16/12,2001:db8::/98,192.168.0.0/16", 10, true, false}, {"invalid IPv6 and IPv4 CIDR with more than 2 subnets", "10.0.0.16/12,2001:db8::/98,192.168.0.0/16", 10, false},
{"invalid IPv6 and IPv4 CIDR with more than 2 subnets", "10.0.0.16/12,2001:db8::/98,192.168.0.0/16,a.b.c.d/24", 10, true, false}, {"invalid IPv6 and IPv4 CIDR with more than 2 subnets", "10.0.0.16/12,2001:db8::/98,192.168.0.0/16,a.b.c.d/24", 10, false},
} }
for _, rt := range tests { for _, rt := range tests {
actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, rt.checkDualStack, nil) actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, nil)
if (len(actual) == 0) != rt.expected { if (len(actual) == 0) != rt.expected {
t.Errorf( t.Errorf(
"%s test case failed :\n\texpected: %t\n\t actual: %t\n\t err(s): %v\n\t", "%s test case failed :\n\texpected: %t\n\t actual: %t\n\t err(s): %v\n\t",
@ -236,41 +222,31 @@ func TestValidateIPNetFromString(t *testing.T) {
func TestValidatePodSubnetNodeMask(t *testing.T) { func TestValidatePodSubnetNodeMask(t *testing.T) {
var tests = []struct { var tests = []struct {
name string name string
subnet string subnet string
cmExtraArgs map[string]string cmExtraArgs map[string]string
checkDualStack bool expected bool
expected bool
}{ }{
{"single IPv4, but mask too small. Default node-mask", "10.0.0.16/29", nil, false, false},
{"single IPv4, but mask too small. Configured node-mask", "10.0.0.16/24", map[string]string{"node-cidr-mask-size": "23"}, false, false},
{"single IPv6, but mask too small. Default node-mask", "2001:db8::1/112", nil, false, false},
{"single IPv6, but mask too small. Configured node-mask", "2001:db8::1/64", map[string]string{"node-cidr-mask-size": "24"}, false, false},
{"single IPv6, but mask difference greater than 16. Default node-mask", "2001:db8::1/12", nil, false, false},
{"single IPv6, but mask difference greater than 16. Configured node-mask", "2001:db8::1/64", map[string]string{"node-cidr-mask-size": "120"}, false, false},
{"single IPv4 CIDR", "10.0.0.16/12", nil, false, true},
{"single IPv6 CIDR", "2001:db8::/48", nil, false, true},
// dual-stack: // dual-stack:
{"dual IPv4 only, but mask too small. Default node-mask", "10.0.0.16/29", nil, true, false}, {"dual IPv4 only, but mask too small. Default node-mask", "10.0.0.16/29", nil, false},
{"dual IPv4 only, but mask too small. Configured node-mask", "10.0.0.16/24", map[string]string{"node-cidr-mask-size-ipv4": "23"}, true, false}, {"dual IPv4 only, but mask too small. Configured node-mask", "10.0.0.16/24", map[string]string{"node-cidr-mask-size-ipv4": "23"}, false},
{"dual IPv6 only, but mask too small. Default node-mask", "2001:db8::1/112", nil, true, false}, {"dual IPv6 only, but mask too small. Default node-mask", "2001:db8::1/112", nil, false},
{"dual IPv6 only, but mask too small. Configured node-mask", "2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "24"}, true, false}, {"dual IPv6 only, but mask too small. Configured node-mask", "2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "24"}, false},
{"dual IPv6 only, but mask difference greater than 16. Default node-mask", "2001:db8::1/12", nil, true, false}, {"dual IPv6 only, but mask difference greater than 16. Default node-mask", "2001:db8::1/12", nil, false},
{"dual IPv6 only, but mask difference greater than 16. Configured node-mask", "2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "120"}, true, false}, {"dual IPv6 only, but mask difference greater than 16. Configured node-mask", "2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "120"}, false},
{"dual IPv4 only CIDR", "10.0.0.16/12", nil, true, true}, {"dual IPv4 only CIDR", "10.0.0.16/12", nil, true},
{"dual IPv6 only CIDR", "2001:db8::/48", nil, true, true}, {"dual IPv6 only CIDR", "2001:db8::/48", nil, true},
{"dual, but IPv4 mask too small. Default node-mask", "10.0.0.16/29,2001:db8::/48", nil, true, false}, {"dual, but IPv4 mask too small. Default node-mask", "10.0.0.16/29,2001:db8::/48", nil, false},
{"dual, but IPv4 mask too small. Configured node-mask", "10.0.0.16/24,2001:db8::/48", map[string]string{"node-cidr-mask-size-ipv4": "23"}, true, false}, {"dual, but IPv4 mask too small. Configured node-mask", "10.0.0.16/24,2001:db8::/48", map[string]string{"node-cidr-mask-size-ipv4": "23"}, false},
{"dual, but IPv6 mask too small. Default node-mask", "2001:db8::1/112,10.0.0.16/16", nil, true, false}, {"dual, but IPv6 mask too small. Default node-mask", "2001:db8::1/112,10.0.0.16/16", nil, false},
{"dual, but IPv6 mask too small. Configured node-mask", "10.0.0.16/16,2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "24"}, true, false}, {"dual, but IPv6 mask too small. Configured node-mask", "10.0.0.16/16,2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "24"}, false},
{"dual, but mask difference greater than 16. Default node-mask", "2001:db8::1/12,10.0.0.16/16", nil, true, false}, {"dual, but mask difference greater than 16. Default node-mask", "2001:db8::1/12,10.0.0.16/16", nil, false},
{"dual, but mask difference greater than 16. Configured node-mask", "10.0.0.16/16,2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "120"}, true, false}, {"dual, but mask difference greater than 16. Configured node-mask", "10.0.0.16/16,2001:db8::1/64", map[string]string{"node-cidr-mask-size-ipv6": "120"}, false},
{"dual IPv4 IPv6", "2001:db8::/48,10.0.0.16/12", nil, true, true}, {"dual IPv4 IPv6", "2001:db8::/48,10.0.0.16/12", nil, true},
{"dual IPv6 IPv4", "2001:db8::/48,10.0.0.16/12", nil, true, true}, {"dual IPv6 IPv4", "2001:db8::/48,10.0.0.16/12", nil, true},
} }
for _, rt := range tests { for _, rt := range tests {
cfg := &kubeadmapi.ClusterConfiguration{ cfg := &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: rt.checkDualStack},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: rt.cmExtraArgs, ExtraArgs: rt.cmExtraArgs,
}, },
@ -1138,66 +1114,14 @@ func TestGetClusterNodeMask(t *testing.T) {
expectedError bool expectedError bool
}{ }{
{ {
name: "ipv4 default mask", name: "dual ipv4 default mask",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{},
FeatureGates: map[string]bool{features.IPv6DualStack: false},
},
isIPv6: false,
expectedMask: 24,
},
{
name: "ipv4 custom mask",
cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: false},
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "23"},
},
},
isIPv6: false,
expectedMask: 23,
},
{
name: "ipv4 wrong mask",
cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: false},
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "aa23"},
},
},
isIPv6: false,
expectedError: true,
},
{
name: "ipv6 default mask",
cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: false},
},
isIPv6: true,
expectedMask: 64,
},
{
name: "ipv6 custom mask",
cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: false},
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "83"},
},
},
isIPv6: true,
expectedMask: 83,
},
{
name: "dual ipv4 default mask",
cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
},
isIPv6: false, isIPv6: false,
expectedMask: 24, expectedMask: 24,
}, },
{ {
name: "dual ipv4 custom mask", name: "dual ipv4 custom mask",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "21", "node-cidr-mask-size-ipv4": "23"}, ExtraArgs: map[string]string{"node-cidr-mask-size": "21", "node-cidr-mask-size-ipv4": "23"},
}, },
@ -1206,17 +1130,14 @@ func TestGetClusterNodeMask(t *testing.T) {
expectedMask: 23, expectedMask: 23,
}, },
{ {
name: "dual ipv6 default mask", name: "dual ipv6 default mask",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{},
FeatureGates: map[string]bool{features.IPv6DualStack: true},
},
isIPv6: true, isIPv6: true,
expectedMask: 64, expectedMask: 64,
}, },
{ {
name: "dual ipv6 custom mask", name: "dual ipv6 custom mask",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size-ipv6": "83"}, ExtraArgs: map[string]string{"node-cidr-mask-size-ipv6": "83"},
}, },
@ -1227,7 +1148,6 @@ func TestGetClusterNodeMask(t *testing.T) {
{ {
name: "dual ipv4 custom mask", name: "dual ipv4 custom mask",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size-ipv4": "23"}, ExtraArgs: map[string]string{"node-cidr-mask-size-ipv4": "23"},
}, },
@ -1238,7 +1158,6 @@ func TestGetClusterNodeMask(t *testing.T) {
{ {
name: "dual ipv4 wrong mask", name: "dual ipv4 wrong mask",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size-ipv4": "aa"}, ExtraArgs: map[string]string{"node-cidr-mask-size-ipv4": "aa"},
}, },
@ -1249,7 +1168,6 @@ func TestGetClusterNodeMask(t *testing.T) {
{ {
name: "dual ipv6 default mask and legacy flag", name: "dual ipv6 default mask and legacy flag",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "23"}, ExtraArgs: map[string]string{"node-cidr-mask-size": "23"},
}, },
@ -1260,7 +1178,6 @@ func TestGetClusterNodeMask(t *testing.T) {
{ {
name: "dual ipv6 custom mask and legacy flag", name: "dual ipv6 custom mask and legacy flag",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "23", "node-cidr-mask-size-ipv6": "83"}, ExtraArgs: map[string]string{"node-cidr-mask-size": "23", "node-cidr-mask-size-ipv6": "83"},
}, },
@ -1271,7 +1188,6 @@ func TestGetClusterNodeMask(t *testing.T) {
{ {
name: "dual ipv6 custom mask and wrong flag", name: "dual ipv6 custom mask and wrong flag",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{features.IPv6DualStack: true},
ControllerManager: kubeadmapi.ControlPlaneComponent{ ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{"node-cidr-mask-size": "23", "node-cidr-mask-size-ipv6": "a83"}, ExtraArgs: map[string]string{"node-cidr-mask-size": "23", "node-cidr-mask-size-ipv6": "a83"},
}, },

View File

@ -525,7 +525,7 @@ func (d *initData) OutputWriter() io.Writer {
func (d *initData) Client() (clientset.Interface, error) { func (d *initData) Client() (clientset.Interface, error) {
if d.client == nil { if d.client == nil {
if d.dryRun { if d.dryRun {
svcSubnetCIDR, err := kubeadmconstants.GetKubernetesServiceCIDR(d.cfg.Networking.ServiceSubnet, features.Enabled(d.cfg.FeatureGates, features.IPv6DualStack)) svcSubnetCIDR, err := kubeadmconstants.GetKubernetesServiceCIDR(d.cfg.Networking.ServiceSubnet)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to get internal Kubernetes Service IP from the given service CIDR (%s)", d.cfg.Networking.ServiceSubnet) return nil, errors.Wrapf(err, "unable to get internal Kubernetes Service IP from the given service CIDR (%s)", d.cfg.Networking.ServiceSubnet)
} }

View File

@ -28,7 +28,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
"k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/util/initsystem" "k8s.io/kubernetes/cmd/kubeadm/app/util/initsystem"
) )
@ -117,12 +116,6 @@ func (kc *kubeletConfig) Default(cfg *kubeadmapi.ClusterConfiguration, _ *kubead
kc.config.FeatureGates = map[string]bool{} kc.config.FeatureGates = map[string]bool{}
} }
// TODO: The following code should be removed after dual-stack is GA.
// Note: The user still retains the ability to explicitly set feature-gates and that value will overwrite this base value.
if enabled, present := cfg.FeatureGates[features.IPv6DualStack]; present {
kc.config.FeatureGates[features.IPv6DualStack] = enabled
}
if kc.config.StaticPodPath == "" { if kc.config.StaticPodPath == "" {
kc.config.StaticPodPath = kubeadmapiv1.DefaultManifestsDir kc.config.StaticPodPath = kubeadmapiv1.DefaultManifestsDir
} else if kc.config.StaticPodPath != kubeadmapiv1.DefaultManifestsDir { } else if kc.config.StaticPodPath != kubeadmapiv1.DefaultManifestsDir {
@ -130,7 +123,7 @@ func (kc *kubeletConfig) Default(cfg *kubeadmapi.ClusterConfiguration, _ *kubead
} }
clusterDNS := "" clusterDNS := ""
dnsIP, err := constants.GetDNSIP(cfg.Networking.ServiceSubnet, features.Enabled(cfg.FeatureGates, features.IPv6DualStack)) dnsIP, err := constants.GetDNSIP(cfg.Networking.ServiceSubnet)
if err != nil { if err != nil {
clusterDNS = kubeadmapiv1.DefaultClusterDNSIP clusterDNS = kubeadmapiv1.DefaultClusterDNSIP
} else { } else {

View File

@ -34,7 +34,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
"k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
) )
func testKubeletConfigMap(contents string) *v1.ConfigMap { func testKubeletConfigMap(contents string) *v1.ConfigMap {
@ -125,60 +124,16 @@ func TestKubeletDefault(t *testing.T) {
}, },
}, },
}, },
{
name: "Service subnet, explicitly disabled dual stack defaulting works",
clusterCfg: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
features.IPv6DualStack: false,
},
Networking: kubeadmapi.Networking{
ServiceSubnet: "192.168.0.0/16",
},
},
expected: kubeletConfig{
config: kubeletconfig.KubeletConfiguration{
FeatureGates: map[string]bool{
features.IPv6DualStack: false,
},
StaticPodPath: kubeadmapiv1.DefaultManifestsDir,
ClusterDNS: []string{"192.168.0.10"},
Authentication: kubeletconfig.KubeletAuthentication{
X509: kubeletconfig.KubeletX509Authentication{
ClientCAFile: constants.CACertName,
},
Anonymous: kubeletconfig.KubeletAnonymousAuthentication{
Enabled: utilpointer.BoolPtr(kubeletAuthenticationAnonymousEnabled),
},
Webhook: kubeletconfig.KubeletWebhookAuthentication{
Enabled: utilpointer.BoolPtr(kubeletAuthenticationWebhookEnabled),
},
},
Authorization: kubeletconfig.KubeletAuthorization{
Mode: kubeletconfig.KubeletAuthorizationModeWebhook,
},
HealthzBindAddress: kubeletHealthzBindAddress,
HealthzPort: utilpointer.Int32Ptr(constants.KubeletHealthzPort),
RotateCertificates: kubeletRotateCertificates,
ResolverConfig: resolverConfig,
CgroupDriver: constants.CgroupDriverSystemd,
},
},
},
{ {
name: "Service subnet, enabled dual stack defaulting works", name: "Service subnet, enabled dual stack defaulting works",
clusterCfg: kubeadmapi.ClusterConfiguration{ clusterCfg: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
features.IPv6DualStack: true,
},
Networking: kubeadmapi.Networking{ Networking: kubeadmapi.Networking{
ServiceSubnet: "192.168.0.0/16", ServiceSubnet: "192.168.0.0/16",
}, },
}, },
expected: kubeletConfig{ expected: kubeletConfig{
config: kubeletconfig.KubeletConfiguration{ config: kubeletconfig.KubeletConfiguration{
FeatureGates: map[string]bool{ FeatureGates: map[string]bool{},
features.IPv6DualStack: true,
},
StaticPodPath: kubeadmapiv1.DefaultManifestsDir, StaticPodPath: kubeadmapiv1.DefaultManifestsDir,
ClusterDNS: []string{"192.168.0.10"}, ClusterDNS: []string{"192.168.0.10"},
Authentication: kubeletconfig.KubeletAuthentication{ Authentication: kubeletconfig.KubeletAuthentication{

View File

@ -24,7 +24,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
) )
const ( const (
@ -118,10 +117,4 @@ func (kp *kubeProxyConfig) Default(cfg *kubeadmapi.ClusterConfiguration, localAP
} else if kp.config.ClientConnection.Kubeconfig != kubeproxyKubeConfigFileName { } else if kp.config.ClientConnection.Kubeconfig != kubeproxyKubeConfigFileName {
warnDefaultComponentConfigValue(kind, "clientConnection.kubeconfig", kubeproxyKubeConfigFileName, kp.config.ClientConnection.Kubeconfig) warnDefaultComponentConfigValue(kind, "clientConnection.kubeconfig", kubeproxyKubeConfigFileName, kp.config.ClientConnection.Kubeconfig)
} }
// TODO: The following code should be removed after dual-stack is GA.
// Note: The user still retains the ability to explicitly set feature-gates and that value will overwrite this base value.
if enabled, present := cfg.FeatureGates[features.IPv6DualStack]; present {
kp.config.FeatureGates[features.IPv6DualStack] = enabled
}
} }

View File

@ -33,7 +33,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
"k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
) )
func testKubeProxyConfigMap(contents string) *v1.ConfigMap { func testKubeProxyConfigMap(contents string) *v1.ConfigMap {
@ -104,46 +103,6 @@ func TestKubeProxyDefault(t *testing.T) {
}, },
}, },
}, },
{
name: "IPv6DualStack feature gate set to true",
clusterCfg: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
features.IPv6DualStack: true,
},
},
endpoint: kubeadmapi.APIEndpoint{},
expected: kubeProxyConfig{
config: kubeproxyconfig.KubeProxyConfiguration{
FeatureGates: map[string]bool{
features.IPv6DualStack: true,
},
BindAddress: kubeadmapiv1.DefaultProxyBindAddressv6,
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
Kubeconfig: kubeproxyKubeConfigFileName,
},
},
},
},
{
name: "IPv6DualStack feature gate set to false",
clusterCfg: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
features.IPv6DualStack: false,
},
},
endpoint: kubeadmapi.APIEndpoint{},
expected: kubeProxyConfig{
config: kubeproxyconfig.KubeProxyConfiguration{
FeatureGates: map[string]bool{
features.IPv6DualStack: false,
},
BindAddress: kubeadmapiv1.DefaultProxyBindAddressv6,
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
Kubeconfig: kubeproxyKubeConfigFileName,
},
},
},
},
} }
for _, test := range tests { for _, test := range tests {

View File

@ -627,9 +627,9 @@ func CreateTimestampDirForKubeadm(kubernetesDir, dirName string) (string, error)
} }
// GetDNSIP returns a dnsIP, which is 10th IP in svcSubnet CIDR range // GetDNSIP returns a dnsIP, which is 10th IP in svcSubnet CIDR range
func GetDNSIP(svcSubnetList string, isDualStack bool) (net.IP, error) { func GetDNSIP(svcSubnetList string) (net.IP, error) {
// Get the service subnet CIDR // Get the service subnet CIDR
svcSubnetCIDR, err := GetKubernetesServiceCIDR(svcSubnetList, isDualStack) svcSubnetCIDR, err := GetKubernetesServiceCIDR(svcSubnetList)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to get internal Kubernetes Service IP from the given service CIDR (%s)", svcSubnetList) return nil, errors.Wrapf(err, "unable to get internal Kubernetes Service IP from the given service CIDR (%s)", svcSubnetList)
} }
@ -644,31 +644,23 @@ func GetDNSIP(svcSubnetList string, isDualStack bool) (net.IP, error) {
} }
// GetKubernetesServiceCIDR returns the default Service CIDR for the Kubernetes internal service // GetKubernetesServiceCIDR returns the default Service CIDR for the Kubernetes internal service
func GetKubernetesServiceCIDR(svcSubnetList string, isDualStack bool) (*net.IPNet, error) { func GetKubernetesServiceCIDR(svcSubnetList string) (*net.IPNet, error) {
if isDualStack { // The default service address family for the cluster is the address family of the first
// The default service address family for the cluster is the address family of the first // service cluster IP range configured via the `--service-cluster-ip-range` flag
// service cluster IP range configured via the `--service-cluster-ip-range` flag // of the kube-controller-manager and kube-apiserver.
// of the kube-controller-manager and kube-apiserver. svcSubnets, err := netutils.ParseCIDRs(strings.Split(svcSubnetList, ","))
svcSubnets, err := netutils.ParseCIDRs(strings.Split(svcSubnetList, ","))
if err != nil {
return nil, errors.Wrapf(err, "unable to parse ServiceSubnet %v", svcSubnetList)
}
if len(svcSubnets) == 0 {
return nil, errors.New("received empty ServiceSubnet for dual-stack")
}
return svcSubnets[0], nil
}
// internal IP address for the API server
_, svcSubnet, err := netutils.ParseCIDRSloppy(svcSubnetList)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to parse ServiceSubnet %v", svcSubnetList) return nil, errors.Wrapf(err, "unable to parse ServiceSubnet %v", svcSubnetList)
} }
return svcSubnet, nil if len(svcSubnets) == 0 {
return nil, errors.New("received empty ServiceSubnet")
}
return svcSubnets[0], nil
} }
// GetAPIServerVirtualIP returns the IP of the internal Kubernetes API service // GetAPIServerVirtualIP returns the IP of the internal Kubernetes API service
func GetAPIServerVirtualIP(svcSubnetList string, isDualStack bool) (net.IP, error) { func GetAPIServerVirtualIP(svcSubnetList string) (net.IP, error) {
svcSubnet, err := GetKubernetesServiceCIDR(svcSubnetList, isDualStack) svcSubnet, err := GetKubernetesServiceCIDR(svcSubnetList)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "unable to get internal Kubernetes Service IP from the given service CIDR") return nil, errors.Wrap(err, "unable to get internal Kubernetes Service IP from the given service CIDR")
} }

View File

@ -182,35 +182,30 @@ func TestGetKubernetesServiceCIDR(t *testing.T) {
}{ }{
{ {
svcSubnetList: "192.168.10.0/24", svcSubnetList: "192.168.10.0/24",
isDualStack: false,
expected: "192.168.10.0/24", expected: "192.168.10.0/24",
expectedError: false, expectedError: false,
name: "valid: valid IPv4 range from single-stack", name: "valid: valid IPv4 range from single-stack",
}, },
{ {
svcSubnetList: "fd03::/112", svcSubnetList: "fd03::/112",
isDualStack: false,
expected: "fd03::/112", expected: "fd03::/112",
expectedError: false, expectedError: false,
name: "valid: valid IPv6 range from single-stack", name: "valid: valid IPv6 range from single-stack",
}, },
{ {
svcSubnetList: "192.168.10.0/24,fd03::/112", svcSubnetList: "192.168.10.0/24,fd03::/112",
isDualStack: true,
expected: "192.168.10.0/24", expected: "192.168.10.0/24",
expectedError: false, expectedError: false,
name: "valid: valid <IPv4,IPv6> ranges from dual-stack", name: "valid: valid <IPv4,IPv6> ranges from dual-stack",
}, },
{ {
svcSubnetList: "fd03::/112,192.168.10.0/24", svcSubnetList: "fd03::/112,192.168.10.0/24",
isDualStack: true,
expected: "fd03::/112", expected: "fd03::/112",
expectedError: false, expectedError: false,
name: "valid: valid <IPv6,IPv4> ranges from dual-stack", name: "valid: valid <IPv6,IPv4> ranges from dual-stack",
}, },
{ {
svcSubnetList: "192.168.10.0/24,fd03:x::/112", svcSubnetList: "192.168.10.0/24,fd03:x::/112",
isDualStack: true,
expected: "", expected: "",
expectedError: true, expectedError: true,
name: "invalid: failed to parse subnet range for dual-stack", name: "invalid: failed to parse subnet range for dual-stack",
@ -219,7 +214,7 @@ func TestGetKubernetesServiceCIDR(t *testing.T) {
for _, rt := range tests { for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) { t.Run(rt.name, func(t *testing.T) {
actual, actualError := GetKubernetesServiceCIDR(rt.svcSubnetList, rt.isDualStack) actual, actualError := GetKubernetesServiceCIDR(rt.svcSubnetList)
if rt.expectedError { if rt.expectedError {
if actualError == nil { if actualError == nil {
t.Errorf("failed GetKubernetesServiceCIDR:\n\texpected error, but got no error") t.Errorf("failed GetKubernetesServiceCIDR:\n\texpected error, but got no error")

View File

@ -37,7 +37,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/images" "k8s.io/kubernetes/cmd/kubeadm/app/images"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
@ -120,7 +119,7 @@ func coreDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interfa
return errors.Wrap(err, "error when parsing CoreDNS configMap template") return errors.Wrap(err, "error when parsing CoreDNS configMap template")
} }
dnsip, err := kubeadmconstants.GetDNSIP(cfg.Networking.ServiceSubnet, features.Enabled(cfg.FeatureGates, features.IPv6DualStack)) dnsip, err := kubeadmconstants.GetDNSIP(cfg.Networking.ServiceSubnet)
if err != nil { if err != nil {
return err return err
} }

View File

@ -80,30 +80,26 @@ func TestGetDNSIP(t *testing.T) {
name: "subnet mask 12", name: "subnet mask 12",
svcSubnet: "10.96.0.0/12", svcSubnet: "10.96.0.0/12",
expectedDNSIP: "10.96.0.10", expectedDNSIP: "10.96.0.10",
isDualStack: false,
}, },
{ {
name: "subnet mask 26", name: "subnet mask 26",
svcSubnet: "10.87.116.64/26", svcSubnet: "10.87.116.64/26",
expectedDNSIP: "10.87.116.74", expectedDNSIP: "10.87.116.74",
isDualStack: false,
}, },
{ {
name: "dual-stack ipv4 primary, subnet mask 26", name: "dual-stack ipv4 primary, subnet mask 26",
svcSubnet: "10.87.116.64/26,fd03::/112", svcSubnet: "10.87.116.64/26,fd03::/112",
expectedDNSIP: "10.87.116.74", expectedDNSIP: "10.87.116.74",
isDualStack: true,
}, },
{ {
name: "dual-stack ipv6 primary, subnet mask 112", name: "dual-stack ipv6 primary, subnet mask 112",
svcSubnet: "fd03::/112,10.87.116.64/26", svcSubnet: "fd03::/112,10.87.116.64/26",
expectedDNSIP: "fd03::a", expectedDNSIP: "fd03::a",
isDualStack: true,
}, },
} }
for _, rt := range tests { for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) { t.Run(rt.name, func(t *testing.T) {
dnsIP, err := kubeadmconstants.GetDNSIP(rt.svcSubnet, rt.isDualStack) dnsIP, err := kubeadmconstants.GetDNSIP(rt.svcSubnet)
if err != nil { if err != nil {
t.Fatalf("couldn't get dnsIP : %v", err) t.Fatalf("couldn't get dnsIP : %v", err)
} }

View File

@ -220,12 +220,6 @@ func getAPIServerCommand(cfg *kubeadmapi.ClusterConfiguration, localAPIEndpoint
} }
} }
// TODO: The following code should be removed after dual-stack is GA.
// Note: The user still retains the ability to explicitly set feature-gates and that value will overwrite this base value.
if enabled, present := cfg.FeatureGates[features.IPv6DualStack]; present {
defaultArguments["feature-gates"] = fmt.Sprintf("%s=%t", features.IPv6DualStack, enabled)
}
if cfg.APIServer.ExtraArgs == nil { if cfg.APIServer.ExtraArgs == nil {
cfg.APIServer.ExtraArgs = map[string]string{} cfg.APIServer.ExtraArgs = map[string]string{}
} }
@ -343,13 +337,6 @@ func getControllerManagerCommand(cfg *kubeadmapi.ClusterConfiguration) []string
defaultArguments["cluster-name"] = cfg.ClusterName defaultArguments["cluster-name"] = cfg.ClusterName
} }
// TODO: The following code should be remvoved after dual-stack is GA.
// Note: The user still retains the ability to explicitly set feature-gates and that value will overwrite this base value.
enabled, present := cfg.FeatureGates[features.IPv6DualStack]
if present {
defaultArguments["feature-gates"] = fmt.Sprintf("%s=%t", features.IPv6DualStack, enabled)
}
command := []string{"kube-controller-manager"} command := []string{"kube-controller-manager"}
command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.ControllerManager.ExtraArgs)...) command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.ControllerManager.ExtraArgs)...)
@ -367,12 +354,6 @@ func getSchedulerCommand(cfg *kubeadmapi.ClusterConfiguration) []string {
"authorization-kubeconfig": kubeconfigFile, "authorization-kubeconfig": kubeconfigFile,
} }
// TODO: The following code should be remvoved after dual-stack is GA.
// Note: The user still retains the ability to explicitly set feature-gates and that value will overwrite this base value.
if enabled, present := cfg.FeatureGates[features.IPv6DualStack]; present {
defaultArguments["feature-gates"] = fmt.Sprintf("%s=%t", features.IPv6DualStack, enabled)
}
command := []string{"kube-scheduler"} command := []string{"kube-scheduler"}
command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.Scheduler.ExtraArgs)...) command = append(command, kubeadmutil.BuildArgumentListFromMap(defaultArguments, cfg.Scheduler.ExtraArgs)...)
return command return command

View File

@ -32,7 +32,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
pkiutiltesting "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil/testing" pkiutiltesting "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil/testing"
staticpodutil "k8s.io/kubernetes/cmd/kubeadm/app/util/staticpod" staticpodutil "k8s.io/kubernetes/cmd/kubeadm/app/util/staticpod"
@ -546,7 +545,6 @@ func TestGetControllerManagerCommand(t *testing.T) {
KubernetesVersion: cpVersion, KubernetesVersion: cpVersion,
CertificatesDir: testCertsDir, CertificatesDir: testCertsDir,
ClusterName: "some-other-cluster-name", ClusterName: "some-other-cluster-name",
FeatureGates: map[string]bool{features.IPv6DualStack: false},
}, },
expected: []string{ expected: []string{
"kube-controller-manager", "kube-controller-manager",
@ -563,7 +561,6 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--authorization-kubeconfig=" + kubeadmconstants.KubernetesDir + "/controller-manager.conf", "--authorization-kubeconfig=" + kubeadmconstants.KubernetesDir + "/controller-manager.conf",
"--client-ca-file=" + testCertsDir + "/ca.crt", "--client-ca-file=" + testCertsDir + "/ca.crt",
"--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt", "--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt",
"--feature-gates=IPv6DualStack=false",
"--cluster-name=some-other-cluster-name", "--cluster-name=some-other-cluster-name",
}, },
}, },
@ -626,7 +623,6 @@ func TestGetControllerManagerCommand(t *testing.T) {
}, },
CertificatesDir: testCertsDir, CertificatesDir: testCertsDir,
KubernetesVersion: cpVersion, KubernetesVersion: cpVersion,
FeatureGates: map[string]bool{features.IPv6DualStack: false},
}, },
expected: []string{ expected: []string{
"kube-controller-manager", "kube-controller-manager",
@ -643,7 +639,6 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--authorization-kubeconfig=" + kubeadmconstants.KubernetesDir + "/controller-manager.conf", "--authorization-kubeconfig=" + kubeadmconstants.KubernetesDir + "/controller-manager.conf",
"--client-ca-file=" + testCertsDir + "/ca.crt", "--client-ca-file=" + testCertsDir + "/ca.crt",
"--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt", "--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt",
"--feature-gates=IPv6DualStack=false",
"--allocate-node-cidrs=true", "--allocate-node-cidrs=true",
"--cluster-cidr=10.0.1.15/16", "--cluster-cidr=10.0.1.15/16",
"--service-cluster-ip-range=172.20.0.0/24", "--service-cluster-ip-range=172.20.0.0/24",
@ -755,7 +750,6 @@ func TestGetControllerManagerCommand(t *testing.T) {
}, },
CertificatesDir: testCertsDir, CertificatesDir: testCertsDir,
KubernetesVersion: cpVersion, KubernetesVersion: cpVersion,
FeatureGates: map[string]bool{features.IPv6DualStack: true},
}, },
expected: []string{ expected: []string{
"kube-controller-manager", "kube-controller-manager",
@ -772,7 +766,6 @@ func TestGetControllerManagerCommand(t *testing.T) {
"--authorization-kubeconfig=" + kubeadmconstants.KubernetesDir + "/controller-manager.conf", "--authorization-kubeconfig=" + kubeadmconstants.KubernetesDir + "/controller-manager.conf",
"--client-ca-file=" + testCertsDir + "/ca.crt", "--client-ca-file=" + testCertsDir + "/ca.crt",
"--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt", "--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt",
"--feature-gates=IPv6DualStack=true",
"--allocate-node-cidrs=true", "--allocate-node-cidrs=true",
"--cluster-cidr=2001:db8::/64,10.1.0.0/16", "--cluster-cidr=2001:db8::/64,10.1.0.0/16",
"--service-cluster-ip-range=fd03::/112,192.168.0.0/16", "--service-cluster-ip-range=fd03::/112,192.168.0.0/16",

View File

@ -45,7 +45,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
) )
@ -424,7 +423,7 @@ func GetAPIServerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames
cfg.LocalAPIEndpoint.AdvertiseAddress) cfg.LocalAPIEndpoint.AdvertiseAddress)
} }
internalAPIServerVirtualIP, err := kubeadmconstants.GetAPIServerVirtualIP(cfg.Networking.ServiceSubnet, features.Enabled(cfg.FeatureGates, features.IPv6DualStack)) internalAPIServerVirtualIP, err := kubeadmconstants.GetAPIServerVirtualIP(cfg.Networking.ServiceSubnet)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to get first IP address from the given CIDR: %v", cfg.Networking.ServiceSubnet) return nil, errors.Wrapf(err, "unable to get first IP address from the given CIDR: %v", cfg.Networking.ServiceSubnet)
} }

View File

@ -265,8 +265,8 @@ func TestCmdInitFeatureGates(t *testing.T) {
args: "", args: "",
}, },
{ {
name: "feature gate IPv6DualStack=false", name: "feature gate IPv6DualStack=true",
args: "--feature-gates=IPv6DualStack=false", args: "--feature-gates=IPv6DualStack=true",
}, },
{ {
name: "feature gate PublicKeysECDSA=true", name: "feature gate PublicKeysECDSA=true",