mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 06:27:05 +00:00
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:
commit
b3441e1348
@ -289,6 +289,8 @@ func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, ignorePreflightEr
|
|||||||
// Join defines struct used by kubeadm join command
|
// Join defines struct used by kubeadm join command
|
||||||
type Join struct {
|
type Join struct {
|
||||||
cfg *kubeadmapi.JoinConfiguration
|
cfg *kubeadmapi.JoinConfiguration
|
||||||
|
initCfg *kubeadmapi.InitConfiguration
|
||||||
|
tlsBootstrapCfg *clientcmdapi.Config
|
||||||
ignorePreflightErrors sets.String
|
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")
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress); err != nil {
|
if err := configutil.VerifyAPIServerBindAddress(internalCfg.APIEndpoint.AdvertiseAddress); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[preflight] running pre-flight checks")
|
fmt.Println("[preflight] Running pre-flight checks")
|
||||||
|
|
||||||
// Then continue with the others...
|
// Start with general checks
|
||||||
glog.V(1).Infoln("[preflight] running various checks on all nodes")
|
glog.V(1).Infoln("[preflight] Running general checks")
|
||||||
if err := preflight.RunJoinNodeChecks(utilsexec.New(), internalcfg, ignorePreflightErrors); err != nil {
|
if err := preflight.RunJoinNodeChecks(utilsexec.New(), internalCfg, ignorePreflightErrors); err != nil {
|
||||||
return nil, err
|
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.
|
// Run executes worker node provisioning and tries to join an existing cluster.
|
||||||
func (j *Join) Run(out io.Writer) error {
|
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 {
|
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
|
// Checks if the cluster configuration supports
|
||||||
// joining a new control plane instance and if all the necessary certificates are provided
|
// 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
|
// outputs the not ready for hosting a new control plane instance message
|
||||||
ctx := map[string]string{
|
ctx := map[string]string{
|
||||||
"Error": err.Error(),
|
"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
|
// 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")
|
fmt.Printf("[join] Running pre-flight checks before initializing the new control plane instance\n")
|
||||||
preflight.RunInitMasterChecks(utilsexec.New(), initConfiguration, j.ignorePreflightErrors)
|
preflight.RunInitMasterChecks(utilsexec.New(), j.initCfg, j.ignorePreflightErrors)
|
||||||
|
|
||||||
// Prepares the node for hosting a new control plane instance by writing necessary
|
// Prepares the node for hosting a new control plane instance by writing necessary
|
||||||
// kubeconfig files, and static pod manifests
|
// kubeconfig files, and static pod manifests
|
||||||
if err = j.PrepareForHostingControlPlane(initConfiguration); err != nil {
|
if err := j.PrepareForHostingControlPlane(j.initCfg); err != nil {
|
||||||
return err
|
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,
|
// 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
|
// as soon as the kubelet starts it will take charge of creating control plane
|
||||||
// components on the node.
|
// components on the node.
|
||||||
if err = j.BootstrapKubelet(tlsBootstrapCfg); err != nil {
|
if err := j.BootstrapKubelet(j.tlsBootstrapCfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the node is hosting a new control plane instance
|
// if the node is hosting a new control plane instance
|
||||||
if j.cfg.ControlPlane == true {
|
if j.cfg.ControlPlane == true {
|
||||||
// Completes the control plane setup
|
// Completes the control plane setup
|
||||||
if err := j.PostInstallControlPlane(initConfiguration); err != nil {
|
if err := j.PostInstallControlPlane(j.initCfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// outputs the join control plane done template and exits
|
// outputs the join control plane done template and exits
|
||||||
etcdMessage := ""
|
etcdMessage := ""
|
||||||
// in case of local etcd
|
// 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."
|
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
|
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
|
// 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
|
// joining an additional control plane instance and if the node is ready to join
|
||||||
func (j *Join) CheckIfReadyForAdditionalControlPlane(initConfiguration *kubeadmapi.InitConfiguration) error {
|
func (j *Join) CheckIfReadyForAdditionalControlPlane(initConfiguration *kubeadmapi.InitConfiguration) error {
|
||||||
@ -624,3 +601,44 @@ func waitForTLSBootstrappedClient() error {
|
|||||||
return (err == nil), nil
|
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
|
||||||
|
}
|
||||||
|
@ -941,7 +941,6 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura
|
|||||||
DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)},
|
DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)},
|
||||||
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)},
|
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)},
|
||||||
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletBootstrapKubeConfigFileName)},
|
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletBootstrapKubeConfigFileName)},
|
||||||
ipvsutil.RequiredIPVSKernelModulesAvailableCheck{Executor: execer},
|
|
||||||
}
|
}
|
||||||
checks = addCommonChecks(execer, cfg, checks)
|
checks = addCommonChecks(execer, cfg, checks)
|
||||||
if !cfg.ControlPlane {
|
if !cfg.ControlPlane {
|
||||||
@ -974,6 +973,20 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura
|
|||||||
return RunChecks(checks, os.Stderr, ignorePreflightErrors)
|
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
|
// addCommonChecks is a helper function to deplicate checks that are common between both the
|
||||||
// kubeadm init and join commands
|
// kubeadm init and join commands
|
||||||
func addCommonChecks(execer utilsexec.Interface, cfg kubeadmapi.CommonConfiguration, checks []Checker) []Checker {
|
func addCommonChecks(execer utilsexec.Interface, cfg kubeadmapi.CommonConfiguration, checks []Checker) []Checker {
|
||||||
|
Loading…
Reference in New Issue
Block a user