kubeadm: use the CRI for preflights checks

parent ce910f24
...@@ -59,6 +59,7 @@ import ( ...@@ -59,6 +59,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin" "k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/util/version" "k8s.io/kubernetes/pkg/util/version"
utilsexec "k8s.io/utils/exec"
) )
var ( var (
...@@ -110,6 +111,7 @@ func NewCmdInit(out io.Writer) *cobra.Command { ...@@ -110,6 +111,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
var skipTokenPrint bool var skipTokenPrint bool
var dryRun bool var dryRun bool
var featureGatesString string var featureGatesString string
var criSocket string
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "init", Use: "init",
...@@ -124,7 +126,7 @@ func NewCmdInit(out io.Writer) *cobra.Command { ...@@ -124,7 +126,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
internalcfg := &kubeadmapi.MasterConfiguration{} internalcfg := &kubeadmapi.MasterConfiguration{}
legacyscheme.Scheme.Convert(cfg, internalcfg, nil) legacyscheme.Scheme.Convert(cfg, internalcfg, nil)
i, err := NewInit(cfgPath, internalcfg, skipPreFlight, skipTokenPrint, dryRun) i, err := NewInit(cfgPath, internalcfg, skipPreFlight, skipTokenPrint, dryRun, criSocket)
kubeadmutil.CheckErr(err) kubeadmutil.CheckErr(err)
kubeadmutil.CheckErr(i.Validate(cmd)) kubeadmutil.CheckErr(i.Validate(cmd))
kubeadmutil.CheckErr(i.Run(out)) kubeadmutil.CheckErr(i.Run(out))
...@@ -132,7 +134,7 @@ func NewCmdInit(out io.Writer) *cobra.Command { ...@@ -132,7 +134,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
} }
AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString) AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
AddInitOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &skipTokenPrint, &dryRun) AddInitOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &skipTokenPrint, &dryRun, &criSocket)
return cmd return cmd
} }
...@@ -188,7 +190,7 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfigur ...@@ -188,7 +190,7 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfigur
} }
// AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset // AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset
func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, skipTokenPrint, dryRun *bool) { func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, skipTokenPrint, dryRun *bool, criSocket *string) {
flagSet.StringVar( flagSet.StringVar(
cfgPath, "config", *cfgPath, cfgPath, "config", *cfgPath,
"Path to kubeadm config file. WARNING: Usage of a configuration file is experimental.", "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental.",
...@@ -208,10 +210,14 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, sk ...@@ -208,10 +210,14 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, sk
dryRun, "dry-run", *dryRun, dryRun, "dry-run", *dryRun,
"Don't apply any changes; just output what would be done.", "Don't apply any changes; just output what would be done.",
) )
flagSet.StringVar(
criSocket, "cri-socket", "/var/run/dockershim.sock",
`Specify the CRI socket to connect to.`,
)
} }
// NewInit validates given arguments and instantiates Init struct with provided information. // NewInit validates given arguments and instantiates Init struct with provided information.
func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight, skipTokenPrint, dryRun bool) (*Init, error) { func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight, skipTokenPrint, dryRun bool, criSocket string) (*Init, error) {
fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.") fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.")
...@@ -247,7 +253,7 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight, ...@@ -247,7 +253,7 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight,
if !skipPreFlight { if !skipPreFlight {
fmt.Println("[preflight] Running pre-flight checks.") fmt.Println("[preflight] Running pre-flight checks.")
if err := preflight.RunInitMasterChecks(cfg); err != nil { if err := preflight.RunInitMasterChecks(utilsexec.New(), cfg, criSocket); err != nil {
return nil, err return nil, err
} }
......
...@@ -38,6 +38,7 @@ import ( ...@@ -38,6 +38,7 @@ import (
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
nodeutil "k8s.io/kubernetes/pkg/util/node" nodeutil "k8s.io/kubernetes/pkg/util/node"
utilsexec "k8s.io/utils/exec"
) )
var ( var (
...@@ -100,6 +101,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command { ...@@ -100,6 +101,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
var skipPreFlight bool var skipPreFlight bool
var cfgPath string var cfgPath string
var criSocket string
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "join [flags]", Use: "join [flags]",
...@@ -112,7 +114,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command { ...@@ -112,7 +114,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
internalcfg := &kubeadmapi.NodeConfiguration{} internalcfg := &kubeadmapi.NodeConfiguration{}
legacyscheme.Scheme.Convert(cfg, internalcfg, nil) legacyscheme.Scheme.Convert(cfg, internalcfg, nil)
j, err := NewJoin(cfgPath, args, internalcfg, skipPreFlight) j, err := NewJoin(cfgPath, args, internalcfg, skipPreFlight, criSocket)
kubeadmutil.CheckErr(err) kubeadmutil.CheckErr(err)
kubeadmutil.CheckErr(j.Validate(cmd)) kubeadmutil.CheckErr(j.Validate(cmd))
kubeadmutil.CheckErr(j.Run(out)) kubeadmutil.CheckErr(j.Run(out))
...@@ -120,7 +122,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command { ...@@ -120,7 +122,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
} }
AddJoinConfigFlags(cmd.PersistentFlags(), cfg) AddJoinConfigFlags(cmd.PersistentFlags(), cfg)
AddJoinOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight) AddJoinOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &criSocket)
return cmd return cmd
} }
...@@ -151,7 +153,7 @@ func AddJoinConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.NodeConfigurat ...@@ -151,7 +153,7 @@ func AddJoinConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.NodeConfigurat
} }
// AddJoinOtherFlags adds join flags that are not bound to a configuration file to the given flagset // AddJoinOtherFlags adds join flags that are not bound to a configuration file to the given flagset
func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bool) { func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bool, criSocket *string) {
flagSet.StringVar( flagSet.StringVar(
cfgPath, "config", *cfgPath, cfgPath, "config", *cfgPath,
"Path to kubeadm config file.") "Path to kubeadm config file.")
...@@ -160,6 +162,10 @@ func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bo ...@@ -160,6 +162,10 @@ func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bo
skipPreFlight, "skip-preflight-checks", false, skipPreFlight, "skip-preflight-checks", false,
"Skip preflight checks normally run before modifying the system.", "Skip preflight checks normally run before modifying the system.",
) )
flagSet.StringVar(
criSocket, "cri-socket", "/var/run/dockershim.sock",
`Specify the CRI socket to connect to.`,
)
} }
// Join defines struct used by kubeadm join command // Join defines struct used by kubeadm join command
...@@ -168,7 +174,7 @@ type Join struct { ...@@ -168,7 +174,7 @@ type Join struct {
} }
// NewJoin instantiates Join struct with given arguments // NewJoin instantiates Join struct with given arguments
func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, skipPreFlight bool) (*Join, error) { func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, skipPreFlight bool, criSocket string) (*Join, error) {
fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.") fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.")
if cfg.NodeName == "" { if cfg.NodeName == "" {
...@@ -189,7 +195,7 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s ...@@ -189,7 +195,7 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s
fmt.Println("[preflight] Running pre-flight checks.") fmt.Println("[preflight] Running pre-flight checks.")
// Then continue with the others... // Then continue with the others...
if err := preflight.RunJoinNodeChecks(cfg); err != nil { if err := preflight.RunJoinNodeChecks(utilsexec.New(), cfg, criSocket); err != nil {
return nil, err return nil, err
} }
......
...@@ -50,6 +50,7 @@ go_library( ...@@ -50,6 +50,7 @@ go_library(
"//pkg/util/version:go_default_library", "//pkg/util/version:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight" "k8s.io/kubernetes/cmd/kubeadm/app/preflight"
utilsexec "k8s.io/utils/exec"
) )
// NewCmdPreFlight calls cobra.Command for preflight checks // NewCmdPreFlight calls cobra.Command for preflight checks
...@@ -44,7 +45,8 @@ func NewCmdPreFlightMaster() *cobra.Command { ...@@ -44,7 +45,8 @@ func NewCmdPreFlightMaster() *cobra.Command {
Short: "Run master pre-flight checks", Short: "Run master pre-flight checks",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cfg := &kubeadmapi.MasterConfiguration{} cfg := &kubeadmapi.MasterConfiguration{}
return preflight.RunInitMasterChecks(cfg) criSocket := ""
return preflight.RunInitMasterChecks(utilsexec.New(), cfg, criSocket)
}, },
} }
...@@ -58,7 +60,8 @@ func NewCmdPreFlightNode() *cobra.Command { ...@@ -58,7 +60,8 @@ func NewCmdPreFlightNode() *cobra.Command {
Short: "Run node pre-flight checks", Short: "Run node pre-flight checks",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cfg := &kubeadmapi.NodeConfiguration{} cfg := &kubeadmapi.NodeConfiguration{}
return preflight.RunJoinNodeChecks(cfg) criSocket := ""
return preflight.RunJoinNodeChecks(utilsexec.New(), cfg, criSocket)
}, },
} }
......
...@@ -36,6 +36,7 @@ go_library( ...@@ -36,6 +36,7 @@ go_library(
"//vendor/github.com/blang/semver:go_default_library", "//vendor/github.com/blang/semver:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )
...@@ -50,6 +51,7 @@ go_test( ...@@ -50,6 +51,7 @@ go_test(
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//vendor/github.com/renstrom/dedent:go_default_library", "//vendor/github.com/renstrom/dedent:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )
......
...@@ -26,7 +26,6 @@ import ( ...@@ -26,7 +26,6 @@ import (
"net" "net"
"net/http" "net/http"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
...@@ -54,6 +53,7 @@ import ( ...@@ -54,6 +53,7 @@ import (
kubeadmversion "k8s.io/kubernetes/pkg/version" kubeadmversion "k8s.io/kubernetes/pkg/version"
schedulerapp "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app" schedulerapp "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app"
"k8s.io/kubernetes/test/e2e_node/system" "k8s.io/kubernetes/test/e2e_node/system"
utilsexec "k8s.io/utils/exec"
) )
const ( const (
...@@ -83,6 +83,21 @@ type Checker interface { ...@@ -83,6 +83,21 @@ type Checker interface {
Check() (warnings, errors []error) Check() (warnings, errors []error)
} }
// CRICheck verifies the container runtime through the CRI.
type CRICheck struct {
socket string
exec utilsexec.Interface
}
// Check validates the container runtime through the CRI.
func (criCheck CRICheck) Check() (warnings, errors []error) {
if err := criCheck.exec.Command("sh", "-c", fmt.Sprintf("crictl -r %s info", criCheck.socket)).Run(); err != nil {
errors = append(errors, fmt.Errorf("unable to check if the container runtime at %q is running: %s", criCheck.socket, err))
return warnings, errors
}
return warnings, errors
}
// ServiceCheck verifies that the given service is enabled and active. If we do not // ServiceCheck verifies that the given service is enabled and active. If we do not
// detect a supported init system however, all checks are skipped and a warning is // detect a supported init system however, all checks are skipped and a warning is
// returned. // returned.
...@@ -259,11 +274,12 @@ func (fcc FileContentCheck) Check() (warnings, errors []error) { ...@@ -259,11 +274,12 @@ func (fcc FileContentCheck) Check() (warnings, errors []error) {
type InPathCheck struct { type InPathCheck struct {
executable string executable string
mandatory bool mandatory bool
exec utilsexec.Interface
} }
// Check validates if the given executable is present in the path. // Check validates if the given executable is present in the path.
func (ipc InPathCheck) Check() (warnings, errors []error) { func (ipc InPathCheck) Check() (warnings, errors []error) {
_, err := exec.LookPath(ipc.executable) _, err := ipc.exec.LookPath(ipc.executable)
if err != nil { if err != nil {
if ipc.mandatory { if ipc.mandatory {
// Return as an error: // Return as an error:
...@@ -418,7 +434,9 @@ func (eac ExtraArgsCheck) Check() (warnings, errors []error) { ...@@ -418,7 +434,9 @@ func (eac ExtraArgsCheck) Check() (warnings, errors []error) {
} }
// SystemVerificationCheck defines struct used for for running the system verification node check in test/e2e_node/system // SystemVerificationCheck defines struct used for for running the system verification node check in test/e2e_node/system
type SystemVerificationCheck struct{} type SystemVerificationCheck struct {
CRISocket string
}
// Check runs all individual checks // Check runs all individual checks
func (sysver SystemVerificationCheck) Check() (warnings, errors []error) { func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
...@@ -431,8 +449,13 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) { ...@@ -431,8 +449,13 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
var warns []error var warns []error
// All the common validators we'd like to run: // All the common validators we'd like to run:
var validators = []system.Validator{ var validators = []system.Validator{
&system.KernelValidator{Reporter: reporter}, &system.KernelValidator{Reporter: reporter}}
&system.DockerValidator{Reporter: reporter}}
// run the docker validator only with dockershim
if sysver.CRISocket == "/var/run/dockershim.sock" {
// https://github.com/kubernetes/kubeadm/issues/533
validators = append(validators, &system.DockerValidator{Reporter: reporter})
}
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
//add linux validators //add linux validators
...@@ -677,20 +700,24 @@ func getEtcdVersionResponse(client *http.Client, url string, target interface{}) ...@@ -677,20 +700,24 @@ func getEtcdVersionResponse(client *http.Client, url string, target interface{})
} }
// RunInitMasterChecks executes all individual, applicable to Master node checks. // RunInitMasterChecks executes all individual, applicable to Master node checks.
func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.MasterConfiguration, criSocket string) error {
// First, check if we're root separately from the other preflight checks and fail fast // First, check if we're root separately from the other preflight checks and fail fast
if err := RunRootCheckOnly(); err != nil { if err := RunRootCheckOnly(); err != nil {
return err return err
} }
// check if we can use crictl to perform checks via the CRI
criCtlChecker := InPathCheck{executable: "crictl", mandatory: false, exec: execer}
warns, _ := criCtlChecker.Check()
useCRI := len(warns) == 0
checks := []Checker{ checks := []Checker{
KubernetesVersionCheck{KubernetesVersion: cfg.KubernetesVersion, KubeadmVersion: kubeadmversion.Get().GitVersion}, KubernetesVersionCheck{KubernetesVersion: cfg.KubernetesVersion, KubeadmVersion: kubeadmversion.Get().GitVersion},
SystemVerificationCheck{}, SystemVerificationCheck{CRISocket: criSocket},
IsPrivilegedUserCheck{}, IsPrivilegedUserCheck{},
HostnameCheck{nodeName: cfg.NodeName}, HostnameCheck{nodeName: cfg.NodeName},
KubeletVersionCheck{}, KubeletVersionCheck{},
ServiceCheck{Service: "kubelet", CheckIfActive: false}, ServiceCheck{Service: "kubelet", CheckIfActive: false},
ServiceCheck{Service: "docker", CheckIfActive: true},
FirewalldCheck{ports: []int{int(cfg.API.BindPort), 10250}}, FirewalldCheck{ports: []int{int(cfg.API.BindPort), 10250}},
PortOpenCheck{port: int(cfg.API.BindPort)}, PortOpenCheck{port: int(cfg.API.BindPort)},
PortOpenCheck{port: 10250}, PortOpenCheck{port: 10250},
...@@ -699,15 +726,16 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { ...@@ -699,15 +726,16 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)}, DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)},
FileContentCheck{Path: bridgenf, Content: []byte{'1'}}, FileContentCheck{Path: bridgenf, Content: []byte{'1'}},
SwapCheck{}, SwapCheck{},
InPathCheck{executable: "ip", mandatory: true}, InPathCheck{executable: "ip", mandatory: true, exec: execer},
InPathCheck{executable: "iptables", mandatory: true}, InPathCheck{executable: "iptables", mandatory: true, exec: execer},
InPathCheck{executable: "mount", mandatory: true}, InPathCheck{executable: "mount", mandatory: true, exec: execer},
InPathCheck{executable: "nsenter", mandatory: true}, InPathCheck{executable: "nsenter", mandatory: true, exec: execer},
InPathCheck{executable: "ebtables", mandatory: false}, InPathCheck{executable: "ebtables", mandatory: false, exec: execer},
InPathCheck{executable: "ethtool", mandatory: false}, InPathCheck{executable: "ethtool", mandatory: false, exec: execer},
InPathCheck{executable: "socat", mandatory: false}, InPathCheck{executable: "socat", mandatory: false, exec: execer},
InPathCheck{executable: "tc", mandatory: false}, InPathCheck{executable: "tc", mandatory: false, exec: execer},
InPathCheck{executable: "touch", mandatory: false}, InPathCheck{executable: "touch", mandatory: false, exec: execer},
criCtlChecker,
ExtraArgsCheck{ ExtraArgsCheck{
APIServerExtraArgs: cfg.APIServerExtraArgs, APIServerExtraArgs: cfg.APIServerExtraArgs,
ControllerManagerExtraArgs: cfg.ControllerManagerExtraArgs, ControllerManagerExtraArgs: cfg.ControllerManagerExtraArgs,
...@@ -718,6 +746,13 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { ...@@ -718,6 +746,13 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
HTTPProxyCIDRCheck{Proto: "https", CIDR: cfg.Networking.PodSubnet}, HTTPProxyCIDRCheck{Proto: "https", CIDR: cfg.Networking.PodSubnet},
} }
if useCRI {
checks = append(checks, CRICheck{socket: criSocket, exec: execer})
} else {
// assume docker
checks = append(checks, ServiceCheck{Service: "docker", CheckIfActive: true})
}
if len(cfg.Etcd.Endpoints) == 0 { if len(cfg.Etcd.Endpoints) == 0 {
// Only do etcd related checks when no external endpoints were specified // Only do etcd related checks when no external endpoints were specified
checks = append(checks, checks = append(checks,
...@@ -761,38 +796,49 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error { ...@@ -761,38 +796,49 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
} }
// RunJoinNodeChecks executes all individual, applicable to node checks. // RunJoinNodeChecks executes all individual, applicable to node checks.
func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error { func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.NodeConfiguration, criSocket string) error {
// First, check if we're root separately from the other preflight checks and fail fast // First, check if we're root separately from the other preflight checks and fail fast
if err := RunRootCheckOnly(); err != nil { if err := RunRootCheckOnly(); err != nil {
return err return err
} }
// check if we can use crictl to perform checks via the CRI
criCtlChecker := InPathCheck{executable: "crictl", mandatory: false, exec: execer}
warns, _ := criCtlChecker.Check()
useCRI := len(warns) == 0
checks := []Checker{ checks := []Checker{
SystemVerificationCheck{}, SystemVerificationCheck{CRISocket: criSocket},
IsPrivilegedUserCheck{}, IsPrivilegedUserCheck{},
HostnameCheck{cfg.NodeName}, HostnameCheck{cfg.NodeName},
KubeletVersionCheck{}, KubeletVersionCheck{},
ServiceCheck{Service: "kubelet", CheckIfActive: false}, ServiceCheck{Service: "kubelet", CheckIfActive: false},
ServiceCheck{Service: "docker", CheckIfActive: true},
PortOpenCheck{port: 10250}, PortOpenCheck{port: 10250},
DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)}, DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)},
FileAvailableCheck{Path: cfg.CACertPath}, FileAvailableCheck{Path: cfg.CACertPath},
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)}, FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)},
} }
if useCRI {
checks = append(checks, CRICheck{socket: criSocket, exec: execer})
} else {
// assume docker
checks = append(checks, ServiceCheck{Service: "docker", CheckIfActive: true})
}
//non-windows checks //non-windows checks
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
checks = append(checks, checks = append(checks,
FileContentCheck{Path: bridgenf, Content: []byte{'1'}}, FileContentCheck{Path: bridgenf, Content: []byte{'1'}},
SwapCheck{}, SwapCheck{},
InPathCheck{executable: "ip", mandatory: true}, InPathCheck{executable: "ip", mandatory: true, exec: execer},
InPathCheck{executable: "iptables", mandatory: true}, InPathCheck{executable: "iptables", mandatory: true, exec: execer},
InPathCheck{executable: "mount", mandatory: true}, InPathCheck{executable: "mount", mandatory: true, exec: execer},
InPathCheck{executable: "nsenter", mandatory: true}, InPathCheck{executable: "nsenter", mandatory: true, exec: execer},
InPathCheck{executable: "ebtables", mandatory: false}, InPathCheck{executable: "ebtables", mandatory: false, exec: execer},
InPathCheck{executable: "ethtool", mandatory: false}, InPathCheck{executable: "ethtool", mandatory: false, exec: execer},
InPathCheck{executable: "socat", mandatory: false}, InPathCheck{executable: "socat", mandatory: false, exec: execer},
InPathCheck{executable: "tc", mandatory: false}, InPathCheck{executable: "tc", mandatory: false, exec: execer},
InPathCheck{executable: "touch", mandatory: false}) InPathCheck{executable: "touch", mandatory: false, exec: execer},
criCtlChecker)
} }
if len(cfg.DiscoveryTokenAPIServers) > 0 { if len(cfg.DiscoveryTokenAPIServers) > 0 {
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"os" "os"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/utils/exec"
) )
var ( var (
...@@ -216,7 +217,7 @@ func TestRunInitMasterChecks(t *testing.T) { ...@@ -216,7 +217,7 @@ func TestRunInitMasterChecks(t *testing.T) {
} }
for _, rt := range tests { for _, rt := range tests {
actual := RunInitMasterChecks(rt.cfg) actual := RunInitMasterChecks(exec.New(), rt.cfg, "")
if (actual == nil) != rt.expected { if (actual == nil) != rt.expected {
t.Errorf( t.Errorf(
"failed RunInitMasterChecks:\n\texpected: %t\n\t actual: %t\n\t error: %v", "failed RunInitMasterChecks:\n\texpected: %t\n\t actual: %t\n\t error: %v",
...@@ -252,7 +253,7 @@ func TestRunJoinNodeChecks(t *testing.T) { ...@@ -252,7 +253,7 @@ func TestRunJoinNodeChecks(t *testing.T) {
} }
for _, rt := range tests { for _, rt := range tests {
actual := RunJoinNodeChecks(rt.cfg) actual := RunJoinNodeChecks(exec.New(), rt.cfg, "")
if (actual == nil) != rt.expected { if (actual == nil) != rt.expected {
t.Errorf( t.Errorf(
"failed RunJoinNodeChecks:\n\texpected: %t\n\t actual: %t", "failed RunJoinNodeChecks:\n\texpected: %t\n\t actual: %t",
...@@ -279,8 +280,8 @@ func TestRunChecks(t *testing.T) { ...@@ -279,8 +280,8 @@ func TestRunChecks(t *testing.T) {
{[]Checker{FileContentCheck{Path: "/does/not/exist"}}, false, ""}, {[]Checker{FileContentCheck{Path: "/does/not/exist"}}, false, ""},
{[]Checker{FileContentCheck{Path: "/"}}, true, ""}, {[]Checker{FileContentCheck{Path: "/"}}, true, ""},
{[]Checker{FileContentCheck{Path: "/", Content: []byte("does not exist")}}, false, ""}, {[]Checker{FileContentCheck{Path: "/", Content: []byte("does not exist")}}, false, ""},
{[]Checker{InPathCheck{executable: "foobarbaz"}}, true, "[preflight] WARNING: foobarbaz not found in system path\n"}, {[]Checker{InPathCheck{executable: "foobarbaz", exec: exec.New()}}, true, "[preflight] WARNING: foobarbaz not found in system path\n"},
{[]Checker{InPathCheck{executable: "foobarbaz", mandatory: true}}, false, ""}, {[]Checker{InPathCheck{executable: "foobarbaz", mandatory: true, exec: exec.New()}}, false, ""},
{[]Checker{ExtraArgsCheck{ {[]Checker{ExtraArgsCheck{
APIServerExtraArgs: map[string]string{"secure-port": "1234"}, APIServerExtraArgs: map[string]string{"secure-port": "1234"},
ControllerManagerExtraArgs: map[string]string{"use-service-account-credentials": "true"}, ControllerManagerExtraArgs: map[string]string{"use-service-account-credentials": "true"},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment