kubeadm: fix upgrade to be able to rollback ControlPlaneLocalMode

This commit is contained in:
Christian Schlotter 2025-02-04 08:51:26 +01:00
parent bb36212342
commit 20fbdeac96
No known key found for this signature in database
GPG Key ID: 0E487122453EB0AC
3 changed files with 27 additions and 22 deletions

View File

@ -24,7 +24,6 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
) )
@ -53,13 +52,11 @@ func runKubeconfig() func(c workflow.RunData) error {
cfg := data.InitCfg() cfg := data.InitCfg()
if features.Enabled(cfg.FeatureGates, features.ControlPlaneKubeletLocalMode) { if err := upgrade.UpdateKubeletKubeconfigServer(cfg, data.DryRun()); err != nil {
if err := upgrade.UpdateKubeletLocalMode(cfg, data.DryRun()); err != nil { return errors.Wrap(err, "failed to update kubelet local mode")
return errors.Wrap(err, "failed to update kubelet local mode")
}
} }
fmt.Println("[upgrad/kubeconfig] The kubeconfig files for this node were successfully upgraded!") fmt.Println("[upgrade/kubeconfig] The kubeconfig files for this node were successfully upgraded!")
return nil return nil
} }

View File

@ -24,7 +24,6 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
) )
@ -60,10 +59,8 @@ func runKubeconfig() func(c workflow.RunData) error {
// Otherwise, retrieve all the info required for kubeconfig upgrade. // Otherwise, retrieve all the info required for kubeconfig upgrade.
cfg := data.InitCfg() cfg := data.InitCfg()
if features.Enabled(cfg.FeatureGates, features.ControlPlaneKubeletLocalMode) { if err := upgrade.UpdateKubeletKubeconfigServer(cfg, data.DryRun()); err != nil {
if err := upgrade.UpdateKubeletLocalMode(cfg, data.DryRun()); err != nil { return errors.Wrap(err, "failed to update kubelet local mode")
return errors.Wrap(err, "failed to update kubelet local mode")
}
} }
fmt.Println("[upgrade/kubeconfig] The kubeconfig files for this node were successfully upgraded!") fmt.Println("[upgrade/kubeconfig] The kubeconfig files for this node were successfully upgraded!")

View File

@ -193,11 +193,11 @@ func WriteKubeletConfigFiles(cfg *kubeadmapi.InitConfiguration, kubeletConfigDir
return nil return nil
} }
// UpdateKubeletLocalMode changes the Server URL in the kubelets kubeconfig to the local API endpoint if it is currently // UpdateKubeletKubeconfigServer changes the Server URL in the kubelets kubeconfig if necessary depending on the
// set to the ControlPlaneEndpoint. // ControlPlaneKubeletLocalMode feature gate.
// TODO: remove this function once kubeletKubeConfigFilePath goes GA and is hardcoded to enabled by default: // TODO: remove this function once ControlPlaneKubeletLocalMode goes GA and is hardcoded to be enabled by default:
// https://github.com/kubernetes/kubeadm/issues/2271 // https://github.com/kubernetes/kubeadm/issues/2271
func UpdateKubeletLocalMode(cfg *kubeadmapi.InitConfiguration, dryRun bool) error { func UpdateKubeletKubeconfigServer(cfg *kubeadmapi.InitConfiguration, dryRun bool) error {
kubeletKubeConfigFilePath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName) kubeletKubeConfigFilePath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)
if _, err := os.Stat(kubeletKubeConfigFilePath); err != nil { if _, err := os.Stat(kubeletKubeConfigFilePath); err != nil {
@ -228,19 +228,30 @@ func UpdateKubeletLocalMode(cfg *kubeadmapi.InitConfiguration, dryRun bool) erro
return err return err
} }
// Skip changing kubeconfig file if Server does not match the ControlPlaneEndpoint. var targetServer string
if config.Clusters[configContext.Cluster].Server != controlPlaneAPIEndpoint || controlPlaneAPIEndpoint == localAPIEndpoint { if features.Enabled(cfg.FeatureGates, features.ControlPlaneKubeletLocalMode) {
klog.V(2).Infof("Skipping update of the Server URL in %s, because it's already not equal to %q or already matches the localAPIEndpoint", kubeletKubeConfigFilePath, cfg.ControlPlaneEndpoint) // Skip changing kubeconfig file if Server does not match the ControlPlaneEndpoint.
return nil if config.Clusters[configContext.Cluster].Server != controlPlaneAPIEndpoint || controlPlaneAPIEndpoint == localAPIEndpoint {
klog.V(2).Infof("Skipping update of the Server URL in %s, because it's already not equal to %q or already matches the localAPIEndpoint", kubeletKubeConfigFilePath, controlPlaneAPIEndpoint)
return nil
}
targetServer = localAPIEndpoint
} else {
// Skip changing kubeconfig file if Server does not match the localAPIEndpoint.
if config.Clusters[configContext.Cluster].Server != localAPIEndpoint {
klog.V(2).Infof("Skipping update of the Server URL in %s, because it already matches the controlPlaneAPIEndpoint", kubeletKubeConfigFilePath)
return nil
}
targetServer = controlPlaneAPIEndpoint
} }
if dryRun { if dryRun {
fmt.Printf("[dryrun] Would change the Server URL from %q to %q in %s and try to restart kubelet\n", config.Clusters[configContext.Cluster].Server, localAPIEndpoint, kubeletKubeConfigFilePath) fmt.Printf("[dryrun] Would change the Server URL from %q to %q in %s and try to restart kubelet\n", config.Clusters[configContext.Cluster].Server, targetServer, kubeletKubeConfigFilePath)
return nil return nil
} }
klog.V(1).Infof("Changing the Server URL from %q to %q in %s", config.Clusters[configContext.Cluster].Server, localAPIEndpoint, kubeletKubeConfigFilePath) klog.V(1).Infof("Changing the Server URL from %q to %q in %s", config.Clusters[configContext.Cluster].Server, targetServer, kubeletKubeConfigFilePath)
config.Clusters[configContext.Cluster].Server = localAPIEndpoint config.Clusters[configContext.Cluster].Server = targetServer
if err := clientcmd.WriteToFile(*config, kubeletKubeConfigFilePath); err != nil { if err := clientcmd.WriteToFile(*config, kubeletKubeConfigFilePath); err != nil {
return err return err