diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/apply/addons.go b/cmd/kubeadm/app/cmd/phases/upgrade/addons.go similarity index 94% rename from cmd/kubeadm/app/cmd/phases/upgrade/apply/addons.go rename to cmd/kubeadm/app/cmd/phases/upgrade/addons.go index cbd1c02a099..d010e09c6bf 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/apply/addons.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/addons.go @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package apply implements phases of 'kubeadm upgrade apply'. -package apply +// Package upgrade holds the common phases for 'kubeadm upgrade'. +package upgrade import ( "fmt" @@ -28,7 +28,6 @@ import ( kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" dnsaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns" proxyaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" @@ -39,7 +38,6 @@ func NewAddonPhase() workflow.Phase { return workflow.Phase{ Name: "addon", Short: "Upgrade the default kubeadm addons", - Long: cmdutil.MacroCommandLongDescription, Phases: []workflow.Phase{ { Name: "all", @@ -98,7 +96,6 @@ func runCoreDNSAddon(c workflow.RunData) error { return nil } - // Upgrade CoreDNS if err := dnsaddon.EnsureDNSAddon(&cfg.ClusterConfiguration, client, patchesDir, out, dryRun); err != nil { return err } @@ -121,7 +118,6 @@ func runKubeProxyAddon(c workflow.RunData) error { return nil } - // Upgrade kube-proxy if err := proxyaddon.EnsureProxyAddon(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, client, out, dryRun); err != nil { return err } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/apply/data.go b/cmd/kubeadm/app/cmd/phases/upgrade/apply/data.go index dfe291e0d5d..ef93e0bf84b 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/apply/data.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/apply/data.go @@ -18,26 +18,14 @@ limitations under the License. package apply import ( - "io" - - "k8s.io/apimachinery/pkg/util/sets" - clientset "k8s.io/client-go/kubernetes" - - kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/upgrade" ) // Data is the interface to use for kubeadm upgrade apply phases. // The "applyData" type from "cmd/upgrade/apply.go" must satisfy this interface. type Data interface { - EtcdUpgrade() bool - RenewCerts() bool - DryRun() bool - Cfg() *kubeadmapi.UpgradeConfiguration - InitCfg() *kubeadmapi.InitConfiguration - Client() clientset.Interface - IgnorePreflightErrors() sets.Set[string] - PatchesDir() string - OutputWriter() io.Writer + upgrade.Data + SessionIsInteractive() bool AllowExperimentalUpgrades() bool AllowRCUpgrades() bool diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/apply/uploadconfig.go b/cmd/kubeadm/app/cmd/phases/upgrade/apply/uploadconfig.go index 525113d3eb2..3844d157cef 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/apply/uploadconfig.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/apply/uploadconfig.go @@ -28,7 +28,6 @@ import ( kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig" @@ -40,7 +39,6 @@ func NewUploadConfigPhase() workflow.Phase { Name: "upload-config", Aliases: []string{"uploadconfig"}, Short: "Upload the kubeadm and kubelet configurations to ConfigMaps", - Long: cmdutil.MacroCommandLongDescription, Phases: []workflow.Phase{ { Name: "all", diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/data.go b/cmd/kubeadm/app/cmd/phases/upgrade/data.go new file mode 100644 index 00000000000..75270be2c2b --- /dev/null +++ b/cmd/kubeadm/app/cmd/phases/upgrade/data.go @@ -0,0 +1,40 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package upgrade holds the common phases for 'kubeadm upgrade'. +package upgrade + +import ( + "io" + + "k8s.io/apimachinery/pkg/util/sets" + clientset "k8s.io/client-go/kubernetes" + + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" +) + +// Data is the common interface to use for kubeadm upgrade phases. +type Data interface { + EtcdUpgrade() bool + RenewCerts() bool + DryRun() bool + Cfg() *kubeadmapi.UpgradeConfiguration + InitCfg() *kubeadmapi.InitConfiguration + Client() clientset.Interface + IgnorePreflightErrors() sets.Set[string] + PatchesDir() string + OutputWriter() io.Writer +} diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/data_test.go b/cmd/kubeadm/app/cmd/phases/upgrade/data_test.go new file mode 100644 index 00000000000..6d6b3b3c943 --- /dev/null +++ b/cmd/kubeadm/app/cmd/phases/upgrade/data_test.go @@ -0,0 +1,42 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package upgrade + +import ( + "io" + + "k8s.io/apimachinery/pkg/util/sets" + clientset "k8s.io/client-go/kubernetes" + + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" +) + +// a package local type for testing purposes. +type testData struct{} + +// testData must satisfy Data. +var _ Data = &testData{} + +func (t *testData) EtcdUpgrade() bool { return false } +func (t *testData) RenewCerts() bool { return false } +func (t *testData) DryRun() bool { return false } +func (t *testData) Cfg() *kubeadmapi.UpgradeConfiguration { return nil } +func (t *testData) InitCfg() *kubeadmapi.InitConfiguration { return nil } +func (t *testData) Client() clientset.Interface { return nil } +func (t *testData) IgnorePreflightErrors() sets.Set[string] { return nil } +func (t *testData) PatchesDir() string { return "" } +func (t *testData) OutputWriter() io.Writer { return nil } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/apply/kubeletconfig.go b/cmd/kubeadm/app/cmd/phases/upgrade/kubeletconfig.go similarity index 88% rename from cmd/kubeadm/app/cmd/phases/upgrade/apply/kubeletconfig.go rename to cmd/kubeadm/app/cmd/phases/upgrade/kubeletconfig.go index 2996b8af167..86e077cc17b 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/apply/kubeletconfig.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/kubeletconfig.go @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package apply implements phases of 'kubeadm upgrade apply'. -package apply +// Package upgrade holds the common phases for 'kubeadm upgrade'. +package upgrade import ( "fmt" @@ -57,16 +57,14 @@ func runKubeletConfigPhase(c workflow.RunData) error { return errors.New("kubelet-config phase invoked with an invalid data struct") } - initCfg, dryRun := data.InitCfg(), data.DryRun() - // Write the configuration for the kubelet down to disk and print the generated manifests instead of dry-running. // If not dry-running, the kubelet config file will be backed up to the /etc/kubernetes/tmp/ dir, so that it could be // recovered if anything goes wrong. - err := upgrade.WriteKubeletConfigFiles(initCfg, data.PatchesDir(), dryRun, data.OutputWriter()) + err := upgrade.WriteKubeletConfigFiles(data.InitCfg(), data.PatchesDir(), data.DryRun(), data.OutputWriter()) if err != nil { return err } - fmt.Println("[upgrade/kubelet-config] The kubelet configuration for this node was successfully updated!") + fmt.Println("[upgrade/kubelet-config] The kubelet configuration for this node was successfully upgraded!") return nil } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/controlplane.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/controlplane.go index cbdca3ec1c6..38b3e81daf3 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/controlplane.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/controlplane.go @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package node implements phases of 'kubeadm upgrade node'. package node import ( @@ -28,13 +29,14 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" ) -// NewControlPlane creates a kubeadm workflow phase that implements handling of control-plane upgrade. +// NewControlPlane returns a new control-plane phase. func NewControlPlane() workflow.Phase { phase := workflow.Phase{ Name: "control-plane", Short: "Upgrade the control plane instance deployed on this node, if any", Run: runControlPlane(), InheritFlags: []string{ + options.CfgPath, options.DryRun, options.KubeconfigPath, options.CertificateRenewal, @@ -54,7 +56,7 @@ func runControlPlane() func(c workflow.RunData) error { // if this is not a control-plane node, this phase should not be executed if !data.IsControlPlaneNode() { - fmt.Println("[upgrade] Skipping phase. Not a control plane node.") + fmt.Println("[upgrade/control-plane] Skipping phase. Not a control plane node.") return nil } @@ -67,8 +69,9 @@ func runControlPlane() func(c workflow.RunData) error { patchesDir := data.PatchesDir() // Upgrade the control plane and etcd if installed on this node - fmt.Printf("[upgrade] Upgrading your Static Pod-hosted control plane instance to version %q...\n", cfg.KubernetesVersion) + fmt.Printf("[upgrade/control-plane] Upgrading your Static Pod-hosted control plane instance to version %q...\n", cfg.KubernetesVersion) if dryRun { + fmt.Printf("[dryrun] Would upgrade your static Pod-hosted control plane to version %q", cfg.KubernetesVersion) return upgrade.DryRunStaticPodUpgrade(patchesDir, cfg) } @@ -78,11 +81,7 @@ func runControlPlane() func(c workflow.RunData) error { return errors.Wrap(err, "couldn't complete the static pod upgrade") } - if err := upgrade.PerformAddonsUpgrade(client, cfg, data.PatchesDir(), data.OutputWriter()); err != nil { - return errors.Wrap(err, "failed to perform addons upgrade") - } - - fmt.Println("[upgrade] The control plane instance for this node was successfully updated!") + fmt.Println("[upgrade/control-plane] The control plane instance for this node was successfully upgraded!") return nil } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go index 4c633c66f09..aaf2cdf4212 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/data.go @@ -14,29 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package node implements phases of 'kubeadm upgrade node'. package node import ( - "io" - - "k8s.io/apimachinery/pkg/util/sets" - clientset "k8s.io/client-go/kubernetes" - - kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/upgrade" ) // Data is the interface to use for kubeadm upgrade node phases. // The "nodeData" type from "cmd/upgrade/node.go" must satisfy this interface. type Data interface { - EtcdUpgrade() bool - RenewCerts() bool - DryRun() bool - Cfg() *kubeadmapi.UpgradeConfiguration - InitCfg() *kubeadmapi.InitConfiguration + upgrade.Data + IsControlPlaneNode() bool - Client() clientset.Interface - IgnorePreflightErrors() sets.Set[string] - PatchesDir() string KubeConfigPath() string - OutputWriter() io.Writer } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeconfig.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeconfig.go index 305ca987e37..544e9d0f84f 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeconfig.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeconfig.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package node holds phases of "kubeadm upgrade node". +// Package node implements phases of 'kubeadm upgrade node'. package node import ( @@ -28,7 +28,7 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" ) -// NewKubeconfigPhase creates a kubeadm workflow phase that implements handling of kubeconfig upgrade. +// NewKubeconfigPhase returns a new kubeconfig phase. func NewKubeconfigPhase() workflow.Phase { phase := workflow.Phase{ Name: "kubeconfig", @@ -36,6 +36,7 @@ func NewKubeconfigPhase() workflow.Phase { Run: runKubeconfig(), Hidden: true, InheritFlags: []string{ + options.CfgPath, options.DryRun, options.KubeconfigPath, }, @@ -50,23 +51,22 @@ func runKubeconfig() func(c workflow.RunData) error { return errors.New("kubeconfig phase invoked with an invalid data struct") } - // if this is not a control-plane node, this phase should not be executed + // If this is not a control-plane node, this phase should not be executed. if !data.IsControlPlaneNode() { - fmt.Println("[upgrade] Skipping phase. Not a control plane node.") + fmt.Println("[upgrade/kubeconfig] Skipping phase. Not a control plane node.") return nil } - // otherwise, retrieve all the info required for kubeconfig upgrade + // Otherwise, retrieve all the info required for kubeconfig upgrade. cfg := data.InitCfg() - dryRun := data.DryRun() if features.Enabled(cfg.FeatureGates, features.ControlPlaneKubeletLocalMode) { - if err := upgrade.UpdateKubeletLocalMode(cfg, dryRun); err != nil { + if err := upgrade.UpdateKubeletLocalMode(cfg, data.DryRun()); err != nil { return errors.Wrap(err, "failed to update kubelet local mode") } } - fmt.Println("[upgrade] The kubeconfig for this node was successfully updated!") + fmt.Println("[upgrade/kubeconfig] The kubeconfig files for this node were successfully upgraded!") return nil } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go deleted file mode 100644 index 6a6503413ec..00000000000 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package node - -import ( - "fmt" - - "github.com/pkg/errors" - - "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" - "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" -) - -var ( - kubeletConfigLongDesc = cmdutil.LongDesc(` - Download the kubelet configuration from the kubelet-config ConfigMap stored in the cluster - `) -) - -// NewKubeletConfigPhase creates a kubeadm workflow phase that implements handling of kubelet-config upgrade. -func NewKubeletConfigPhase() workflow.Phase { - phase := workflow.Phase{ - Name: "kubelet-config", - Short: "Upgrade the kubelet configuration for this node", - Long: kubeletConfigLongDesc, - Run: runKubeletConfigPhase(), - InheritFlags: []string{ - options.DryRun, - options.KubeconfigPath, - options.Patches, - }, - } - return phase -} - -func runKubeletConfigPhase() func(c workflow.RunData) error { - return func(c workflow.RunData) error { - data, ok := c.(Data) - if !ok { - return errors.New("kubelet-config phase invoked with an invalid data struct") - } - - // otherwise, retrieve all the info required for kubelet config upgrade - cfg := data.InitCfg() - dryRun := data.DryRun() - - // Write the configuration for the kubelet down to disk and print the generated manifests instead if dry-running. - // If not dry-running, the kubelet config file will be backed up to /etc/kubernetes/tmp/ dir, so that it could be - // recovered if there is anything goes wrong. - err := upgrade.WriteKubeletConfigFiles(cfg, data.PatchesDir(), dryRun, data.OutputWriter()) - if err != nil { - return err - } - - fmt.Println("[upgrade] The configuration for this node was successfully updated!") - fmt.Println("[upgrade] Now you should go ahead and upgrade the kubelet package using your package manager.") - return nil - } -} diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/preflight.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/preflight.go index 9d79f281cda..25ed36f0c72 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/preflight.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/preflight.go @@ -28,7 +28,7 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/preflight" ) -// NewPreflightPhase creates a kubeadm workflow phase that implements preflight checks for a new node join +// NewPreflightPhase returns a new preflight phase. func NewPreflightPhase() workflow.Phase { return workflow.Phase{ Name: "preflight", @@ -36,6 +36,7 @@ func NewPreflightPhase() workflow.Phase { Long: "Run pre-flight checks for kubeadm upgrade node.", Run: runPreflight, InheritFlags: []string{ + options.CfgPath, options.IgnorePreflightErrors, }, } @@ -47,14 +48,14 @@ func runPreflight(c workflow.RunData) error { if !ok { return errors.New("preflight phase invoked with an invalid data struct") } - fmt.Println("[preflight] Running pre-flight checks") + fmt.Println("[upgrade/preflight] Running pre-flight checks") - // First, check if we're root separately from the other preflight checks and fail fast + // First, check if we're root separately from the other preflight checks and fail fast. if err := preflight.RunRootCheckOnly(data.IgnorePreflightErrors()); err != nil { return err } - // If this is a control-plane node, pull the basic images + // If this is a control-plane node, pull the basic images. if data.IsControlPlaneNode() { // Update the InitConfiguration used for RunPullImagesCheck with ImagePullPolicy and ImagePullSerial // that come from UpgradeNodeConfiguration. @@ -63,17 +64,17 @@ func runPreflight(c workflow.RunData) error { initConfig.NodeRegistration.ImagePullSerial = data.Cfg().Node.ImagePullSerial if !data.DryRun() { - fmt.Println("[preflight] Pulling images required for setting up a Kubernetes cluster") - fmt.Println("[preflight] This might take a minute or two, depending on the speed of your internet connection") - fmt.Println("[preflight] You can also perform this action beforehand using 'kubeadm config images pull'") + fmt.Println("[upgrade/preflight] Pulling images required for setting up a Kubernetes cluster") + fmt.Println("[upgrade/preflight] This might take a minute or two, depending on the speed of your internet connection") + fmt.Println("[upgrade/preflight] You can also perform this action beforehand using 'kubeadm config images pull'") if err := preflight.RunPullImagesCheck(utilsexec.New(), initConfig, data.IgnorePreflightErrors()); err != nil { return err } } else { - fmt.Println("[preflight] Would pull the required images (like 'kubeadm config images pull')") + fmt.Println("[upgrade/preflight] Would pull the required images (like 'kubeadm config images pull')") } } else { - fmt.Println("[preflight] Skipping prepull. Not a control plane node.") + fmt.Println("[upgrade/preflight] Skipping prepull. Not a control plane node.") return nil } diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/apply/postupgrade.go b/cmd/kubeadm/app/cmd/phases/upgrade/postupgrade.go similarity index 88% rename from cmd/kubeadm/app/cmd/phases/upgrade/apply/postupgrade.go rename to cmd/kubeadm/app/cmd/phases/upgrade/postupgrade.go index 8e4483d1025..bfeeda599e6 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/apply/postupgrade.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/postupgrade.go @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package apply implements phases of 'kubeadm upgrade apply'. -package apply +// Package upgrade holds the common phases for 'kubeadm upgrade'. +package upgrade import ( "github.com/pkg/errors" @@ -41,7 +41,7 @@ func NewPostUpgradePhase() workflow.Phase { func runPostUpgrade(c workflow.RunData) error { _, ok := c.(Data) if !ok { - return errors.New("preflight phase invoked with an invalid data struct") + return errors.New("post-upgrade phase invoked with an invalid data struct") } // PLACEHOLDER: this phase should contain any release specific post-upgrade tasks. diff --git a/cmd/kubeadm/app/cmd/upgrade/apply.go b/cmd/kubeadm/app/cmd/upgrade/apply.go index 10b0d4113ff..14eb32bc0de 100644 --- a/cmd/kubeadm/app/cmd/upgrade/apply.go +++ b/cmd/kubeadm/app/cmd/upgrade/apply.go @@ -34,6 +34,7 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + commonphases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/upgrade" phases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/upgrade/apply" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" @@ -134,10 +135,10 @@ func newCmdApply(apf *applyPlanFlags) *cobra.Command { applyRunner.AppendPhase(phases.NewControlPlanePhase()) applyRunner.AppendPhase(phases.NewUploadConfigPhase()) applyRunner.AppendPhase(phases.NewKubeconfigPhase()) - applyRunner.AppendPhase(phases.NewKubeletConfigPhase()) + applyRunner.AppendPhase(commonphases.NewKubeletConfigPhase()) applyRunner.AppendPhase(phases.NewBootstrapTokenPhase()) - applyRunner.AppendPhase(phases.NewAddonPhase()) - applyRunner.AppendPhase(phases.NewPostUpgradePhase()) + applyRunner.AppendPhase(commonphases.NewAddonPhase()) + applyRunner.AppendPhase(commonphases.NewPostUpgradePhase()) // Sets the data builder function, that will be used by the runner, // both when running the entire workflow or single phases. diff --git a/cmd/kubeadm/app/cmd/upgrade/node.go b/cmd/kubeadm/app/cmd/upgrade/node.go index 90eea2875f1..e88fc2c6211 100644 --- a/cmd/kubeadm/app/cmd/upgrade/node.go +++ b/cmd/kubeadm/app/cmd/upgrade/node.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" + commonphases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/upgrade" phases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/upgrade/node" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" @@ -98,7 +99,9 @@ func newCmdNode(out io.Writer) *cobra.Command { nodeRunner.AppendPhase(phases.NewPreflightPhase()) nodeRunner.AppendPhase(phases.NewControlPlane()) nodeRunner.AppendPhase(phases.NewKubeconfigPhase()) - nodeRunner.AppendPhase(phases.NewKubeletConfigPhase()) + nodeRunner.AppendPhase(commonphases.NewKubeletConfigPhase()) + nodeRunner.AppendPhase(commonphases.NewAddonPhase()) + nodeRunner.AppendPhase(commonphases.NewPostUpgradePhase()) // sets the data builder function, that will be used by the runner // both when running the entire workflow or single phases diff --git a/cmd/kubeadm/app/phases/upgrade/postupgrade.go b/cmd/kubeadm/app/phases/upgrade/postupgrade.go index cf5ad4c219b..0a8b6e310f7 100644 --- a/cmd/kubeadm/app/phases/upgrade/postupgrade.go +++ b/cmd/kubeadm/app/phases/upgrade/postupgrade.go @@ -25,7 +25,6 @@ import ( "github.com/pkg/errors" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" errorsutil "k8s.io/apimachinery/pkg/util/errors" @@ -36,79 +35,11 @@ import ( kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns" - "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun" ) -// PerformAddonsUpgrade performs the upgrade of the coredns and kube-proxy addons. -func PerformAddonsUpgrade(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, patchesDir string, out io.Writer) error { - unupgradedControlPlanes, err := UnupgradedControlPlaneInstances(client, cfg.NodeRegistration.Name) - if err != nil { - return errors.Wrapf(err, "failed to determine whether all the control plane instances have been upgraded") - } - if len(unupgradedControlPlanes) > 0 { - fmt.Fprintf(out, "[upgrade/addons] skip upgrade addons because control plane instances %v have not been upgraded\n", unupgradedControlPlanes) - return nil - } - - var errs []error - - // If the coredns ConfigMap is missing, show a warning and assume that the - // DNS addon was skipped during "kubeadm init", and that its redeployment on upgrade is not desired. - // - // TODO: remove this once "kubeadm upgrade apply" phases are supported: - // https://github.com/kubernetes/kubeadm/issues/1318 - var missingCoreDNSConfigMap bool - if _, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get( - context.TODO(), - kubeadmconstants.CoreDNSConfigMap, - metav1.GetOptions{}, - ); err != nil && apierrors.IsNotFound(err) { - missingCoreDNSConfigMap = true - } - if missingCoreDNSConfigMap { - klog.Warningf("the ConfigMaps %q in the namespace %q were not found. "+ - "Assuming that a DNS server was not deployed for this cluster. "+ - "Note that once 'kubeadm upgrade apply' supports phases you "+ - "will have to skip the DNS upgrade manually", - kubeadmconstants.CoreDNSConfigMap, - metav1.NamespaceSystem) - } else { - // Upgrade CoreDNS - if err := dns.EnsureDNSAddon(&cfg.ClusterConfiguration, client, patchesDir, out, false); err != nil { - errs = append(errs, err) - } - } - - // If the kube-proxy ConfigMap is missing, show a warning and assume that kube-proxy - // was skipped during "kubeadm init", and that its redeployment on upgrade is not desired. - // - // TODO: remove this once "kubeadm upgrade apply" phases are supported: - // https://github.com/kubernetes/kubeadm/issues/1318 - if _, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get( - context.TODO(), - kubeadmconstants.KubeProxyConfigMap, - metav1.GetOptions{}, - ); err != nil && apierrors.IsNotFound(err) { - klog.Warningf("the ConfigMap %q in the namespace %q was not found. "+ - "Assuming that kube-proxy was not deployed for this cluster. "+ - "Note that once 'kubeadm upgrade apply' supports phases you "+ - "will have to skip the kube-proxy upgrade manually", - kubeadmconstants.KubeProxyConfigMap, - metav1.NamespaceSystem) - } else { - // Upgrade kube-proxy - if err := proxy.EnsureProxyAddon(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, client, out, false); err != nil { - errs = append(errs, err) - } - } - - return errorsutil.NewAggregate(errs) -} - // UnupgradedControlPlaneInstances returns a list of control plane instances that have not yet been upgraded. // // NB. This function can only be called after the current control plane instance has been upgraded already.