mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
Merge pull request #125780 from chrischdi/pr-kubeadm-control-plane-kubelet-local-init
kubeadm: consider feature gate ControlPlaneKubeletLocalMode on init and upgrade
This commit is contained in:
commit
33ccc51cb7
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
||||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
)
|
)
|
||||||
@ -157,7 +158,16 @@ func runKubeConfigFile(kubeConfigFileName string) func(workflow.RunData) error {
|
|||||||
cfg.CertificatesDir = data.CertificateWriteDir()
|
cfg.CertificatesDir = data.CertificateWriteDir()
|
||||||
defer func() { cfg.CertificatesDir = data.CertificateDir() }()
|
defer func() { cfg.CertificatesDir = data.CertificateDir() }()
|
||||||
|
|
||||||
|
initConfiguration := data.Cfg().DeepCopy()
|
||||||
|
|
||||||
|
if features.Enabled(cfg.FeatureGates, features.ControlPlaneKubeletLocalMode) {
|
||||||
|
if kubeConfigFileName == kubeadmconstants.KubeletKubeConfigFileName {
|
||||||
|
// Unset the ControlPlaneEndpoint so the creation falls back to the LocalAPIEndpoint for the kubelet's kubeconfig.
|
||||||
|
initConfiguration.ControlPlaneEndpoint = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// creates the KubeConfig file (or use existing)
|
// creates the KubeConfig file (or use existing)
|
||||||
return kubeconfigphase.CreateKubeConfigFile(kubeConfigFileName, data.KubeConfigDir(), data.Cfg())
|
return kubeconfigphase.CreateKubeConfigFile(kubeConfigFileName, data.KubeConfigDir(), initConfiguration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ 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"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||||
)
|
)
|
||||||
@ -82,6 +83,12 @@ func runControlPlane() func(c workflow.RunData) error {
|
|||||||
return errors.Wrap(err, "failed to perform addons upgrade")
|
return errors.Wrap(err, "failed to perform addons upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if features.Enabled(cfg.FeatureGates, features.ControlPlaneKubeletLocalMode) {
|
||||||
|
if err := upgrade.UpdateKubeletLocalMode(cfg, dryRun); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to update kubelet local mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println("[upgrade] The control plane instance for this node was successfully updated!")
|
fmt.Println("[upgrade] The control plane instance for this node was successfully updated!")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -31,10 +31,12 @@ import (
|
|||||||
errorsutil "k8s.io/apimachinery/pkg/util/errors"
|
errorsutil "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
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/addons/dns"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
||||||
@ -109,6 +111,12 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
|
|||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if features.Enabled(cfg.FeatureGates, features.ControlPlaneKubeletLocalMode) {
|
||||||
|
if err := UpdateKubeletLocalMode(cfg, dryRun); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to update kubelet local mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return errorsutil.NewAggregate(errs)
|
return errorsutil.NewAggregate(errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,3 +289,61 @@ func GetKubeletDir(dryRun bool) (string, error) {
|
|||||||
}
|
}
|
||||||
return kubeadmconstants.KubeletRunDirectory, nil
|
return kubeadmconstants.KubeletRunDirectory, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateKubeletLocalMode changes the Server URL in the kubelets kubeconfig to the local API endpoint if it is currently
|
||||||
|
// set to the ControlPlaneEndpoint.
|
||||||
|
// TODO: remove this function once kubeletKubeConfigFilePath goes GA and is hardcoded to enabled by default:
|
||||||
|
// https://github.com/kubernetes/kubeadm/issues/2271
|
||||||
|
func UpdateKubeletLocalMode(cfg *kubeadmapi.InitConfiguration, dryRun bool) error {
|
||||||
|
kubeletKubeConfigFilePath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)
|
||||||
|
|
||||||
|
if _, err := os.Stat(kubeletKubeConfigFilePath); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
klog.V(2).Infof("Could not mutate the Server URL in %s: %v", kubeletKubeConfigFilePath, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := clientcmd.LoadFromFile(kubeletKubeConfigFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
configContext, ok := config.Contexts[config.CurrentContext]
|
||||||
|
if !ok {
|
||||||
|
return errors.Errorf("cannot find cluster for active context in kubeconfig %q", kubeletKubeConfigFilePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
localAPIEndpoint, err := kubeadmutil.GetLocalAPIEndpoint(&cfg.LocalAPIEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
controlPlaneAPIEndpoint, err := kubeadmutil.GetControlPlaneEndpoint(cfg.ControlPlaneEndpoint, &cfg.LocalAPIEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip changing kubeconfig file if Server does not match the ControlPlaneEndoint.
|
||||||
|
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, cfg.ControlPlaneEndpoint)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(1).Infof("Changing the Server URL from %q to %q in %s", config.Clusters[configContext.Cluster].Server, localAPIEndpoint, kubeletKubeConfigFilePath)
|
||||||
|
config.Clusters[configContext.Cluster].Server = localAPIEndpoint
|
||||||
|
|
||||||
|
if err := clientcmd.WriteToFile(*config, kubeletKubeConfigFilePath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeletphase.TryRestartKubelet()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user