diff --git a/cmd/kubeadm/app/cmd/config.go b/cmd/kubeadm/app/cmd/config.go index e3967f93ae107..f4ff47c7cacd3 100644 --- a/cmd/kubeadm/app/cmd/config.go +++ b/cmd/kubeadm/app/cmd/config.go @@ -27,6 +27,7 @@ import ( clientset "k8s.io/client-go/kubernetes" kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1" "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/features" "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" @@ -128,6 +129,8 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C cfg := &kubeadmapiext.MasterConfiguration{} api.Scheme.Default(cfg) + var featureFlagsString string + cmd := &cobra.Command{ Use: "from-flags", Short: "Create the in-cluster configuration file for the first time from using flags", @@ -137,6 +140,11 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C same flags before upgrading to v1.8 using 'kubeadm upgrade'. `), metav1.NamespaceSystem, constants.MasterConfigurationConfigMap), Run: func(cmd *cobra.Command, args []string) { + var err error + if cfg.FeatureFlags, err = features.NewFeatureGate(&features.InitFeatureGates, featureFlagsString); err != nil { + kubeadmutil.CheckErr(err) + } + client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile) kubeadmutil.CheckErr(err) @@ -146,7 +154,7 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C kubeadmutil.CheckErr(err) }, } - AddInitConfigFlags(cmd.PersistentFlags(), cfg) + AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureFlagsString) return cmd } diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index 2a409d9b75492..1914b7284e5b8 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -21,6 +21,7 @@ import ( "io" "io/ioutil" "os" + "strings" "text/template" "time" @@ -33,8 +34,8 @@ import ( kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" - "k8s.io/kubernetes/cmd/kubeadm/app/cmd/features" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/features" dnsaddonphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns" proxyaddonphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy" apiconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig" @@ -89,10 +90,17 @@ func NewCmdInit(out io.Writer) *cobra.Command { var skipPreFlight bool var skipTokenPrint bool var dryRun bool + var featureFlagsString string + cmd := &cobra.Command{ Use: "init", Short: "Run this in order to set up the Kubernetes master", Run: func(cmd *cobra.Command, args []string) { + var err error + if cfg.FeatureFlags, err = features.NewFeatureGate(&features.InitFeatureGates, featureFlagsString); err != nil { + kubeadmutil.CheckErr(err) + } + api.Scheme.Default(cfg) internalcfg := &kubeadmapi.MasterConfiguration{} api.Scheme.Convert(cfg, internalcfg, nil) @@ -110,14 +118,14 @@ func NewCmdInit(out io.Writer) *cobra.Command { }, } - AddInitConfigFlags(cmd.PersistentFlags(), cfg) + AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureFlagsString) AddInitOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &skipTokenPrint, &dryRun) return cmd } // AddInitConfigFlags adds init flags bound to the config to the specified flagset -func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfiguration) { +func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfiguration, featureFlagsString *string) { flagSet.StringVar( &cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address the API Server will advertise it's listening on. 0.0.0.0 means the default network interface's address.", @@ -162,6 +170,8 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfigur &cfg.TokenTTL, "token-ttl", cfg.TokenTTL, "The duration before the bootstrap token is automatically deleted. 0 means 'never expires'.", ) + flagSet.StringVar(featureFlagsString, "feature-gates", *featureFlagsString, "A set of key=value pairs that describe feature gates for various features. "+ + "Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n")) } // AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset diff --git a/cmd/kubeadm/app/cmd/phases/selfhosting.go b/cmd/kubeadm/app/cmd/phases/selfhosting.go index 2cd4ca1475963..8e3f8d80e0174 100644 --- a/cmd/kubeadm/app/cmd/phases/selfhosting.go +++ b/cmd/kubeadm/app/cmd/phases/selfhosting.go @@ -17,10 +17,13 @@ limitations under the License. package phases import ( + "strings" + "github.com/spf13/cobra" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1" + "k8s.io/kubernetes/cmd/kubeadm/app/features" "k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" @@ -29,13 +32,19 @@ import ( // NewCmdSelfhosting returns the self-hosting Cobra command func NewCmdSelfhosting() *cobra.Command { - var kubeConfigFile string + var kubeConfigFile, featureFlagsString string cfg := &kubeadmapiext.MasterConfiguration{} cmd := &cobra.Command{ Use: "selfhosting", Aliases: []string{"selfhosted"}, Short: "Make a kubeadm cluster self-hosted.", Run: func(cmd *cobra.Command, args []string) { + + var err error + if cfg.FeatureFlags, err = features.NewFeatureGate(&features.InitFeatureGates, featureFlagsString); err != nil { + kubeadmutil.CheckErr(err) + } + api.Scheme.Default(cfg) internalcfg := &kubeadmapi.MasterConfiguration{} api.Scheme.Convert(cfg, internalcfg, nil) @@ -48,5 +57,8 @@ func NewCmdSelfhosting() *cobra.Command { } cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster") + cmd.Flags().StringVar(&featureFlagsString, "feature-gates", featureFlagsString, "A set of key=value pairs that describe feature gates for various features."+ + "Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n")) + return cmd }