func JoinNodesToCluster(mgr *manager.Manager, node *kubekeyapiv1alpha1.HostCfg) error {
	if !manager.ExistNode(mgr, node) {
		if err := generateKubeadmConfig(mgr, node, false, mgr.ClusterStatus.BootstrapToken, mgr.ClusterStatus.CertificateKey); err != nil {
			return err
		}
		resetCmd := "/usr/local/bin/kubeadm reset -f"
		if mgr.ContainerRuntimeEndpoint != "" {
			resetCmd = resetCmd + " --cri-socket " + mgr.ContainerRuntimeEndpoint
		}
		for i := 0; i < 3; i++ {
			_, err := mgr.Runner.ExecuteCmd("sudo env PATH=$PATH:/sbin:/usr/sbin /bin/sh -c \"/usr/local/bin/kubeadm join --config=/etc/kubernetes/kubeadm-config.yaml\"", 0, true)
			if err != nil {
				if i == 2 {
					return errors.Wrap(errors.WithStack(err), "Failed to add master to cluster")
				}
				_, _ = mgr.Runner.ExecuteCmd(fmt.Sprintf("sudo env PATH=$PATH:/sbin:/usr/sbin /bin/sh -c \"%s\"", resetCmd), 0, true)
			} else {
				break
			}
		}
		if node.IsMaster {
			if err := GetKubeConfigForControlPlane(mgr); err != nil {
				return err
			}
			if err := removeMasterTaint(mgr, node); err != nil {
				return err
			}
			if err := InstallK8sCertsRenew(mgr); err != nil {
				return err
			}
		}
		if node.IsWorker && !node.IsMaster {
			if err := getKubeConfigForWorker(mgr); err != nil {
				return err
			}
		}
		if err := addWorkerLabel(mgr, node); err != nil {
			return err
		}
	}
	return nil
}
JoinNodesToCluster is used to join node to Cluster.
package kubernetes
import (
	"encoding/base64"
	"fmt"
	"github.com/kubesphere/kubekey/pkg/kubernetes/config/v1beta2"
	"io/ioutil"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
	kubekeyapiv1alpha1 "github.com/kubesphere/kubekey/apis/kubekey/v1alpha1"
	"github.com/kubesphere/kubekey/pkg/plugins/dns"
	"github.com/kubesphere/kubekey/pkg/util"
	"github.com/kubesphere/kubekey/pkg/util/manager"
	"github.com/pkg/errors"
)
func GetClusterStatus(mgr *manager.Manager, _ *kubekeyapiv1alpha1.HostCfg) error {
	output, err := mgr.Runner.ExecuteCmd("sudo -E /bin/sh -c \"[ -f /etc/kubernetes/admin.conf ] && echo 'Cluster already exists.' || echo 'Cluster will be created.'\"", 0, false)
	if strings.Contains(output, "Cluster will be created") {
		return nil
	} else {
		if err != nil {
			return errors.Wrap(errors.WithStack(err), "Failed to find /etc/kubernetes/admin.conf")
		}
		mgr.ClusterStatus.IsExist = true
		if output, err := mgr.Runner.ExecuteCmd("sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep 'image:' | awk -F '[:]' '{print $(NF-0)}'", 0, false); err != nil {
			return errors.Wrap(errors.WithStack(err), "Failed to find current version")
		} else {
			if !strings.Contains(output, "No such file or directory") {
				mgr.ClusterStatus.Version = output
			}
		}
		if err := loadKubeConfig(mgr); err != nil {
			return err
		}
		if err := getClusterInfo(mgr); err != nil {
			return err
		}
		checkKubeadmConfig, err := mgr.Runner.ExecuteCmd("sudo -E /bin/sh -c \"cat /etc/kubernetes/kubeadm-config.yaml\"", 0, false)
		if err != nil {
			return errors.Wrap(errors.WithStack(err), "Failed to find /etc/kubernetes/kubeadm-config.yaml")
		}
		if (mgr.ClusterStatus.BootstrapToken == "" || mgr.ClusterStatus.CertificateKey == "") && (strings.Contains(checkKubeadmConfig, "InitConfiguration") || strings.Contains(checkKubeadmConfig, "ClusterConfiguration")) {
			if err := getJoinInfo(mgr); err != nil {
				return err
			}
		}
	}
	return nil
}
func InitKubernetesCluster(mgr *manager.Manager, node *kubekeyapiv1alpha1.HostCfg) error {
	if mgr.Runner.Index == 0 && !mgr.ClusterStatus.IsExist {
		if err := generateKubeadmConfig(mgr, node, manager.IsInitCluster, "", ""); err != nil {
			return err
		}
		resetCmd := "/usr/local/bin/kubeadm reset -f"
		if mgr.ContainerRuntimeEndpoint != "" {
			resetCmd = resetCmd + " --cri-socket " + mgr.ContainerRuntimeEndpoint
		}
		for i := 0; i < 3; i++ {
			_, err2 := mgr.Runner.ExecuteCmd("sudo env PATH=$PATH:/sbin:/usr/sbin /bin/sh -c \"/usr/local/bin/kubeadm init --config=/etc/kubernetes/kubeadm-config.yaml --ignore-preflight-errors=FileExisting-crictl\"", 0, true)
			if err2 != nil {
				if i == 2 {
					return errors.Wrap(errors.WithStack(err2), "Failed to init kubernetes cluster")
				}
				_, _ = mgr.Runner.ExecuteCmd(fmt.Sprintf("sudo env PATH=$PATH:/sbin:/usr/sbin /bin/sh -c \"%s\"", resetCmd), 0, true)
			} else {
				break
			}
		}
		if err := GetKubeConfigForControlPlane(mgr); err != nil {
			return err
		}
		if err := removeMasterTaint(mgr, node); err != nil {
			return err
		}
		if err := addWorkerLabel(mgr, node); err != nil {
			return err
		}
		if err := dns.CreateClusterDns(mgr); err != nil {
			return err
		}
		if err := InstallK8sCertsRenew(mgr); err != nil {
			return err
		}
	}
	return nil
}