diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go index e707564ef52d..04e7595f48c4 100644 --- a/cmd/kubeadm/app/constants/constants.go +++ b/cmd/kubeadm/app/constants/constants.go @@ -323,6 +323,9 @@ const ( // DefaultAPIServerBindAddress is the default bind address for the API Server DefaultAPIServerBindAddress = "0.0.0.0" + + // MasterNumCPU is the number of CPUs required on master + MasterNumCPU = 2 ) var ( diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go index 30edb559e42c..74162872af01 100644 --- a/cmd/kubeadm/app/preflight/checks.go +++ b/cmd/kubeadm/app/preflight/checks.go @@ -845,6 +845,25 @@ func (ipc ImagePullCheck) Check() (warnings, errors []error) { return warnings, errors } +// NumCPUCheck checks if current number of CPUs is not less than required +type NumCPUCheck struct { + NumCPU int +} + +// Name returns the label for NumCPUCheck +func (NumCPUCheck) Name() string { + return "NumCPU" +} + +// Check number of CPUs required by kubeadm +func (ncc NumCPUCheck) Check() (warnings, errors []error) { + numCPU := runtime.NumCPU() + if numCPU < ncc.NumCPU { + errors = append(errors, fmt.Errorf("the number of available CPUs %d is less than the required %d", numCPU, ncc.NumCPU)) + } + return warnings, errors +} + // RunInitMasterChecks executes all individual, applicable to Master node checks. func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.InitConfiguration, ignorePreflightErrors sets.String) error { // First, check if we're root separately from the other preflight checks and fail fast @@ -854,6 +873,7 @@ func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigu manifestsDir := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName) checks := []Checker{ + NumCPUCheck{NumCPU: kubeadmconstants.MasterNumCPU}, KubernetesVersionCheck{KubernetesVersion: cfg.KubernetesVersion, KubeadmVersion: kubeadmversion.Get().GitVersion}, FirewalldCheck{ports: []int{int(cfg.APIEndpoint.BindPort), 10250}}, PortOpenCheck{port: int(cfg.APIEndpoint.BindPort)}, diff --git a/cmd/kubeadm/app/preflight/checks_test.go b/cmd/kubeadm/app/preflight/checks_test.go index efdf901a14c0..52abc2e56bbe 100644 --- a/cmd/kubeadm/app/preflight/checks_test.go +++ b/cmd/kubeadm/app/preflight/checks_test.go @@ -777,3 +777,24 @@ func TestImagePullCheck(t *testing.T) { t.Fatalf("expected 2 errors but got %d: %q", len(errors), errors) } } + +func TestNumCPUCheck(t *testing.T) { + var tests = []struct { + numCPU int + numErrors int + numWarnings int + }{ + {0, 0, 0}, + {999999999, 1, 0}, + } + + for _, rt := range tests { + warnings, errors := NumCPUCheck{NumCPU: rt.numCPU}.Check() + if len(warnings) != rt.numWarnings { + t.Errorf("expected %d warning(s) but got %d: %q", rt.numWarnings, len(warnings), warnings) + } + if len(errors) != rt.numErrors { + t.Errorf("expected %d warning(s) but got %d: %q", rt.numErrors, len(errors), errors) + } + } +}