kubeadm graduate upload-config phase

pull/58/head
Yago Nobre 2018-10-30 01:12:37 -03:00
parent c2aa35866c
commit 79f1b66f4e
No known key found for this signature in database
GPG Key ID: 09AE6CEC2B8E9DD3
13 changed files with 123 additions and 193 deletions

View File

@ -55,7 +55,6 @@ func newCmdPhase(out io.Writer) *cobra.Command {
cmd.AddCommand(phases.NewCmdBootstrapToken())
cmd.AddCommand(phases.NewCmdMarkMaster())
cmd.AddCommand(phases.NewCmdSelfhosting())
cmd.AddCommand(phases.NewCmdUploadConfig())
return cmd
}

View File

@ -50,9 +50,7 @@ import (
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet"
markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster"
patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode"
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"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
@ -183,6 +181,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
initRunner.AppendPhase(phases.NewControlPlanePhase())
initRunner.AppendPhase(phases.NewEtcdPhase())
initRunner.AppendPhase(phases.NewWaitControlPlanePhase())
initRunner.AppendPhase(phases.NewUploadConfigPhase())
// TODO: add other phases to the runner.
// sets the data builder function, that will be used by the runner
@ -487,30 +486,12 @@ func runInit(i *initData, out io.Writer) error {
return errors.Wrap(err, "failed to create waiter")
}
// Upload currently used configuration to the cluster
// Note: This is done right in the beginning of cluster initialization; as we might want to make other phases
// depend on centralized information from this source in the future
glog.V(1).Infof("[init] uploading currently used configuration to the cluster")
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
glog.V(1).Infof("[init] marking the master with right label")
if err := markmasterphase.MarkMaster(client, i.cfg.NodeRegistration.Name, i.cfg.NodeRegistration.Taints); err != nil {
return errors.Wrap(err, "error marking master")
}
glog.V(1).Infof("[init] preserving the crisocket information for the master")
if err := patchnodephase.AnnotateCRISocket(client, i.cfg.NodeRegistration.Name, i.cfg.NodeRegistration.CRISocket); err != nil {
return errors.Wrap(err, "error uploading crisocket")
}
// This feature is disabled by default
if features.Enabled(i.cfg.FeatureGates, features.DynamicKubeletConfig) {
kubeletVersion, err := preflight.GetKubeletVersion(utilsexec.New())

View File

@ -19,18 +19,10 @@ package phases
import (
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
"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/constants"
kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet"
patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/pkg/util/normalizer"
)
@ -39,24 +31,6 @@ var (
# Writes a dynamic environment file with kubelet flags from a InitConfiguration file.
kubeadm init phase kubelet-start --config masterconfig.yaml
`)
kubeletConfigUploadLongDesc = normalizer.LongDesc(`
Uploads kubelet configuration extracted from the kubeadm InitConfiguration object to a ConfigMap
of the form kubelet-config-1.X in the cluster, where X is the minor version of the current (API Server) Kubernetes version.
` + cmdutil.AlphaDisclaimer)
kubeletConfigUploadExample = normalizer.Examples(`
# Uploads the kubelet configuration from the kubeadm Config file to a ConfigMap in the cluster.
kubeadm alpha phase kubelet config upload --config kubeadm.yaml
`)
kubeletConfigAnnotateCRILongDesc = normalizer.LongDesc(`
Adds an annotation to the current node with the CRI socket specified in the kubeadm InitConfiguration object.
` + cmdutil.AlphaDisclaimer)
kubeletConfigAnnotateCRIExample = normalizer.Examples(`
kubeadm alpha phase kubelet config annotate-cri --config kubeadm.yaml
`)
)
// kubeletStartData defines the behavior that a runtime data struct passed to the kubelet start phase
@ -118,104 +92,3 @@ func runKubeletStart(c workflow.RunData) error {
return nil
}
// NewCmdKubelet returns command for `kubeadm phase kubelet`
func NewCmdKubelet() *cobra.Command {
cmd := &cobra.Command{
Use: "kubelet",
Short: "Commands related to handling the kubelet.",
Long: cmdutil.MacroCommandLongDescription,
}
cmd.AddCommand(NewCmdKubeletConfig())
return cmd
}
// NewCmdKubeletConfig returns command for `kubeadm phase kubelet config`
func NewCmdKubeletConfig() *cobra.Command {
cmd := &cobra.Command{
Use: "config",
Short: "Handles kubelet configuration.",
Long: cmdutil.MacroCommandLongDescription,
}
cmd.AddCommand(NewCmdKubeletConfigUpload())
cmd.AddCommand(NewCmdKubeletAnnotateCRI())
return cmd
}
// NewCmdKubeletConfigUpload calls cobra.Command for uploading dynamic kubelet configuration
func NewCmdKubeletConfigUpload() *cobra.Command {
cfg := &kubeadmapiv1beta1.InitConfiguration{}
var cfgPath string
kubeConfigFile := constants.GetAdminKubeConfigPath()
cmd := &cobra.Command{
Use: "upload",
Short: "Uploads kubelet configuration to a ConfigMap based on a kubeadm InitConfiguration file.",
Long: kubeletConfigUploadLongDesc,
Example: kubeletConfigUploadExample,
Run: func(cmd *cobra.Command, args []string) {
if len(cfgPath) == 0 {
kubeadmutil.CheckErr(errors.New("The --config argument is required"))
}
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
SetKubernetesVersion(cfg)
// This call returns the ready-to-use configuration based on the configuration file
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
kubeadmutil.CheckErr(err)
kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile)
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
kubeadmutil.CheckErr(err)
err = kubeletphase.CreateConfigMap(internalcfg, client)
kubeadmutil.CheckErr(err)
},
}
options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile)
options.AddConfigFlag(cmd.Flags(), &cfgPath)
return cmd
}
// NewCmdKubeletAnnotateCRI calls cobra.Command for annotating the node with the given crisocket
func NewCmdKubeletAnnotateCRI() *cobra.Command {
cfg := &kubeadmapiv1beta1.InitConfiguration{}
var cfgPath string
kubeConfigFile := constants.GetAdminKubeConfigPath()
cmd := &cobra.Command{
Use: "annotate-cri",
Short: "annotates the node with the given crisocket",
Long: kubeletConfigAnnotateCRILongDesc,
Example: kubeletConfigAnnotateCRIExample,
Run: func(cmd *cobra.Command, args []string) {
if len(cfgPath) == 0 {
kubeadmutil.CheckErr(errors.New("The --config argument is required"))
}
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
SetKubernetesVersion(cfg)
// This call returns the ready-to-use configuration based on the configuration file
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
kubeadmutil.CheckErr(err)
kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile)
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
kubeadmutil.CheckErr(err)
err = patchnodephase.AnnotateCRISocket(client, internalcfg.NodeRegistration.Name, internalcfg.NodeRegistration.CRISocket)
kubeadmutil.CheckErr(err)
},
}
options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile)
options.AddConfigFlag(cmd.Flags(), &cfgPath)
return cmd
}

View File

@ -19,70 +19,127 @@ package phases
import (
"fmt"
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
clientset "k8s.io/client-go/kubernetes"
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"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
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"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/pkg/util/normalizer"
)
var (
uploadConfigLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Uploads the kubeadm init configuration of your cluster to a ConfigMap called %s in the %s namespace.
uploadKubeadmConfigLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Uploads the kubeadm ClusterConfiguration to a ConfigMap called %s in the %s namespace.
This enables correct configuration of system components and a seamless user experience when upgrading.
Alternatively, you can use kubeadm config.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.KubeadmConfigConfigMap, metav1.NamespaceSystem)
`), kubeadmconstants.KubeadmConfigConfigMap, metav1.NamespaceSystem)
uploadConfigExample = normalizer.Examples(`
uploadKubeadmConfigExample = normalizer.Examples(`
# uploads the configuration of your cluster
kubeadm alpha phase upload-config --config=myConfig.yaml
`)
uploadKubeletConfigLongDesc = normalizer.LongDesc(`
Uploads kubelet configuration extracted from the kubeadm InitConfiguration object to a ConfigMap
of the form kubelet-config-1.X in the cluster, where X is the minor version of the current (API Server) Kubernetes version.
`)
uploadKubeletConfigExample = normalizer.Examples(`
# Uploads the kubelet configuration from the kubeadm Config file to a ConfigMap in the cluster.
kubeadm init phase upload-config kubelet --config kubeadm.yaml
`)
)
// NewCmdUploadConfig returns the Cobra command for running the uploadconfig phase
func NewCmdUploadConfig() *cobra.Command {
cfg := &kubeadmapiv1beta1.InitConfiguration{}
kubeConfigFile := kubeadmconstants.GetAdminKubeConfigPath()
var cfgPath string
type uploadConfigData interface {
Cfg() *kubeadmapi.InitConfiguration
Client() (clientset.Interface, error)
}
cmd := &cobra.Command{
Use: "upload-config",
Short: "Uploads the currently used configuration for kubeadm to a ConfigMap",
Long: uploadConfigLongDesc,
Example: uploadConfigExample,
// NewUploadConfigPhase returns the phase to uploadConfig
func NewUploadConfigPhase() workflow.Phase {
return workflow.Phase{
Name: "upload-config",
Aliases: []string{"uploadconfig"},
Run: func(_ *cobra.Command, args []string) {
if len(cfgPath) == 0 {
kubeadmutil.CheckErr(errors.New("the --config flag is mandatory"))
}
kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile)
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
kubeadmutil.CheckErr(err)
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
SetKubernetesVersion(cfg)
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
kubeadmutil.CheckErr(err)
err = uploadconfig.UploadConfiguration(internalcfg, client)
kubeadmutil.CheckErr(err)
Short: "Uploads the kubeadm and kubelet configuration to a ConfigMap",
Long: cmdutil.MacroCommandLongDescription,
Phases: []workflow.Phase{
{
Name: "kubeadm",
Short: "Uploads the kubeadm ClusterConfiguration to a ConfigMap",
Long: uploadKubeadmConfigLongDesc,
Example: uploadKubeadmConfigExample,
Run: runUploadKubeadmConfig,
CmdFlags: getUploadConfigPhaseFlags(),
},
{
Name: "kubelet",
Short: "Uploads the kubelet component config to a ConfigMap",
Long: uploadKubeletConfigLongDesc,
Example: uploadKubeletConfigExample,
Run: runUploadKubeletConfig,
CmdFlags: getUploadConfigPhaseFlags(),
},
},
}
options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile)
cmd.Flags().StringVar(&cfgPath, "config", "", "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental")
return cmd
}
func getUploadConfigPhaseFlags() []string {
return []string{
options.CfgPath,
options.KubeconfigPath,
}
}
// runUploadKubeadmConfig uploads the kubeadm configuration to a ConfigMap
func runUploadKubeadmConfig(c workflow.RunData) error {
cfg, client, err := getUploadConfigData(c)
if err != nil {
return err
}
glog.V(1).Infof("[upload-config] Uploading the kubeadm ClusterConfiguration to a ConfigMap")
if err := uploadconfig.UploadConfiguration(cfg, client); err != nil {
return errors.Wrap(err, "error uploading the kubeadm ClusterConfiguration")
}
return nil
}
// runUploadKubeletConfig uploads the kubelet configuration to a ConfigMap
func runUploadKubeletConfig(c workflow.RunData) error {
cfg, client, err := getUploadConfigData(c)
if err != nil {
return err
}
glog.V(1).Infof("[upload-config] Uploading the kubelet component config to a ConfigMap")
if err = kubeletphase.CreateConfigMap(cfg, client); err != nil {
return errors.Wrap(err, "error creating kubelet configuration ConfigMap")
}
glog.V(1).Infof("[upload-config] Preserving the CRISocket information for the control-plane node")
if err := patchnodephase.AnnotateCRISocket(client, cfg.NodeRegistration.Name, cfg.NodeRegistration.CRISocket); err != nil {
return errors.Wrap(err, "Error writing Crisocket information for the control-plane node")
}
return nil
}
func getUploadConfigData(c workflow.RunData) (*kubeadmapi.InitConfiguration, clientset.Interface, error) {
data, ok := c.(uploadConfigData)
if !ok {
return nil, nil, errors.New("upload-config phase invoked with an invalid data struct")
}
cfg := data.Cfg()
client, err := data.Client()
if err != nil {
return nil, nil, err
}
return cfg, client, err
}

View File

@ -24,6 +24,9 @@ type Phase struct {
// the same workflow or phases belonging to the same parent phase).
Name string
// Aliases returns the aliases for the phase.
Aliases []string
// Short description of the phase.
Short string

View File

@ -312,6 +312,7 @@ func (e *Runner) BindToCommand(cmd *cobra.Command) {
Short: p.Short,
Long: p.Long,
Example: p.Example,
Aliases: p.Aliases,
Run: func(cmd *cobra.Command, args []string) {
e.Options.FilterPhases = []string{p.generatedName}
if err := e.Run(); err != nil {

View File

@ -37,7 +37,6 @@ 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_selfhosting.md
docs/admin/kubeadm_alpha_phase_selfhosting_convert-from-staticpods.md
docs/admin/kubeadm_alpha_phase_upload-config.md
docs/admin/kubeadm_alpha_preflight.md
docs/admin/kubeadm_alpha_preflight_node.md
docs/admin/kubeadm_completion.md
@ -80,6 +79,9 @@ docs/admin/kubeadm_init_phase_kubeconfig_kubelet.md
docs/admin/kubeadm_init_phase_kubeconfig_scheduler.md
docs/admin/kubeadm_init_phase_kubelet-start.md
docs/admin/kubeadm_init_phase_preflight.md
docs/admin/kubeadm_init_phase_upload-config.md
docs/admin/kubeadm_init_phase_upload-config_kubeadm.md
docs/admin/kubeadm_init_phase_upload-config_kubelet.md
docs/admin/kubeadm_join.md
docs/admin/kubeadm_reset.md
docs/admin/kubeadm_token.md
@ -131,7 +133,6 @@ docs/man/man1/kubeadm-alpha-phase-bootstrap-token.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-upload-config.1
docs/man/man1/kubeadm-alpha-phase.1
docs/man/man1/kubeadm-alpha-preflight-node.1
docs/man/man1/kubeadm-alpha-preflight.1
@ -175,6 +176,9 @@ docs/man/man1/kubeadm-init-phase-kubeconfig-scheduler.1
docs/man/man1/kubeadm-init-phase-kubeconfig.1
docs/man/man1/kubeadm-init-phase-kubelet-start.1
docs/man/man1/kubeadm-init-phase-preflight.1
docs/man/man1/kubeadm-init-phase-upload-config-kubeadm.1
docs/man/man1/kubeadm-init-phase-upload-config-kubelet.1
docs/man/man1/kubeadm-init-phase-upload-config.1
docs/man/man1/kubeadm-init-phase.1
docs/man/man1/kubeadm-init.1
docs/man/man1/kubeadm-join.1

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.