Merge pull request #69662 from ereslibre/conditional-ipvs-check

kubeadm: Perform IPVS check on join only if the cluster was set up with IPVS
This commit is contained in:
k8s-ci-robot 2018-11-05 10:24:17 -08:00 committed by GitHub
commit b3441e1348
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 53 deletions

View File

@ -289,6 +289,8 @@ func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, ignorePreflightEr
// Join defines struct used by kubeadm join command
type Join struct {
cfg *kubeadmapi.JoinConfiguration
initCfg *kubeadmapi.InitConfiguration
tlsBootstrapCfg *clientcmdapi.Config
ignorePreflightErrors sets.String
}
@ -303,52 +305,44 @@ func NewJoin(cfgPath string, defaultcfg *kubeadmapiv1beta1.JoinConfiguration, ig
glog.V(1).Infoln("[join] found advertiseAddress empty; using default interface's IP address as advertiseAddress")
}
internalcfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig(cfgPath, defaultcfg)
internalCfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig(cfgPath, defaultcfg)
if err != nil {
return nil, err
}
if err := configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress); err != nil {
if err := configutil.VerifyAPIServerBindAddress(internalCfg.APIEndpoint.AdvertiseAddress); err != nil {
return nil, err
}
fmt.Println("[preflight] running pre-flight checks")
fmt.Println("[preflight] Running pre-flight checks")
// Then continue with the others...
glog.V(1).Infoln("[preflight] running various checks on all nodes")
if err := preflight.RunJoinNodeChecks(utilsexec.New(), internalcfg, ignorePreflightErrors); err != nil {
// Start with general checks
glog.V(1).Infoln("[preflight] Running general checks")
if err := preflight.RunJoinNodeChecks(utilsexec.New(), internalCfg, ignorePreflightErrors); err != nil {
return nil, err
}
return &Join{cfg: internalcfg, ignorePreflightErrors: ignorePreflightErrors}, nil
// Fetch the init configuration based on the join configuration
glog.V(1).Infoln("[preflight] Fetching init configuration")
initCfg, tlsBootstrapCfg, err := fetchInitConfigurationFromJoinConfiguration(internalCfg)
if err != nil {
return nil, err
}
// Continue with more specific checks based on the init configuration
glog.V(1).Infoln("[preflight] Running configuration dependant checks")
if err := preflight.RunOptionalJoinNodeChecks(utilsexec.New(), initCfg, ignorePreflightErrors); err != nil {
return nil, err
}
return &Join{cfg: internalCfg, initCfg: initCfg, tlsBootstrapCfg: tlsBootstrapCfg, ignorePreflightErrors: ignorePreflightErrors}, nil
}
// Run executes worker node provisioning and tries to join an existing cluster.
func (j *Join) Run(out io.Writer) error {
// Perform the Discovery, which turns a Bootstrap Token and optionally (and preferably) a CA cert hash into a kubeconfig
// file that may be used for the TLS Bootstrapping process the kubelet performs using the Certificates API.
glog.V(1).Infoln("[join] discovering cluster-info")
tlsBootstrapCfg, err := discovery.For(j.cfg)
if err != nil {
return err
}
// If the node should host a new control plane instance
var initConfiguration *kubeadmapi.InitConfiguration
if j.cfg.ControlPlane == true {
// Retrives the kubeadm configuration used during kubeadm init
glog.V(1).Infoln("[join] retrieving kubeconfig objects")
initConfiguration, err = j.FetchInitConfiguration(tlsBootstrapCfg)
if err != nil {
return err
}
// injects into the kubeadm configuration the information about the joining node
initConfiguration.NodeRegistration = j.cfg.NodeRegistration
initConfiguration.APIEndpoint = j.cfg.APIEndpoint
// Checks if the cluster configuration supports
// joining a new control plane instance and if all the necessary certificates are provided
if err = j.CheckIfReadyForAdditionalControlPlane(initConfiguration); err != nil {
if err := j.CheckIfReadyForAdditionalControlPlane(j.initCfg); err != nil {
// outputs the not ready for hosting a new control plane instance message
ctx := map[string]string{
"Error": err.Error(),
@ -360,12 +354,12 @@ func (j *Join) Run(out io.Writer) error {
}
// run kubeadm init preflight checks for checking all the prequisites
fmt.Printf("[join] running pre-flight checks before initializing the new control plane instance\n")
preflight.RunInitMasterChecks(utilsexec.New(), initConfiguration, j.ignorePreflightErrors)
fmt.Printf("[join] Running pre-flight checks before initializing the new control plane instance\n")
preflight.RunInitMasterChecks(utilsexec.New(), j.initCfg, j.ignorePreflightErrors)
// Prepares the node for hosting a new control plane instance by writing necessary
// kubeconfig files, and static pod manifests
if err = j.PrepareForHostingControlPlane(initConfiguration); err != nil {
if err := j.PrepareForHostingControlPlane(j.initCfg); err != nil {
return err
}
}
@ -376,21 +370,21 @@ func (j *Join) Run(out io.Writer) error {
// if the node is hosting a new control plane instance, since it uses static pods for the control plane,
// as soon as the kubelet starts it will take charge of creating control plane
// components on the node.
if err = j.BootstrapKubelet(tlsBootstrapCfg); err != nil {
if err := j.BootstrapKubelet(j.tlsBootstrapCfg); err != nil {
return err
}
// if the node is hosting a new control plane instance
if j.cfg.ControlPlane == true {
// Completes the control plane setup
if err := j.PostInstallControlPlane(initConfiguration); err != nil {
if err := j.PostInstallControlPlane(j.initCfg); err != nil {
return err
}
// outputs the join control plane done template and exits
etcdMessage := ""
// in case of local etcd
if initConfiguration.Etcd.External == nil {
if j.initCfg.Etcd.External == nil {
etcdMessage = "* A new etcd member was added to the local/stacked etcd cluster."
}
@ -408,23 +402,6 @@ func (j *Join) Run(out io.Writer) error {
return nil
}
// FetchInitConfiguration reads the cluster configuration from the kubeadm-admin configMap,
func (j *Join) FetchInitConfiguration(tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.InitConfiguration, error) {
// creates a client to access the cluster using the bootstrap token identity
tlsClient, err := kubeconfigutil.ToClientSet(tlsBootstrapCfg)
if err != nil {
return nil, errors.Wrap(err, "Unable to access the cluster")
}
// Fetches the init configuration
initConfiguration, err := configutil.FetchConfigFromFileOrCluster(tlsClient, os.Stdout, "join", "", true)
if err != nil {
return nil, errors.Wrap(err, "Unable to fetch the kubeadm-config ConfigMap")
}
return initConfiguration, nil
}
// CheckIfReadyForAdditionalControlPlane ensures that the cluster is in a state that supports
// joining an additional control plane instance and if the node is ready to join
func (j *Join) CheckIfReadyForAdditionalControlPlane(initConfiguration *kubeadmapi.InitConfiguration) error {
@ -624,3 +601,44 @@ func waitForTLSBootstrappedClient() error {
return (err == nil), nil
})
}
// fetchInitConfigurationFromJoinConfiguration retrieves the init configuration from a join configuration, performing the discovery
func fetchInitConfigurationFromJoinConfiguration(cfg *kubeadmapi.JoinConfiguration) (*kubeadmapi.InitConfiguration, *clientcmdapi.Config, error) {
// Perform the Discovery, which turns a Bootstrap Token and optionally (and preferably) a CA cert hash into a KubeConfig
// file that may be used for the TLS Bootstrapping process the kubelet performs using the Certificates API.
glog.V(1).Infoln("[join] Discovering cluster-info")
tlsBootstrapCfg, err := discovery.For(cfg)
if err != nil {
return nil, nil, err
}
// Retrieves the kubeadm configuration
glog.V(1).Infoln("[join] Retrieving KubeConfig objects")
initConfiguration, err := fetchInitConfiguration(tlsBootstrapCfg)
if err != nil {
return nil, nil, err
}
// injects into the kubeadm configuration the information about the joining node
initConfiguration.NodeRegistration = cfg.NodeRegistration
initConfiguration.APIEndpoint = cfg.APIEndpoint
return initConfiguration, tlsBootstrapCfg, nil
}
// fetchInitConfiguration reads the cluster configuration from the kubeadm-admin configMap
func fetchInitConfiguration(tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.InitConfiguration, error) {
// creates a client to access the cluster using the bootstrap token identity
tlsClient, err := kubeconfigutil.ToClientSet(tlsBootstrapCfg)
if err != nil {
return nil, errors.Wrap(err, "unable to access the cluster")
}
// Fetches the init configuration
initConfiguration, err := configutil.FetchConfigFromFileOrCluster(tlsClient, os.Stdout, "join", "", true)
if err != nil {
return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap")
}
return initConfiguration, nil
}

View File

@ -941,7 +941,6 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura
DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)},
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)},
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletBootstrapKubeConfigFileName)},
ipvsutil.RequiredIPVSKernelModulesAvailableCheck{Executor: execer},
}
checks = addCommonChecks(execer, cfg, checks)
if !cfg.ControlPlane {
@ -974,6 +973,20 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura
return RunChecks(checks, os.Stderr, ignorePreflightErrors)
}
// RunOptionalJoinNodeChecks executes all individual, applicable to node configuration dependant checks
func RunOptionalJoinNodeChecks(execer utilsexec.Interface, initCfg *kubeadmapi.InitConfiguration, ignorePreflightErrors sets.String) error {
checks := []Checker{}
// Check ipvs required kernel module if we use ipvs kube-proxy mode
if initCfg.ComponentConfigs.KubeProxy != nil && initCfg.ComponentConfigs.KubeProxy.Mode == ipvsutil.IPVSProxyMode {
checks = append(checks,
ipvsutil.RequiredIPVSKernelModulesAvailableCheck{Executor: execer},
)
}
return RunChecks(checks, os.Stderr, ignorePreflightErrors)
}
// addCommonChecks is a helper function to deplicate checks that are common between both the
// kubeadm init and join commands
func addCommonChecks(execer utilsexec.Interface, cfg kubeadmapi.CommonConfiguration, checks []Checker) []Checker {