Unverified Commit e41f297d authored by k8s-ci-robot's avatar k8s-ci-robot Committed by GitHub

Merge pull request #69878 from Klaven/kubeadm_1072

Fixes /kubernetes/kubeadm/issues/1072 Cleanup of selfhosting logic
parents 3bf41a21 18dc529d
...@@ -603,11 +603,10 @@ func TestValidateFeatureGates(t *testing.T) { ...@@ -603,11 +603,10 @@ func TestValidateFeatureGates(t *testing.T) {
featureGates featureFlag featureGates featureFlag
expected bool expected bool
}{ }{
{featureFlag{"SelfHosting": true}, true}, {featureFlag{"Unknown": true}, false},
{featureFlag{"SelfHosting": false}, true}, {featureFlag{"Unknown": false}, false},
{featureFlag{"StoreCertsInSecrets": true}, true}, {featureFlag{"CoreDNS": true}, true},
{featureFlag{"StoreCertsInSecrets": false}, true}, {featureFlag{"CoreDNS": false}, true},
{featureFlag{"Foo": true}, false},
} }
for _, rt := range tests { for _, rt := range tests {
actual := ValidateFeatureGates(rt.featureGates, nil) actual := ValidateFeatureGates(rt.featureGates, nil)
......
...@@ -47,7 +47,6 @@ go_library( ...@@ -47,7 +47,6 @@ go_library(
"//cmd/kubeadm/app/phases/kubelet:go_default_library", "//cmd/kubeadm/app/phases/kubelet:go_default_library",
"//cmd/kubeadm/app/phases/markmaster:go_default_library", "//cmd/kubeadm/app/phases/markmaster:go_default_library",
"//cmd/kubeadm/app/phases/patchnode:go_default_library", "//cmd/kubeadm/app/phases/patchnode:go_default_library",
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library", "//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
......
...@@ -8,6 +8,7 @@ go_library( ...@@ -8,6 +8,7 @@ go_library(
"kubeconfig.go", "kubeconfig.go",
"kubelet.go", "kubelet.go",
"preflight.go", "preflight.go",
"selfhosting.go",
], ],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/alpha", importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/alpha",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
...@@ -19,12 +20,15 @@ go_library( ...@@ -19,12 +20,15 @@ go_library(
"//cmd/kubeadm/app/cmd/phases:go_default_library", "//cmd/kubeadm/app/cmd/phases:go_default_library",
"//cmd/kubeadm/app/cmd/util:go_default_library", "//cmd/kubeadm/app/cmd/util:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/app/phases/certs:go_default_library", "//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/phases/certs/renewal:go_default_library", "//cmd/kubeadm/app/phases/certs/renewal:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library", "//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/phases/kubelet:go_default_library", "//cmd/kubeadm/app/phases/kubelet:go_default_library",
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/apiclient:go_default_library",
"//cmd/kubeadm/app/util/config:go_default_library", "//cmd/kubeadm/app/util/config:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library", "//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//pkg/util/normalizer:go_default_library", "//pkg/util/normalizer:go_default_library",
......
...@@ -25,7 +25,7 @@ import ( ...@@ -25,7 +25,7 @@ import (
) )
// NewCmdAlpha returns "kubeadm alpha" command. // NewCmdAlpha returns "kubeadm alpha" command.
func NewCmdAlpha(out io.Writer) *cobra.Command { func NewCmdAlpha(in io.Reader, out io.Writer) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "alpha", Use: "alpha",
Short: "Kubeadm experimental sub-commands", Short: "Kubeadm experimental sub-commands",
...@@ -35,6 +35,7 @@ func NewCmdAlpha(out io.Writer) *cobra.Command { ...@@ -35,6 +35,7 @@ func NewCmdAlpha(out io.Writer) *cobra.Command {
cmd.AddCommand(newCmdKubeletUtility()) cmd.AddCommand(newCmdKubeletUtility())
cmd.AddCommand(newCmdKubeConfigUtility(out)) cmd.AddCommand(newCmdKubeConfigUtility(out))
cmd.AddCommand(newCmdPreFlightUtility()) cmd.AddCommand(newCmdPreFlightUtility())
cmd.AddCommand(NewCmdSelfhosting(in))
// TODO: This command should be removed as soon as the kubeadm init phase refactoring is completed. // TODO: This command should be removed as soon as the kubeadm init phase refactoring is completed.
// current phases implemented as cobra.Commands should become workflow.Phases, while other utilities // current phases implemented as cobra.Commands should become workflow.Phases, while other utilities
...@@ -54,7 +55,6 @@ func newCmdPhase(out io.Writer) *cobra.Command { ...@@ -54,7 +55,6 @@ func newCmdPhase(out io.Writer) *cobra.Command {
cmd.AddCommand(phases.NewCmdAddon()) cmd.AddCommand(phases.NewCmdAddon())
cmd.AddCommand(phases.NewCmdBootstrapToken()) cmd.AddCommand(phases.NewCmdBootstrapToken())
cmd.AddCommand(phases.NewCmdMarkMaster()) cmd.AddCommand(phases.NewCmdMarkMaster())
cmd.AddCommand(phases.NewCmdSelfhosting())
return cmd return cmd
} }
...@@ -14,12 +14,14 @@ See the License for the specific language governing permissions and ...@@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package phases package alpha
import ( import (
"os" "bufio"
"errors"
"fmt"
"io"
"strings" "strings"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
...@@ -27,6 +29,7 @@ import ( ...@@ -27,6 +29,7 @@ import (
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
"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/features"
...@@ -36,6 +39,9 @@ import ( ...@@ -36,6 +39,9 @@ import (
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/pkg/util/normalizer" "k8s.io/kubernetes/pkg/util/normalizer"
"os"
"time"
) )
var ( var (
...@@ -47,16 +53,14 @@ var ( ...@@ -47,16 +53,14 @@ var (
` + cmdutil.AlphaDisclaimer) ` + cmdutil.AlphaDisclaimer)
selfhostingExample = normalizer.Examples(` selfhostingExample = normalizer.Examples(`
# Converts a static Pod-hosted control plane into a self-hosted one, # Converts a static Pod-hosted control plane into a self-hosted one.
# functionally equivalent to what generated by kubeadm init executed
# with --feature-gates=SelfHosting=true.
kubeadm alpha phase selfhosting convert-from-staticpods kubeadm alpha phase self-hosting convert-from-staticpods
`) `)
) )
// NewCmdSelfhosting returns the self-hosting Cobra command // NewCmdSelfhosting returns the self-hosting Cobra command
func NewCmdSelfhosting() *cobra.Command { func NewCmdSelfhosting(in io.Reader) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "selfhosting", Use: "selfhosting",
Aliases: []string{"selfhosted", "self-hosting"}, Aliases: []string{"selfhosted", "self-hosting"},
...@@ -64,29 +68,48 @@ func NewCmdSelfhosting() *cobra.Command { ...@@ -64,29 +68,48 @@ func NewCmdSelfhosting() *cobra.Command {
Long: cmdutil.MacroCommandLongDescription, Long: cmdutil.MacroCommandLongDescription,
} }
cmd.AddCommand(getSelfhostingSubCommand()) cmd.AddCommand(getSelfhostingSubCommand(in))
return cmd return cmd
} }
// getSelfhostingSubCommand returns sub commands for Selfhosting phase // getSelfhostingSubCommand returns sub commands for Self-hosting phase
func getSelfhostingSubCommand() *cobra.Command { func getSelfhostingSubCommand(in io.Reader) *cobra.Command {
cfg := &kubeadmapiv1beta1.InitConfiguration{} cfg := &kubeadmapiv1beta1.InitConfiguration{}
// Default values for the cobra help text // Default values for the cobra help text
kubeadmscheme.Scheme.Default(cfg) kubeadmscheme.Scheme.Default(cfg)
var cfgPath, featureGatesString string var cfgPath, featureGatesString string
forcePivot, certsInSecrets := false, false
kubeConfigFile := constants.GetAdminKubeConfigPath() kubeConfigFile := constants.GetAdminKubeConfigPath()
// Creates the UX Command // Creates the UX Command
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "convert-from-staticpods", Use: "pivot",
Aliases: []string{"from-staticpods"}, Aliases: []string{"from-staticpods"},
Short: "Converts a static Pod-hosted control plane into a self-hosted one", Short: "Converts a static Pod-hosted control plane into a self-hosted one",
Long: selfhostingLongDesc, Long: selfhostingLongDesc,
Example: selfhostingExample, Example: selfhostingExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
var err error var err error
if !forcePivot {
fmt.Println("WARNING: self-hosted clusters are not supported by kubeadm upgrade and by other kubeadm commands!")
fmt.Print("[pivot] are you sure you want to proceed? [y/n]: ")
s := bufio.NewScanner(in)
s.Scan()
err = s.Err()
kubeadmutil.CheckErr(err)
if strings.ToLower(s.Text()) != "y" {
kubeadmutil.CheckErr(errors.New("aborted pivot operation"))
}
}
fmt.Println("[pivot] pivoting cluster to self-hosted")
if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil { if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil {
kubeadmutil.CheckErr(err) kubeadmutil.CheckErr(err)
} }
...@@ -102,7 +125,7 @@ func getSelfhostingSubCommand() *cobra.Command { ...@@ -102,7 +125,7 @@ func getSelfhostingSubCommand() *cobra.Command {
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup // KubernetesVersion is not used, but we set it explicitly to avoid the lookup
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig // of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
SetKubernetesVersion(cfg) phases.SetKubernetesVersion(cfg)
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags // This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
...@@ -110,7 +133,7 @@ func getSelfhostingSubCommand() *cobra.Command { ...@@ -110,7 +133,7 @@ func getSelfhostingSubCommand() *cobra.Command {
// Converts the Static Pod-hosted control plane into a self-hosted one // Converts the Static Pod-hosted control plane into a self-hosted one
waiter := apiclient.NewKubeWaiter(client, 2*time.Minute, os.Stdout) waiter := apiclient.NewKubeWaiter(client, 2*time.Minute, os.Stdout)
err = selfhosting.CreateSelfHostedControlPlane(constants.GetStaticPodDirectory(), constants.KubernetesDir, internalcfg, client, waiter, false) err = selfhosting.CreateSelfHostedControlPlane(constants.GetStaticPodDirectory(), constants.KubernetesDir, internalcfg, client, waiter, false, certsInSecrets)
kubeadmutil.CheckErr(err) kubeadmutil.CheckErr(err)
}, },
} }
...@@ -119,8 +142,15 @@ func getSelfhostingSubCommand() *cobra.Command { ...@@ -119,8 +142,15 @@ func getSelfhostingSubCommand() *cobra.Command {
// flags bound to the configuration object // flags bound to the configuration object
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`) cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`)
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental") cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental")
cmd.Flags().StringVar(&featureGatesString, "feature-gates", featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+
"Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n")) cmd.Flags().BoolVarP(
&certsInSecrets, "store-certs-in-secrets", "s",
false, "Enable storing certs in secrets")
cmd.Flags().BoolVarP(
&forcePivot, "force", "f", false,
"Pivot the cluster without prompting for confirmation",
)
// flags that are not bound to the configuration object // flags that are not bound to the configuration object
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go // Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
......
...@@ -89,7 +89,7 @@ func NewKubeadmCommand(in io.Reader, out, err io.Writer) *cobra.Command { ...@@ -89,7 +89,7 @@ func NewKubeadmCommand(in io.Reader, out, err io.Writer) *cobra.Command {
cmds.AddCommand(NewCmdVersion(out)) cmds.AddCommand(NewCmdVersion(out))
cmds.AddCommand(NewCmdToken(out, err)) cmds.AddCommand(NewCmdToken(out, err))
cmds.AddCommand(upgrade.NewCmdUpgrade(out)) cmds.AddCommand(upgrade.NewCmdUpgrade(out))
cmds.AddCommand(alpha.NewCmdAlpha(out)) cmds.AddCommand(alpha.NewCmdAlpha(in, out))
AddKubeadmOtherFlags(cmds.PersistentFlags(), &rootfsPath) AddKubeadmOtherFlags(cmds.PersistentFlags(), &rootfsPath)
......
...@@ -50,7 +50,7 @@ import ( ...@@ -50,7 +50,7 @@ import (
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet"
markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster" markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster"
selfhostingphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting" uploadconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight" "k8s.io/kubernetes/cmd/kubeadm/app/preflight"
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"
...@@ -462,7 +462,7 @@ func runInit(i *initData, out io.Writer) error { ...@@ -462,7 +462,7 @@ func runInit(i *initData, out io.Writer) error {
// Get directories to write files to; can be faked if we're dry-running // Get directories to write files to; can be faked if we're dry-running
glog.V(1).Infof("[init] Getting certificates directory from configuration") glog.V(1).Infof("[init] Getting certificates directory from configuration")
certsDirToWriteTo, kubeConfigDir, manifestDir, _, err := getDirectoriesToUse(i.dryRun, i.dryRunDir, i.cfg.CertificatesDir) certsDirToWriteTo, kubeConfigDir, _, _, err := getDirectoriesToUse(i.dryRun, i.dryRunDir, i.cfg.CertificatesDir)
if err != nil { if err != nil {
return errors.Wrap(err, "error getting directories to use") return errors.Wrap(err, "error getting directories to use")
} }
...@@ -479,11 +479,17 @@ func runInit(i *initData, out io.Writer) error { ...@@ -479,11 +479,17 @@ func runInit(i *initData, out io.Writer) error {
return errors.Wrap(err, "failed to create client") return errors.Wrap(err, "failed to create client")
} }
// TODO: NewControlPlaneWaiter should be converted to private after the self-hosting phase is removed. // Upload currently used configuration to the cluster
timeout := i.cfg.ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration // Note: This is done right in the beginning of cluster initialization; as we might want to make other phases
waiter, err := phases.NewControlPlaneWaiter(i.dryRun, timeout, client, i.outputWriter) // depend on centralized information from this source in the future
if err != nil { glog.V(1).Infof("[init] uploading currently used configuration to the cluster")
return errors.Wrap(err, "failed to create waiter") if err := uploadconfigphase.UploadConfiguration(i.cfg, client); err != nil {
return errors.Wrap(err, "error uploading configuration")
}
glog.V(1).Infof("[init] creating kubelet configuration configmap")
if err := kubeletphase.CreateConfigMap(i.cfg, client); err != nil {
return errors.Wrap(err, "error creating kubelet configuration ConfigMap")
} }
// PHASE 4: Mark the master with the right label/taint // PHASE 4: Mark the master with the right label/taint
...@@ -560,17 +566,6 @@ func runInit(i *initData, out io.Writer) error { ...@@ -560,17 +566,6 @@ func runInit(i *initData, out io.Writer) error {
return errors.Wrap(err, "error ensuring proxy addon") return errors.Wrap(err, "error ensuring proxy addon")
} }
// PHASE 7: Make the control plane self-hosted if feature gate is enabled
if features.Enabled(i.cfg.FeatureGates, features.SelfHosting) {
glog.V(1).Infof("[init] feature gate is enabled. Making control plane self-hosted")
// Temporary control plane is up, now we create our self hosted control
// plane components and remove the static manifests:
fmt.Println("[self-hosted] creating self-hosted control plane")
if err := selfhostingphase.CreateSelfHostedControlPlane(manifestDir, kubeConfigDir, i.cfg, client, waiter, i.dryRun); err != nil {
return errors.Wrap(err, "error creating self hosted control plane")
}
}
// Exit earlier if we're dryrunning // Exit earlier if we're dryrunning
if i.dryRun { if i.dryRun {
fmt.Println("[dryrun] finished dry-running successfully. Above are the resources that would be created") fmt.Println("[dryrun] finished dry-running successfully. Above are the resources that would be created")
......
...@@ -410,16 +410,6 @@ func (j *Join) CheckIfReadyForAdditionalControlPlane(initConfiguration *kubeadma ...@@ -410,16 +410,6 @@ func (j *Join) CheckIfReadyForAdditionalControlPlane(initConfiguration *kubeadma
return errors.New("unable to add a new control plane instance a cluster that doesn't have a stable controlPlaneEndpoint address") return errors.New("unable to add a new control plane instance a cluster that doesn't have a stable controlPlaneEndpoint address")
} }
// blocks if control plane is self-hosted
if features.Enabled(initConfiguration.FeatureGates, features.SelfHosting) {
return errors.New("self-hosted clusters are deprecated and won't be supported by `kubeadm join --experimental-control-plane`")
}
// blocks if the certificates for the control plane are stored in secrets (instead of the local pki folder)
if features.Enabled(initConfiguration.FeatureGates, features.StoreCertsInSecrets) {
return errors.New("certificates stored in secrets, as well as self-hosted clusters are deprecated and won't be supported by `kubeadm join --experimental-control-plane`")
}
// checks if the certificates that must be equal across contolplane instances are provided // checks if the certificates that must be equal across contolplane instances are provided
if ret, err := certsphase.SharedCertificateExists(initConfiguration); !ret { if ret, err := certsphase.SharedCertificateExists(initConfiguration); !ret {
return err return err
......
...@@ -12,7 +12,6 @@ go_library( ...@@ -12,7 +12,6 @@ go_library(
"kubelet.go", "kubelet.go",
"markmaster.go", "markmaster.go",
"preflight.go", "preflight.go",
"selfhosting.go",
"uploadconfig.go", "uploadconfig.go",
"util.go", "util.go",
"waitcontrolplane.go", "waitcontrolplane.go",
...@@ -40,7 +39,6 @@ go_library( ...@@ -40,7 +39,6 @@ go_library(
"//cmd/kubeadm/app/phases/kubelet:go_default_library", "//cmd/kubeadm/app/phases/kubelet:go_default_library",
"//cmd/kubeadm/app/phases/markmaster:go_default_library", "//cmd/kubeadm/app/phases/markmaster:go_default_library",
"//cmd/kubeadm/app/phases/patchnode:go_default_library", "//cmd/kubeadm/app/phases/patchnode:go_default_library",
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library", "//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
......
...@@ -49,7 +49,7 @@ var ( ...@@ -49,7 +49,7 @@ var (
# Installs the CoreDNS and the kube-proxy addons components via the API server, # Installs the CoreDNS and the kube-proxy addons components via the API server,
# functionally equivalent to what installed by kubeadm init. # functionally equivalent to what installed by kubeadm init.
kubeadm alpha phase selfhosting from-staticpods kubeadm alpha phase self-hosting from-staticpods
`) `)
corednsAddonsLongDesc = normalizer.LongDesc(` corednsAddonsLongDesc = normalizer.LongDesc(`
......
...@@ -94,7 +94,7 @@ func runWaitControlPlanePhase(c workflow.RunData) error { ...@@ -94,7 +94,7 @@ func runWaitControlPlanePhase(c workflow.RunData) error {
} }
timeout := data.Cfg().ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration timeout := data.Cfg().ClusterConfiguration.APIServer.TimeoutForControlPlane.Duration
waiter, err := NewControlPlaneWaiter(data.DryRun(), timeout, client, data.OutputWriter()) waiter, err := newControlPlaneWaiter(data.DryRun(), timeout, client, data.OutputWriter())
if err != nil { if err != nil {
return errors.Wrap(err, "error creating waiter") return errors.Wrap(err, "error creating waiter")
} }
...@@ -144,7 +144,7 @@ func printFilesIfDryRunning(data waitControlPlaneData) error { ...@@ -144,7 +144,7 @@ func printFilesIfDryRunning(data waitControlPlaneData) error {
// NewControlPlaneWaiter returns a new waiter that is used to wait on the control plane to boot up. // NewControlPlaneWaiter returns a new waiter that is used to wait on the control plane to boot up.
// TODO: make private (lowercase) after self-hosting phase is removed. // TODO: make private (lowercase) after self-hosting phase is removed.
func NewControlPlaneWaiter(dryRun bool, timeout time.Duration, client clientset.Interface, out io.Writer) (apiclient.Waiter, error) { func newControlPlaneWaiter(dryRun bool, timeout time.Duration, client clientset.Interface, out io.Writer) (apiclient.Waiter, error) {
if dryRun { if dryRun {
return dryrunutil.NewWaiter(), nil return dryrunutil.NewWaiter(), nil
} }
......
...@@ -270,16 +270,6 @@ func EnforceVersionPolicies(flags *applyFlags, versionGetter upgrade.VersionGett ...@@ -270,16 +270,6 @@ func EnforceVersionPolicies(flags *applyFlags, versionGetter upgrade.VersionGett
// PerformControlPlaneUpgrade actually performs the upgrade procedure for the cluster of your type (self-hosted or static-pod-hosted) // PerformControlPlaneUpgrade actually performs the upgrade procedure for the cluster of your type (self-hosted or static-pod-hosted)
func PerformControlPlaneUpgrade(flags *applyFlags, client clientset.Interface, waiter apiclient.Waiter, internalcfg *kubeadmapi.InitConfiguration) error { func PerformControlPlaneUpgrade(flags *applyFlags, client clientset.Interface, waiter apiclient.Waiter, internalcfg *kubeadmapi.InitConfiguration) error {
// Check if the cluster is self-hosted and act accordingly
glog.V(1).Infoln("checking if cluster is self-hosted")
if upgrade.IsControlPlaneSelfHosted(client) {
fmt.Printf("[upgrade/apply] Upgrading your Self-Hosted control plane to version %q...\n", flags.newK8sVersionStr)
// Upgrade the self-hosted cluster
glog.V(1).Infoln("[upgrade/apply] upgrading self-hosted cluster")
return upgrade.SelfHostedControlPlane(client, waiter, internalcfg, flags.newK8sVersion)
}
// OK, the cluster is hosted using static pods. Upgrade a static-pod hosted cluster // OK, the cluster is hosted using static pods. Upgrade a static-pod hosted cluster
fmt.Printf("[upgrade/apply] Upgrading your Static Pod-hosted control plane to version %q...\n", flags.newK8sVersionStr) fmt.Printf("[upgrade/apply] Upgrading your Static Pod-hosted control plane to version %q...\n", flags.newK8sVersionStr)
......
...@@ -58,6 +58,11 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin ...@@ -58,6 +58,11 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
return nil, errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath) return nil, errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath)
} }
// Check if the cluster is self-hosted
if upgrade.IsControlPlaneSelfHosted(client) {
return nil, errors.Errorf("cannot upgrade a self-hosted control plane")
}
// Run healthchecks against the cluster // Run healthchecks against the cluster
if err := upgrade.CheckClusterHealth(client, flags.ignorePreflightErrorsSet); err != nil { if err := upgrade.CheckClusterHealth(client, flags.ignorePreflightErrorsSet); err != nil {
return nil, errors.Wrap(err, "[upgrade/health] FATAL") return nil, errors.Wrap(err, "[upgrade/health] FATAL")
......
...@@ -27,18 +27,10 @@ import ( ...@@ -27,18 +27,10 @@ import (
) )
const ( const (
// HighAvailability is alpha in v1.9 - deprecated in v1.12 (TODO remove in v1.13)
HighAvailability = "HighAvailability"
// CoreDNS is GA in v1.11 // CoreDNS is GA in v1.11
CoreDNS = "CoreDNS" CoreDNS = "CoreDNS"
// SelfHosting is alpha in v1.8 and v1.9 - deprecated in v1.12 (TODO remove in v1.13)
SelfHosting = "SelfHosting"
// StoreCertsInSecrets is alpha in v1.8 and v1.9 - deprecated in v1.12 (TODO remove in v1.13)
StoreCertsInSecrets = "StoreCertsInSecrets"
// DynamicKubeletConfig is beta in v1.11 // DynamicKubeletConfig is beta in v1.11
DynamicKubeletConfig = "DynamicKubeletConfig" DynamicKubeletConfig = "DynamicKubeletConfig"
...@@ -46,18 +38,8 @@ const ( ...@@ -46,18 +38,8 @@ const (
Auditing = "Auditing" Auditing = "Auditing"
) )
var selfHostingDeprecationMessage = "featureGates:SelfHosting has been removed in v1.12"
var storeCertsInSecretsDeprecationMessage = "featureGates:StoreCertsInSecrets has been removed in v1.12"
var highAvailabilityMessage = "featureGates:HighAvailability has been removed in v1.12\n" +
"\tThis feature has been replaced by the kubeadm join --control-plane workflow."
// InitFeatureGates are the default feature gates for the init command // InitFeatureGates are the default feature gates for the init command
var InitFeatureGates = FeatureList{ var InitFeatureGates = FeatureList{
SelfHosting: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Deprecated}, HiddenInHelpText: true, DeprecationMessage: selfHostingDeprecationMessage},
StoreCertsInSecrets: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Deprecated}, HiddenInHelpText: true, DeprecationMessage: storeCertsInSecretsDeprecationMessage},
HighAvailability: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Deprecated}, HiddenInHelpText: true, DeprecationMessage: highAvailabilityMessage},
CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.GA}}, CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.GA}},
DynamicKubeletConfig: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}}, DynamicKubeletConfig: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
Auditing: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}}, Auditing: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
...@@ -174,8 +156,6 @@ func NewFeatureGate(f *FeatureList, value string) (map[string]bool, error) { ...@@ -174,8 +156,6 @@ func NewFeatureGate(f *FeatureList, value string) (map[string]bool, error) {
featureGate[k] = boolValue featureGate[k] = boolValue
} }
ResolveFeatureGateDependencies(featureGate)
return featureGate, nil return featureGate, nil
} }
...@@ -201,18 +181,3 @@ func CheckDeprecatedFlags(f *FeatureList, features map[string]bool) map[string]s ...@@ -201,18 +181,3 @@ func CheckDeprecatedFlags(f *FeatureList, features map[string]bool) map[string]s
return deprecatedMsg return deprecatedMsg
} }
// ResolveFeatureGateDependencies resolve dependencies between feature gates
func ResolveFeatureGateDependencies(featureGate map[string]bool) {
// if HighAvailability enabled and StoreCertsInSecrets disabled, both StoreCertsInSecrets
// and SelfHosting should enabled
if Enabled(featureGate, HighAvailability) && !Enabled(featureGate, StoreCertsInSecrets) {
featureGate[StoreCertsInSecrets] = true
}
// if StoreCertsInSecrets enabled, SelfHosting should enabled
if Enabled(featureGate, StoreCertsInSecrets) {
featureGate[SelfHosting] = true
}
}
...@@ -166,39 +166,6 @@ func TestValidateVersion(t *testing.T) { ...@@ -166,39 +166,6 @@ func TestValidateVersion(t *testing.T) {
} }
} }
func TestResolveFeatureGateDependencies(t *testing.T) {
var tests = []struct {
inputFeatures map[string]bool
expectedFeatures map[string]bool
}{
{ // no flags
inputFeatures: map[string]bool{},
expectedFeatures: map[string]bool{},
},
{ // others flags
inputFeatures: map[string]bool{CoreDNS: false},
expectedFeatures: map[string]bool{CoreDNS: false},
},
{ // just StoreCertsInSecrets flags
inputFeatures: map[string]bool{StoreCertsInSecrets: true},
expectedFeatures: map[string]bool{StoreCertsInSecrets: true, SelfHosting: true},
},
{ // just HighAvailability flags
inputFeatures: map[string]bool{HighAvailability: true},
expectedFeatures: map[string]bool{HighAvailability: true, StoreCertsInSecrets: true, SelfHosting: true},
},
}
for _, test := range tests {
ResolveFeatureGateDependencies(test.inputFeatures)
if !reflect.DeepEqual(test.inputFeatures, test.expectedFeatures) {
t.Errorf("ResolveFeatureGateDependencies failed, expected: %v, got: %v", test.inputFeatures, test.expectedFeatures)
}
}
}
// TestEnabledDefaults tests that Enabled returns the default values for // TestEnabledDefaults tests that Enabled returns the default values for
// each feature gate when no feature gates are specified. // each feature gate when no feature gates are specified.
func TestEnabledDefaults(t *testing.T) { func TestEnabledDefaults(t *testing.T) {
......
...@@ -176,10 +176,6 @@ func getAPIServerCommand(cfg *kubeadmapi.InitConfiguration) []string { ...@@ -176,10 +176,6 @@ func getAPIServerCommand(cfg *kubeadmapi.InitConfiguration) []string {
} }
} }
if features.Enabled(cfg.FeatureGates, features.HighAvailability) {
defaultArguments["endpoint-reconciler-type"] = kubeadmconstants.LeaseEndpointReconcilerType
}
if features.Enabled(cfg.FeatureGates, features.DynamicKubeletConfig) { if features.Enabled(cfg.FeatureGates, features.DynamicKubeletConfig) {
defaultArguments["feature-gates"] = "DynamicKubeletConfig=true" defaultArguments["feature-gates"] = "DynamicKubeletConfig=true"
} }
......
...@@ -270,8 +270,7 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -270,8 +270,7 @@ func TestGetAPIServerCommand(t *testing.T) {
cfg: &kubeadmapi.InitConfiguration{ cfg: &kubeadmapi.InitConfiguration{
APIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"}, APIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
FeatureGates: map[string]bool{features.HighAvailability: true},
Etcd: kubeadmapi.Etcd{ Etcd: kubeadmapi.Etcd{
External: &kubeadmapi.ExternalEtcd{ External: &kubeadmapi.ExternalEtcd{
Endpoints: []string{"https://8.6.4.1:2379", "https://8.6.4.2:2379"}, Endpoints: []string{"https://8.6.4.1:2379", "https://8.6.4.2:2379"},
...@@ -311,7 +310,6 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -311,7 +310,6 @@ func TestGetAPIServerCommand(t *testing.T) {
"--etcd-cafile=fuz", "--etcd-cafile=fuz",
"--etcd-certfile=fiz", "--etcd-certfile=fiz",
"--etcd-keyfile=faz", "--etcd-keyfile=faz",
fmt.Sprintf("--endpoint-reconciler-type=%s", kubeadmconstants.LeaseEndpointReconcilerType),
}, },
}, },
{ {
...@@ -356,12 +354,12 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -356,12 +354,12 @@ func TestGetAPIServerCommand(t *testing.T) {
}, },
}, },
{ {
name: "auditing and HA are enabled with a custom log max age of 0", name: "auditing is enabled with a custom log max age of 0",
cfg: &kubeadmapi.InitConfiguration{ cfg: &kubeadmapi.InitConfiguration{
APIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"}, APIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
FeatureGates: map[string]bool{features.HighAvailability: true, features.Auditing: true}, FeatureGates: map[string]bool{features.Auditing: true},
CertificatesDir: testCertsDir, CertificatesDir: testCertsDir,
AuditPolicyConfiguration: kubeadmapi.AuditPolicyConfiguration{ AuditPolicyConfiguration: kubeadmapi.AuditPolicyConfiguration{
LogMaxAge: utilpointer.Int32Ptr(0), LogMaxAge: utilpointer.Int32Ptr(0),
...@@ -396,7 +394,6 @@ func TestGetAPIServerCommand(t *testing.T) { ...@@ -396,7 +394,6 @@ func TestGetAPIServerCommand(t *testing.T) {
"--etcd-cafile=" + testCertsDir + "/etcd/ca.crt", "--etcd-cafile=" + testCertsDir + "/etcd/ca.crt",
"--etcd-certfile=" + testCertsDir + "/apiserver-etcd-client.crt", "--etcd-certfile=" + testCertsDir + "/apiserver-etcd-client.crt",
"--etcd-keyfile=" + testCertsDir + "/apiserver-etcd-client.key", "--etcd-keyfile=" + testCertsDir + "/apiserver-etcd-client.key",
fmt.Sprintf("--endpoint-reconciler-type=%s", kubeadmconstants.LeaseEndpointReconcilerType),
"--audit-policy-file=/etc/kubernetes/audit/audit.yaml", "--audit-policy-file=/etc/kubernetes/audit/audit.yaml",
"--audit-log-path=/var/log/kubernetes/audit/audit.log", "--audit-log-path=/var/log/kubernetes/audit/audit.log",
"--audit-log-maxage=0", "--audit-log-maxage=0",
......
...@@ -34,7 +34,6 @@ go_library( ...@@ -34,7 +34,6 @@ go_library(
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/apiclient:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library",
"//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library",
......
...@@ -22,7 +22,6 @@ import ( ...@@ -22,7 +22,6 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
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"
) )
...@@ -59,18 +58,18 @@ func GetDefaultMutators() map[string][]PodSpecMutatorFunc { ...@@ -59,18 +58,18 @@ func GetDefaultMutators() map[string][]PodSpecMutatorFunc {
} }
// GetMutatorsFromFeatureGates returns all mutators needed based on the feature gates passed // GetMutatorsFromFeatureGates returns all mutators needed based on the feature gates passed
func GetMutatorsFromFeatureGates(featureGates map[string]bool) map[string][]PodSpecMutatorFunc { func GetMutatorsFromFeatureGates(certsInSecrets bool) map[string][]PodSpecMutatorFunc {
// Here the map of different mutators to use for the control plane's podspec is stored // Here the map of different mutators to use for the control plane's podspec is stored
mutators := GetDefaultMutators() mutators := GetDefaultMutators()
// Some extra work to be done if we should store the control plane certificates in Secrets if certsInSecrets {
if features.Enabled(featureGates, features.StoreCertsInSecrets) { // Some extra work to be done if we should store the control plane certificates in Secrets
// Add the store-certs-in-secrets-specific mutators here so that the self-hosted component starts using them // Add the store-certs-in-secrets-specific mutators here so that the self-hosted component starts using them
mutators[kubeadmconstants.KubeAPIServer] = append(mutators[kubeadmconstants.KubeAPIServer], setSelfHostedVolumesForAPIServer) mutators[kubeadmconstants.KubeAPIServer] = append(mutators[kubeadmconstants.KubeAPIServer], setSelfHostedVolumesForAPIServer)
mutators[kubeadmconstants.KubeControllerManager] = append(mutators[kubeadmconstants.KubeControllerManager], setSelfHostedVolumesForControllerManager) mutators[kubeadmconstants.KubeControllerManager] = append(mutators[kubeadmconstants.KubeControllerManager], setSelfHostedVolumesForControllerManager)
mutators[kubeadmconstants.KubeScheduler] = append(mutators[kubeadmconstants.KubeScheduler], setSelfHostedVolumesForScheduler) mutators[kubeadmconstants.KubeScheduler] = append(mutators[kubeadmconstants.KubeScheduler], setSelfHostedVolumesForScheduler)
} }
return mutators return mutators
} }
......
...@@ -33,7 +33,6 @@ import ( ...@@ -33,7 +33,6 @@ import (
clientscheme "k8s.io/client-go/kubernetes/scheme" clientscheme "k8s.io/client-go/kubernetes/scheme"
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/util/apiclient" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
) )
...@@ -57,18 +56,16 @@ const ( ...@@ -57,18 +56,16 @@ const (
// 8. In order to avoid race conditions, we have to make sure that static pod is deleted correctly before we continue // 8. In order to avoid race conditions, we have to make sure that static pod is deleted correctly before we continue
// Otherwise, there is a race condition when we proceed without kubelet having restarted the API server correctly and the next .Create call flakes // Otherwise, there is a race condition when we proceed without kubelet having restarted the API server correctly and the next .Create call flakes
// 9. Do that for the kube-apiserver, kube-controller-manager and kube-scheduler in a loop // 9. Do that for the kube-apiserver, kube-controller-manager and kube-scheduler in a loop
func CreateSelfHostedControlPlane(manifestsDir, kubeConfigDir string, cfg *kubeadmapi.InitConfiguration, client clientset.Interface, waiter apiclient.Waiter, dryRun bool) error { func CreateSelfHostedControlPlane(manifestsDir, kubeConfigDir string, cfg *kubeadmapi.InitConfiguration, client clientset.Interface, waiter apiclient.Waiter, dryRun bool, certsInSecrets bool) error {
glog.V(1).Infoln("creating self hosted control plane") glog.V(1).Infoln("creating self hosted control plane")
// Adjust the timeout slightly to something self-hosting specific // Adjust the timeout slightly to something self-hosting specific
waiter.SetTimeout(selfHostingWaitTimeout) waiter.SetTimeout(selfHostingWaitTimeout)
// Here the map of different mutators to use for the control plane's PodSpec is stored // Here the map of different mutators to use for the control plane's PodSpec is stored
glog.V(1).Infoln("getting mutators") glog.V(1).Infoln("getting mutators")
mutators := GetMutatorsFromFeatureGates(cfg.FeatureGates) mutators := GetMutatorsFromFeatureGates(certsInSecrets)
// Some extra work to be done if we should store the control plane certificates in Secrets
if features.Enabled(cfg.FeatureGates, features.StoreCertsInSecrets) {
if certsInSecrets {
// Upload the certificates and kubeconfig files from disk to the cluster as Secrets // Upload the certificates and kubeconfig files from disk to the cluster as Secrets
if err := uploadTLSSecrets(client, cfg.CertificatesDir); err != nil { if err := uploadTLSSecrets(client, cfg.CertificatesDir); err != nil {
return err return err
......
...@@ -8,7 +8,6 @@ go_library( ...@@ -8,7 +8,6 @@ go_library(
"policy.go", "policy.go",
"postupgrade.go", "postupgrade.go",
"prepull.go", "prepull.go",
"selfhosted.go",
"staticpods.go", "staticpods.go",
"versiongetter.go", "versiongetter.go",
], ],
...@@ -30,7 +29,6 @@ go_library( ...@@ -30,7 +29,6 @@ go_library(
"//cmd/kubeadm/app/phases/etcd:go_default_library", "//cmd/kubeadm/app/phases/etcd:go_default_library",
"//cmd/kubeadm/app/phases/kubelet:go_default_library", "//cmd/kubeadm/app/phases/kubelet:go_default_library",
"//cmd/kubeadm/app/phases/patchnode:go_default_library", "//cmd/kubeadm/app/phases/patchnode:go_default_library",
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library", "//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library", "//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
......
...@@ -76,20 +76,11 @@ func CheckClusterHealth(client clientset.Interface, ignoreChecksErrors sets.Stri ...@@ -76,20 +76,11 @@ func CheckClusterHealth(client clientset.Interface, ignoreChecksErrors sets.Stri
// TODO: Add a check for ComponentStatuses here? // TODO: Add a check for ComponentStatuses here?
} }
// Run slightly different health checks depending on control plane hosting type healthChecks = append(healthChecks, &healthCheck{
if IsControlPlaneSelfHosted(client) { name: "StaticPodManifest",
healthChecks = append(healthChecks, &healthCheck{ client: client,
name: "ControlPlaneHealth", f: staticPodManifestHealth,
client: client, })
f: controlPlaneHealth,
})
} else {
healthChecks = append(healthChecks, &healthCheck{
name: "StaticPodManifest",
client: client,
f: staticPodManifestHealth,
})
}
return preflight.RunChecks(healthChecks, os.Stderr, ignoreChecksErrors) return preflight.RunChecks(healthChecks, os.Stderr, ignoreChecksErrors)
} }
...@@ -132,19 +123,6 @@ func masterNodesReady(client clientset.Interface) error { ...@@ -132,19 +123,6 @@ func masterNodesReady(client clientset.Interface) error {
return nil return nil
} }
// controlPlaneHealth ensures all control plane DaemonSets are healthy
func controlPlaneHealth(client clientset.Interface) error {
notReadyDaemonSets, err := getNotReadyDaemonSets(client)
if err != nil {
return err
}
if len(notReadyDaemonSets) != 0 {
return errors.Errorf("there are control plane DaemonSets in the cluster that are not ready: %v", notReadyDaemonSets)
}
return nil
}
// staticPodManifestHealth makes sure the required static pods are presents // staticPodManifestHealth makes sure the required static pods are presents
func staticPodManifestHealth(_ clientset.Interface) error { func staticPodManifestHealth(_ clientset.Interface) error {
nonExistentManifests := []string{} nonExistentManifests := []string{}
...@@ -167,7 +145,7 @@ func IsControlPlaneSelfHosted(client clientset.Interface) bool { ...@@ -167,7 +145,7 @@ func IsControlPlaneSelfHosted(client clientset.Interface) bool {
return false return false
} }
// If there are no NotReady DaemonSets, we are using self-hosting // If there are no NotReady DaemonSets, we are using selfhosting
return len(notReadyDaemonSets) == 0 return len(notReadyDaemonSets) == 0
} }
......
...@@ -42,7 +42,6 @@ import ( ...@@ -42,7 +42,6 @@ import (
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet"
patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig" "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun" dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
...@@ -94,11 +93,6 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon ...@@ -94,11 +93,6 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
errs = append(errs, err) errs = append(errs, err)
} }
// Upgrade to a self-hosted control plane if possible
if err := upgradeToSelfHosting(client, cfg, dryRun); err != nil {
errs = append(errs, err)
}
// TODO: Is this needed to do here? I think that updating cluster info should probably be separate from a normal upgrade // TODO: Is this needed to do here? I think that updating cluster info should probably be separate from a normal upgrade
// Create the cluster-info ConfigMap with the associated RBAC rules // Create the cluster-info ConfigMap with the associated RBAC rules
// if err := clusterinfo.CreateBootstrapConfigMapIfNotExists(client, kubeadmconstants.GetAdminKubeConfigPath()); err != nil { // if err := clusterinfo.CreateBootstrapConfigMapIfNotExists(client, kubeadmconstants.GetAdminKubeConfigPath()); err != nil {
...@@ -160,20 +154,6 @@ func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.InitConfiguration, ...@@ -160,20 +154,6 @@ func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.InitConfiguration,
}, 10) }, 10)
} }
func upgradeToSelfHosting(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, dryRun bool) error {
if features.Enabled(cfg.FeatureGates, features.SelfHosting) && !IsControlPlaneSelfHosted(client) {
waiter := getWaiter(dryRun, client)
// kubeadm will now convert the static Pod-hosted control plane into a self-hosted one
fmt.Println("[self-hosted] Creating self-hosted control plane.")
if err := selfhosting.CreateSelfHostedControlPlane(kubeadmconstants.GetStaticPodDirectory(), kubeadmconstants.KubernetesDir, cfg, client, waiter, dryRun); err != nil {
return pkgerrors.Wrap(err, "error creating self hosted control plane")
}
}
return nil
}
// BackupAPIServerCertIfNeeded rotates the kube-apiserver certificate if older than 180 days // BackupAPIServerCertIfNeeded rotates the kube-apiserver certificate if older than 180 days
func BackupAPIServerCertIfNeeded(cfg *kubeadmapi.InitConfiguration, dryRun bool) error { func BackupAPIServerCertIfNeeded(cfg *kubeadmapi.InitConfiguration, dryRun bool) error {
certAndKeyDir := kubeadmapiv1beta1.DefaultCertificatesDir certAndKeyDir := kubeadmapiv1beta1.DefaultCertificatesDir
...@@ -242,15 +222,6 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon ...@@ -242,15 +222,6 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon
return errors.NewAggregate(errs) return errors.NewAggregate(errs)
} }
// getWaiter gets the right waiter implementation for the right occasion
// TODO: Consolidate this with what's in init.go?
func getWaiter(dryRun bool, client clientset.Interface) apiclient.Waiter {
if dryRun {
return dryrunutil.NewWaiter()
}
return apiclient.NewKubeWaiter(client, 30*time.Minute, os.Stdout)
}
// getKubeletDir gets the kubelet directory based on whether the user is dry-running this command or not. // getKubeletDir gets the kubelet directory based on whether the user is dry-running this command or not.
// TODO: Consolidate this with similar funcs? // TODO: Consolidate this with similar funcs?
func getKubeletDir(dryRun bool) (string, error) { func getKubeletDir(dryRun bool) (string, error) {
......
...@@ -13,7 +13,6 @@ go_test( ...@@ -13,7 +13,6 @@ go_test(
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
...@@ -28,7 +27,6 @@ go_library( ...@@ -28,7 +27,6 @@ go_library(
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/app/util:go_default_library", "//cmd/kubeadm/app/util:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
......
...@@ -32,8 +32,6 @@ import ( ...@@ -32,8 +32,6 @@ import (
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
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/util" "k8s.io/kubernetes/cmd/kubeadm/app/util"
...@@ -240,9 +238,7 @@ func GetProbeAddress(cfg *kubeadmapi.InitConfiguration, componentName string) st ...@@ -240,9 +238,7 @@ func GetProbeAddress(cfg *kubeadmapi.InitConfiguration, componentName string) st
// future hosts that do not have the same address. Furthermore, since liveness and readiness // future hosts that do not have the same address. Furthermore, since liveness and readiness
// probes do not support the Downward API we cannot dynamically set the advertise address to // probes do not support the Downward API we cannot dynamically set the advertise address to
// the node's IP. The only option then is to use localhost. // the node's IP. The only option then is to use localhost.
if features.Enabled(cfg.FeatureGates, features.SelfHosting) { if cfg.APIEndpoint.AdvertiseAddress != "" {
return "127.0.0.1"
} else if cfg.APIEndpoint.AdvertiseAddress != "" {
return cfg.APIEndpoint.AdvertiseAddress return cfg.APIEndpoint.AdvertiseAddress
} }
case componentName == kubeadmconstants.KubeControllerManager: case componentName == kubeadmconstants.KubeControllerManager:
......
...@@ -28,8 +28,6 @@ import ( ...@@ -28,8 +28,6 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
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"
testutil "k8s.io/kubernetes/cmd/kubeadm/test" testutil "k8s.io/kubernetes/cmd/kubeadm/test"
...@@ -68,24 +66,6 @@ func TestComponentProbe(t *testing.T) { ...@@ -68,24 +66,6 @@ func TestComponentProbe(t *testing.T) {
expected: "127.0.0.1", expected: "127.0.0.1",
}, },
{ {
name: "default apiserver advertise address with http",
cfg: &kubeadmapi.InitConfiguration{
APIEndpoint: kubeadmapi.APIEndpoint{
AdvertiseAddress: "1.2.3.4",
},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
features.SelfHosting: true,
},
},
},
component: kubeadmconstants.KubeAPIServer,
port: 1,
path: "foo",
scheme: v1.URISchemeHTTP,
expected: "127.0.0.1",
},
{
name: "default apiserver advertise address with https", name: "default apiserver advertise address with https",
cfg: &kubeadmapi.InitConfiguration{ cfg: &kubeadmapi.InitConfiguration{
APIEndpoint: kubeadmapi.APIEndpoint{ APIEndpoint: kubeadmapi.APIEndpoint{
......
...@@ -35,10 +35,10 @@ docs/admin/kubeadm_alpha_phase_bootstrap-token_node.md ...@@ -35,10 +35,10 @@ docs/admin/kubeadm_alpha_phase_bootstrap-token_node.md
docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md
docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md
docs/admin/kubeadm_alpha_phase_mark-master.md docs/admin/kubeadm_alpha_phase_mark-master.md
docs/admin/kubeadm_alpha_phase_selfhosting.md
docs/admin/kubeadm_alpha_phase_selfhosting_convert-from-staticpods.md
docs/admin/kubeadm_alpha_preflight.md docs/admin/kubeadm_alpha_preflight.md
docs/admin/kubeadm_alpha_preflight_node.md docs/admin/kubeadm_alpha_preflight_node.md
docs/admin/kubeadm_alpha_selfhosting.md
docs/admin/kubeadm_alpha_selfhosting_pivot.md
docs/admin/kubeadm_completion.md docs/admin/kubeadm_completion.md
docs/admin/kubeadm_config.md docs/admin/kubeadm_config.md
docs/admin/kubeadm_config_images.md docs/admin/kubeadm_config_images.md
...@@ -131,11 +131,11 @@ docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node-allow-post-csrs.1 ...@@ -131,11 +131,11 @@ docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node-allow-post-csrs.1
docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node.1
docs/man/man1/kubeadm-alpha-phase-bootstrap-token.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token.1
docs/man/man1/kubeadm-alpha-phase-mark-master.1 docs/man/man1/kubeadm-alpha-phase-mark-master.1
docs/man/man1/kubeadm-alpha-phase-selfhosting-convert-from-staticpods.1
docs/man/man1/kubeadm-alpha-phase-selfhosting.1
docs/man/man1/kubeadm-alpha-phase.1 docs/man/man1/kubeadm-alpha-phase.1
docs/man/man1/kubeadm-alpha-preflight-node.1 docs/man/man1/kubeadm-alpha-preflight-node.1
docs/man/man1/kubeadm-alpha-preflight.1 docs/man/man1/kubeadm-alpha-preflight.1
docs/man/man1/kubeadm-alpha-selfhosting-pivot.1
docs/man/man1/kubeadm-alpha-selfhosting.1
docs/man/man1/kubeadm-alpha.1 docs/man/man1/kubeadm-alpha.1
docs/man/man1/kubeadm-completion.1 docs/man/man1/kubeadm-completion.1
docs/man/man1/kubeadm-config-images-list.1 docs/man/man1/kubeadm-config-images-list.1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment