mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 15:58:37 +00:00
kubeadM: allow conversion of TimeoutForControlPlane
v1beta3.ClusterConfiguration.APIServer.TimeoutForControlPlane must be migrated to {Init|Join}Configuration.Timeouts. .ControlPlaneComponentHealthCheck. To achieve this sort of cross-Kind migration do the following: - Use a temporary, thread-safe variable in timeoututils.go - Make the order of GVKs in documentMapToInitConfiguration deterministic.
This commit is contained in:
parent
4af99cd676
commit
09078d4810
@ -89,9 +89,7 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue
|
||||
obj.CIImageRepository = "" // This fields doesn't exists in public API >> using default to get the roundtrip test pass
|
||||
obj.KubernetesVersion = "qux"
|
||||
obj.CIKubernetesVersion = "" // This fields doesn't exists in public API >> using default to get the roundtrip test pass
|
||||
obj.APIServer.TimeoutForControlPlane = &metav1.Duration{
|
||||
Duration: 0,
|
||||
}
|
||||
obj.APIServer.TimeoutForControlPlane = &metav1.Duration{}
|
||||
obj.ControllerManager.ExtraEnvs = nil
|
||||
obj.APIServer.ExtraEnvs = nil
|
||||
obj.Scheduler.ExtraEnvs = nil
|
||||
|
@ -39,6 +39,12 @@ func SetDefaultTimeouts(t **Timeouts) {
|
||||
var (
|
||||
activeTimeouts *Timeouts = nil
|
||||
timeoutMutex = &sync.RWMutex{}
|
||||
|
||||
// conversionTimeoutControlPlane is a variable used when converting the v1beta3 field
|
||||
// ClusterConfiguration.APIServer.TimeoutForControlPlane to
|
||||
// v1beta4 {Init|Join}Configuration.Timeouts.ControlPlaneComponentHealthCheck.
|
||||
// TODO: remove this once v1beta3 is removed.
|
||||
conversionTimeoutControlPlane *metav1.Duration
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -58,3 +64,19 @@ func SetActiveTimeouts(timeouts *Timeouts) {
|
||||
activeTimeouts = timeouts.DeepCopy()
|
||||
timeoutMutex.Unlock()
|
||||
}
|
||||
|
||||
// TODO: remove these once v1beta3 is removed
|
||||
|
||||
// GetConversionTimeoutControlPlane returns conversionTimeoutControlPlane.
|
||||
func GetConversionTimeoutControlPlane() *metav1.Duration {
|
||||
timeoutMutex.RLock()
|
||||
defer timeoutMutex.RUnlock()
|
||||
return conversionTimeoutControlPlane
|
||||
}
|
||||
|
||||
// SetConversionTimeoutControlPlane stores t into conversionTimeoutControlPlane.
|
||||
func SetConversionTimeoutControlPlane(t *metav1.Duration) {
|
||||
timeoutMutex.Lock()
|
||||
conversionTimeoutControlPlane = t.DeepCopy()
|
||||
timeoutMutex.Unlock()
|
||||
}
|
||||
|
@ -77,6 +77,9 @@ func Convert_v1beta3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *Cl
|
||||
out.EncryptionAlgorithm = kubeadm.EncryptionAlgorithmRSA2048
|
||||
out.CertificateValidityPeriod = &metav1.Duration{Duration: constants.CertificateValidityPeriod}
|
||||
out.CACertificateValidityPeriod = &metav1.Duration{Duration: constants.CACertificateValidityPeriod}
|
||||
if in.APIServer.TimeoutForControlPlane != nil && in.APIServer.TimeoutForControlPlane.Duration != 0 {
|
||||
kubeadm.SetConversionTimeoutControlPlane(in.APIServer.TimeoutForControlPlane)
|
||||
}
|
||||
return autoConvert_v1beta3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,12 @@ import (
|
||||
|
||||
// Convert_kubeadm_InitConfiguration_To_v1beta4_InitConfiguration converts a private InitConfiguration to a public InitConfiguration.
|
||||
func Convert_kubeadm_InitConfiguration_To_v1beta4_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_InitConfiguration_To_v1beta4_InitConfiguration(in, out, s)
|
||||
err := autoConvert_kubeadm_InitConfiguration_To_v1beta4_InitConfiguration(in, out, s)
|
||||
timeoutControlPlane := kubeadm.GetConversionTimeoutControlPlane() // Remove with v1beta3.
|
||||
if timeoutControlPlane != nil {
|
||||
out.Timeouts.ControlPlaneComponentHealthCheck = timeoutControlPlane
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert_v1beta4_InitConfiguration_To_kubeadm_InitConfiguration converts a public InitConfiguration to a private InitConfiguration.
|
||||
@ -46,8 +51,9 @@ func Convert_kubeadm_APIServer_To_v1beta4_APIServer(in *kubeadm.APIServer, out *
|
||||
|
||||
// Convert_v1beta4_ClusterConfiguration_To_kubeadm_ClusterConfiguration is required due to missing TimeoutForControlPlane in v1beta4
|
||||
func Convert_v1beta4_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error {
|
||||
err := autoConvert_v1beta4_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s)
|
||||
out.APIServer.TimeoutForControlPlane = &metav1.Duration{}
|
||||
return autoConvert_v1beta4_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert_v1beta4_JoinConfiguration_To_kubeadm_JoinConfiguration converts a public JoinConfiguration to a private JoinConfiguration.
|
||||
@ -57,6 +63,16 @@ func Convert_v1beta4_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConf
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration converts a private JoinConfinguration to a public JoinCOnfiguration.
|
||||
func Convert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration(in *kubeadm.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error {
|
||||
err := autoConvert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration(in, out, s)
|
||||
timeoutControlPlane := kubeadm.GetConversionTimeoutControlPlane() // Remove with v1beta3.
|
||||
if timeoutControlPlane != nil {
|
||||
out.Timeouts.ControlPlaneComponentHealthCheck = timeoutControlPlane
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert_kubeadm_Discovery_To_v1beta4_Discovery is required because there is no Discovery.Timeout in v1beta4
|
||||
func Convert_kubeadm_Discovery_To_v1beta4_Discovery(in *kubeadm.Discovery, out *Discovery, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_Discovery_To_v1beta4_Discovery(in, out, s)
|
||||
|
@ -159,11 +159,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*kubeadm.JoinConfiguration)(nil), (*JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration(a.(*kubeadm.JoinConfiguration), b.(*JoinConfiguration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*JoinControlPlane)(nil), (*kubeadm.JoinControlPlane)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta4_JoinControlPlane_To_kubeadm_JoinControlPlane(a.(*JoinControlPlane), b.(*kubeadm.JoinControlPlane), scope)
|
||||
}); err != nil {
|
||||
@ -309,6 +304,11 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*kubeadm.JoinConfiguration)(nil), (*JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration(a.(*kubeadm.JoinConfiguration), b.(*JoinConfiguration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*ClusterConfiguration)(nil), (*kubeadm.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta4_ClusterConfiguration_To_kubeadm_ClusterConfiguration(a.(*ClusterConfiguration), b.(*kubeadm.ClusterConfiguration), scope)
|
||||
}); err != nil {
|
||||
@ -768,11 +768,6 @@ func autoConvert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration(in *kube
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration is an autogenerated conversion function.
|
||||
func Convert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration(in *kubeadm.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_JoinConfiguration_To_v1beta4_JoinConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta4_JoinControlPlane_To_kubeadm_JoinControlPlane(in *JoinControlPlane, out *kubeadm.JoinControlPlane, s conversion.Scope) error {
|
||||
if err := Convert_v1beta4_APIEndpoint_To_kubeadm_APIEndpoint(&in.LocalAPIEndpoint, &out.LocalAPIEndpoint, s); err != nil {
|
||||
return err
|
||||
|
@ -441,11 +441,11 @@ func TestMigrateOldConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test the migration of extra args from v1beta3 to v1beta4, as this is the only breaking change that is migrated.
|
||||
// Another breaking change is the removal of ClusterConfiguration.TimeoutForControlPlane, but this field is not
|
||||
// migrated to InitConfiguration.Timeouts.ControlPlaneComponentHealthCheck due to API machinery limitations.
|
||||
// Remove this test once v1beta3 is removed.
|
||||
func TestMigrateV1Beta3ExtraArgs(t *testing.T) {
|
||||
// Test the migration of all breaking changes in v1beta4, marked as "MIGRATED" in the YAML below:
|
||||
// - ExtraArgs
|
||||
// - ClusterConfiguration.APIServer.TimeoutForControlPlane -> {Init|Join}Configuration.Timeout.ControlPlaneComponentHealthCheck
|
||||
// - JoinConfiguration.Discovery.Timeout -> JoinConfiguration.Timeout.Discovery
|
||||
func TestMigrateV1Beta3WithBreakingChanges(t *testing.T) {
|
||||
var (
|
||||
gv = kubeadmapiv1old.SchemeGroupVersion.String()
|
||||
gvNew = kubeadmapiv1.SchemeGroupVersion.String()
|
||||
@ -465,27 +465,45 @@ func TestMigrateV1Beta3ExtraArgs(t *testing.T) {
|
||||
advertiseAddress: 1.2.3.4
|
||||
bindPort: 6443
|
||||
nodeRegistration:
|
||||
criSocket: unix:///var/run/containerd/containerd.sock
|
||||
kubeletExtraArgs:
|
||||
criSocket: unix:///some-socket-path
|
||||
kubeletExtraArgs: # MIGRATED
|
||||
foo: bar
|
||||
name: node
|
||||
---
|
||||
apiServer:
|
||||
timeoutForControlPlane: 2m0s ### note: this is note migrated!
|
||||
extraArgs:
|
||||
timeoutForControlPlane: 2m32s # MIGRATED
|
||||
extraArgs: # MIGRATED
|
||||
foo: bar
|
||||
apiVersion: %[1]s
|
||||
controllerManager:
|
||||
extraArgs:
|
||||
extraArgs: # MIGRATED
|
||||
foo: bar
|
||||
etcd:
|
||||
local:
|
||||
extraArgs:
|
||||
extraArgs: # MIGRATED
|
||||
foo: bar
|
||||
kind: ClusterConfiguration
|
||||
kubernetesVersion: v1.10.0
|
||||
scheduler:
|
||||
extraArgs:
|
||||
extraArgs: # MIGRATED
|
||||
foo: bar
|
||||
---
|
||||
apiVersion: %[1]s
|
||||
kind: JoinConfiguration
|
||||
nodeRegistration:
|
||||
criSocket: unix:///some-socket-path
|
||||
imagePullPolicy: IfNotPresent
|
||||
kubeletExtraArgs: # MIGRATED
|
||||
foo: baz
|
||||
name: foo
|
||||
taints: null
|
||||
discovery:
|
||||
bootstrapToken:
|
||||
apiServerEndpoint: some-address:6443
|
||||
token: abcdef.0123456789abcdef
|
||||
unsafeSkipCAVerification: true
|
||||
tlsBootstrapToken: abcdef.0123456789abcdef
|
||||
timeout: 2m10s # MIGRATED
|
||||
`, gv))
|
||||
|
||||
expectedOutput = dedent.Dedent(fmt.Sprintf(`
|
||||
@ -503,7 +521,7 @@ func TestMigrateV1Beta3ExtraArgs(t *testing.T) {
|
||||
advertiseAddress: 1.2.3.4
|
||||
bindPort: 6443
|
||||
nodeRegistration:
|
||||
criSocket: unix:///var/run/containerd/containerd.sock
|
||||
criSocket: unix:///some-socket-path
|
||||
imagePullPolicy: IfNotPresent
|
||||
imagePullSerial: true
|
||||
kubeletExtraArgs:
|
||||
@ -514,7 +532,7 @@ func TestMigrateV1Beta3ExtraArgs(t *testing.T) {
|
||||
- effect: NoSchedule
|
||||
key: node-role.kubernetes.io/control-plane
|
||||
timeouts:
|
||||
controlPlaneComponentHealthCheck: 4m0s
|
||||
controlPlaneComponentHealthCheck: 2m32s
|
||||
discovery: 5m0s
|
||||
etcdAPICall: 2m0s
|
||||
kubeletHealthCheck: 4m0s
|
||||
@ -545,7 +563,7 @@ func TestMigrateV1Beta3ExtraArgs(t *testing.T) {
|
||||
value: bar
|
||||
imageRepository: registry.k8s.io
|
||||
kind: ClusterConfiguration
|
||||
kubernetesVersion: v1.30.1
|
||||
kubernetesVersion: v1.10.0
|
||||
networking:
|
||||
dnsDomain: cluster.local
|
||||
serviceSubnet: 10.96.0.0/12
|
||||
@ -554,6 +572,33 @@ func TestMigrateV1Beta3ExtraArgs(t *testing.T) {
|
||||
extraArgs:
|
||||
- name: foo
|
||||
value: bar
|
||||
---
|
||||
apiVersion: %[1]s
|
||||
caCertPath: /etc/kubernetes/pki/ca.crt
|
||||
discovery:
|
||||
bootstrapToken:
|
||||
apiServerEndpoint: some-address:6443
|
||||
token: abcdef.0123456789abcdef
|
||||
unsafeSkipCAVerification: true
|
||||
tlsBootstrapToken: abcdef.0123456789abcdef
|
||||
kind: JoinConfiguration
|
||||
nodeRegistration:
|
||||
criSocket: unix:///some-socket-path
|
||||
imagePullPolicy: IfNotPresent
|
||||
imagePullSerial: true
|
||||
kubeletExtraArgs:
|
||||
- name: foo
|
||||
value: baz
|
||||
name: foo
|
||||
taints: null
|
||||
timeouts:
|
||||
controlPlaneComponentHealthCheck: 2m32s
|
||||
discovery: 2m10s
|
||||
etcdAPICall: 2m0s
|
||||
kubeletHealthCheck: 4m0s
|
||||
kubernetesAPICall: 1m0s
|
||||
tlsBootstrap: 5m0s
|
||||
upgradeManifests: 5m0s
|
||||
`, gvNew))
|
||||
)
|
||||
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"bytes"
|
||||
"net"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -307,7 +308,19 @@ func documentMapToInitConfiguration(gvkmap kubeadmapi.DocumentMap, allowDeprecat
|
||||
var initcfg *kubeadmapi.InitConfiguration
|
||||
var clustercfg *kubeadmapi.ClusterConfiguration
|
||||
|
||||
for gvk, fileContent := range gvkmap {
|
||||
// Sort the GVKs deterministically by GVK string.
|
||||
// This allows ClusterConfiguration to be decoded first.
|
||||
gvks := make([]schema.GroupVersionKind, 0, len(gvkmap))
|
||||
for gvk := range gvkmap {
|
||||
gvks = append(gvks, gvk)
|
||||
}
|
||||
sort.Slice(gvks, func(i, j int) bool {
|
||||
return gvks[i].String() < gvks[j].String()
|
||||
})
|
||||
|
||||
for _, gvk := range gvks {
|
||||
fileContent := gvkmap[gvk]
|
||||
|
||||
// first, check if this GVK is supported and possibly not deprecated
|
||||
if err := validateSupportedVersion(gvk.GroupVersion(), allowDeprecated, allowExperimental); err != nil {
|
||||
return nil, err
|
||||
|
Loading…
Reference in New Issue
Block a user