Skip to content

Commit 92ba3eb

Browse files
authored
Merge pull request kubernetes#93275 from xlgao-zju/check-mem
kubeadm: Add a preflight check that the control-plane node has at least 1700MB of RAM
2 parents 8da7c92 + c6975a7 commit 92ba3eb

File tree

6 files changed

+74
-0
lines changed

6 files changed

+74
-0
lines changed

cmd/kubeadm/app/constants/constants.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ const (
350350
// ControlPlaneNumCPU is the number of CPUs required on control-plane
351351
ControlPlaneNumCPU = 2
352352

353+
// ControlPlaneMem is the number of megabytes of memory required on the control-plane
354+
// Below that amount of RAM running a stable control plane would be difficult.
355+
ControlPlaneMem = 1700
356+
353357
// KubeadmCertsSecret specifies in what Secret in the kube-system namespace the certificates should be stored
354358
KubeadmCertsSecret = "kubeadm-certs"
355359

cmd/kubeadm/app/preflight/checks.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,16 @@ func (ncc NumCPUCheck) Check() (warnings, errorList []error) {
869869
return warnings, errorList
870870
}
871871

872+
// MemCheck checks if the number of megabytes of memory is not less than required
873+
type MemCheck struct {
874+
Mem uint64
875+
}
876+
877+
// Name returns the label for memory
878+
func (MemCheck) Name() string {
879+
return "Mem"
880+
}
881+
872882
// RunInitNodeChecks executes all individual, applicable to control-plane node checks.
873883
// The boolean flag 'isSecondaryControlPlane' controls whether we are running checks in a --join-control-plane scenario.
874884
// The boolean flag 'downloadCerts' controls whether we should skip checks on certificates because we are downloading them.
@@ -884,6 +894,9 @@ func RunInitNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigura
884894
manifestsDir := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)
885895
checks := []Checker{
886896
NumCPUCheck{NumCPU: kubeadmconstants.ControlPlaneNumCPU},
897+
// Linux only
898+
// TODO: support other OS, if control-plane is supported on it.
899+
MemCheck{Mem: kubeadmconstants.ControlPlaneMem},
887900
KubernetesVersionCheck{KubernetesVersion: cfg.KubernetesVersion, KubeadmVersion: kubeadmversion.Get().GitVersion},
888901
FirewalldCheck{ports: []int{int(cfg.LocalAPIEndpoint.BindPort), kubeadmconstants.KubeletPort}},
889902
PortOpenCheck{port: int(cfg.LocalAPIEndpoint.BindPort)},

cmd/kubeadm/app/preflight/checks_darwin.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ package preflight
2525
func (idsc IsDockerSystemdCheck) Check() (warnings, errorList []error) {
2626
return nil, nil
2727
}
28+
29+
// Check number of memory required by kubeadm
30+
// No-op for Darwin (MacOS).
31+
func (mc MemCheck) Check() (warnings, errorList []error) {
32+
return nil, nil
33+
}

cmd/kubeadm/app/preflight/checks_linux.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ limitations under the License.
1919
package preflight
2020

2121
import (
22+
"syscall"
23+
2224
"github.com/pkg/errors"
2325
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
2426
"k8s.io/utils/exec"
@@ -40,3 +42,19 @@ func (idsc IsDockerSystemdCheck) Check() (warnings, errorList []error) {
4042
}
4143
return nil, nil
4244
}
45+
46+
// Check number of memory required by kubeadm
47+
func (mc MemCheck) Check() (warnings, errorList []error) {
48+
info := syscall.Sysinfo_t{}
49+
err := syscall.Sysinfo(&info)
50+
if err != nil {
51+
errorList = append(errorList, errors.Wrapf(err, "failed to get system info"))
52+
}
53+
54+
// Totalram returns bytes; convert to MB
55+
actual := uint64(info.Totalram) / 1024 / 1024
56+
if actual < mc.Mem {
57+
errorList = append(errorList, errors.Errorf("the system RAM (%d MB) is less than the minimum %d MB", actual, mc.Mem))
58+
}
59+
return warnings, errorList
60+
}

cmd/kubeadm/app/preflight/checks_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"bytes"
2121
"fmt"
2222
"io/ioutil"
23+
"runtime"
2324
"strings"
2425
"testing"
2526

@@ -856,3 +857,29 @@ func TestNumCPUCheck(t *testing.T) {
856857
})
857858
}
858859
}
860+
861+
func TestMemCheck(t *testing.T) {
862+
// skip this test, if OS in not Linux, since it will ONLY pass on Linux.
863+
if runtime.GOOS != "linux" {
864+
t.Skip("unsupported OS for memory check test ")
865+
}
866+
867+
var tests = []struct {
868+
minimum uint64
869+
expectedErrors int
870+
}{
871+
{0, 0},
872+
{9999999999999999, 1},
873+
}
874+
875+
for _, rt := range tests {
876+
t.Run(fmt.Sprintf("MemoryCheck{%d}", rt.minimum), func(t *testing.T) {
877+
warnings, errors := MemCheck{Mem: rt.minimum}.Check()
878+
if len(warnings) > 0 {
879+
t.Errorf("expected 0 warnings but got %d: %q", len(warnings), warnings)
880+
} else if len(errors) != rt.expectedErrors {
881+
t.Errorf("expected %d error(s) but got %d: %q", rt.expectedErrors, len(errors), errors)
882+
}
883+
})
884+
}
885+
}

cmd/kubeadm/app/preflight/checks_windows.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,9 @@ func (ipuc IsPrivilegedUserCheck) Check() (warnings, errorList []error) {
5454
func (idsc IsDockerSystemdCheck) Check() (warnings, errorList []error) {
5555
return nil, nil
5656
}
57+
58+
// Check number of memory required by kubeadm
59+
// No-op for Windows.
60+
func (mc MemCheck) Check() (warnings, errorList []error) {
61+
return nil, nil
62+
}

0 commit comments

Comments
 (0)