diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index ec070e2bd1c..ebfa652645f 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -22,6 +22,7 @@ import ( "html/template" "io" "io/ioutil" + "os" "github.com/renstrom/dedent" "github.com/spf13/cobra" @@ -183,15 +184,26 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight } if !skipPreFlight { - fmt.Println("Running pre-flight checks") - err := preflight.RunInitMasterChecks(cfg) - if err != nil { + fmt.Println("[preflight] Running pre-flight checks...") + + // First, check if we're root separately from the other preflight checks and fail fast + if err := preflight.RunChecks([]preflight.PreFlightCheck{preflight.IsRootCheck{}}, os.Stderr); err != nil { + return nil, &preflight.PreFlightError{Msg: err.Error()} + } + + // Then continue with the others... + if err := preflight.RunInitMasterChecks(cfg); err != nil { return nil, &preflight.PreFlightError{Msg: err.Error()} } } else { fmt.Println("Skipping pre-flight checks") } + // Try to start the kubelet service in case it's inactive + if err := preflight.TryStartKubelet(); err != nil { + return nil, &preflight.PreFlightError{Msg: err.Error()} + } + // validate version argument ver, err := kubeadmutil.KubernetesReleaseVersion(cfg.KubernetesVersion) if err != nil { diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go index b6c7780e973..b5e288926eb 100644 --- a/cmd/kubeadm/app/cmd/join.go +++ b/cmd/kubeadm/app/cmd/join.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "io/ioutil" + "os" "github.com/renstrom/dedent" "github.com/spf13/cobra" @@ -113,15 +114,26 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s } if !skipPreFlight { - fmt.Println("Running pre-flight checks") - err := preflight.RunJoinNodeChecks(cfg) - if err != nil { + fmt.Println("[preflight] Running pre-flight checks...") + + // First, check if we're root separately from the other preflight checks and fail fast + if err := preflight.RunChecks([]preflight.PreFlightCheck{preflight.IsRootCheck{}}, os.Stderr); err != nil { + return nil, &preflight.PreFlightError{Msg: err.Error()} + } + + // Then continue with the others... + if err := preflight.RunJoinNodeChecks(cfg); err != nil { return nil, &preflight.PreFlightError{Msg: err.Error()} } } else { fmt.Println("Skipping pre-flight checks") } + // Try to start the kubelet service in case it's inactive + if err := preflight.TryStartKubelet(); err != nil { + return nil, &preflight.PreFlightError{Msg: err.Error()} + } + ok, err := kubeadmutil.UseGivenTokenIfValid(&cfg.Secrets) if !ok { if err != nil { diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go index 91d2ac131af..bd309b79704 100644 --- a/cmd/kubeadm/app/preflight/checks.go +++ b/cmd/kubeadm/app/preflight/checks.go @@ -51,7 +51,8 @@ type PreFlightCheck interface { // detect a supported init system however, all checks are skipped and a warning is // returned. type ServiceCheck struct { - Service string + Service string + CheckIfActive bool } func (sc ServiceCheck) Check() (warnings, errors []error) { @@ -73,7 +74,7 @@ func (sc ServiceCheck) Check() (warnings, errors []error) { sc.Service, sc.Service)) } - if !initSystem.ServiceIsActive(sc.Service) { + if sc.CheckIfActive && !initSystem.ServiceIsActive(sc.Service) { errors = append(errors, fmt.Errorf("%s service is not active, please run 'systemctl start %s.service'", sc.Service, sc.Service)) @@ -128,7 +129,7 @@ func (poc PortOpenCheck) Check() (warnings, errors []error) { } // IsRootCheck verifies user is root -type IsRootCheck struct {} +type IsRootCheck struct{} func (irc IsRootCheck) Check() (warnings, errors []error) { errors = []error{} @@ -260,8 +261,8 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { SystemVerificationCheck{}, IsRootCheck{}, HostnameCheck{}, - ServiceCheck{Service: "kubelet"}, - ServiceCheck{Service: "docker"}, + ServiceCheck{Service: "kubelet", CheckIfActive: false}, + ServiceCheck{Service: "docker", CheckIfActive: true}, FirewalldCheck{ports: []int{int(cfg.API.BindPort), int(cfg.Discovery.BindPort), 10250}}, PortOpenCheck{port: int(cfg.API.BindPort)}, PortOpenCheck{port: 8080}, @@ -302,8 +303,8 @@ func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error { SystemVerificationCheck{}, IsRootCheck{}, HostnameCheck{}, - ServiceCheck{Service: "docker"}, - ServiceCheck{Service: "kubelet"}, + ServiceCheck{Service: "kubelet", CheckIfActive: false}, + ServiceCheck{Service: "docker", CheckIfActive: true}, PortOpenCheck{port: 10250}, HTTPProxyCheck{Proto: "https", Host: cfg.MasterAddresses[0], Port: int(cfg.APIPort)}, HTTPProxyCheck{Proto: "http", Host: cfg.MasterAddresses[0], Port: int(cfg.DiscoveryPort)}, @@ -346,3 +347,17 @@ func RunChecks(checks []PreFlightCheck, ww io.Writer) error { } return nil } + +func TryStartKubelet() error { + // If we notice that the kubelet service is inactive, try to start it + initSystem, err := initsystem.GetInitSystem() + if err != nil { + fmt.Println("[preflight] No supported init system detected, won't check if kubelet is running") + } else if !initSystem.ServiceIsActive("kubelet") { + fmt.Printf("[preflight] Starting the kubelet service by running %q\n", "systemctl start kubelet") + if err := initSystem.ServiceStart("kubelet"); err != nil { + return fmt.Errorf("Couldn't start the kubelet service. Please start the kubelet service manually and try again.") + } + } + return nil +}