diff --git a/pkg/kubelet/cm/BUILD b/pkg/kubelet/cm/BUILD index 000741247cb..1ad243e0b3a 100644 --- a/pkg/kubelet/cm/BUILD +++ b/pkg/kubelet/cm/BUILD @@ -181,6 +181,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/component-base/featuregate/testing:go_default_library", + "//vendor/github.com/opencontainers/runc/libcontainer/cgroups:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/k8s.io/utils/mount:go_default_library", @@ -193,6 +194,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/component-base/featuregate/testing:go_default_library", + "//vendor/github.com/opencontainers/runc/libcontainer/cgroups:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/k8s.io/utils/mount:go_default_library", diff --git a/pkg/kubelet/cm/cgroup_manager_linux.go b/pkg/kubelet/cm/cgroup_manager_linux.go index b13006e1539..4d8b26e5eb0 100644 --- a/pkg/kubelet/cm/cgroup_manager_linux.go +++ b/pkg/kubelet/cm/cgroup_manager_linux.go @@ -364,6 +364,30 @@ func setSupportedSubsystems(cgroupConfig *libcontainerconfigs.Cgroup) error { return nil } +// getCpuWeight converts from the range [2, 262144] to [1, 10000] +func getCpuWeight(cpuShares *uint64) uint64 { + if cpuShares == nil { + return 0 + } + if *cpuShares >= 262144 { + return 10000 + } + return 1 + ((*cpuShares-2)*9999)/262142 +} + +// getCpuMax returns the cgroup v2 cpu.max setting given the cpu quota and the cpu period +func getCpuMax(cpuQuota *int64, cpuPeriod *uint64) string { + quotaStr := "max" + periodStr := "100000" + if cpuQuota != nil { + quotaStr = strconv.FormatInt(*cpuQuota, 10) + } + if cpuPeriod != nil { + periodStr = strconv.FormatUint(*cpuPeriod, 10) + } + return fmt.Sprintf("%s %s", quotaStr, periodStr) +} + func (m *cgroupManagerImpl) toResources(resourceConfig *ResourceConfig) *libcontainerconfigs.Resources { resources := &libcontainerconfigs.Resources{} if resourceConfig == nil { @@ -373,20 +397,8 @@ func (m *cgroupManagerImpl) toResources(resourceConfig *ResourceConfig) *libcont resources.Memory = *resourceConfig.Memory } if libcontainercgroups.IsCgroup2UnifiedMode() { - if resourceConfig.CpuShares != nil { - // Convert from the range [2-262144] to [1-10000] - resources.CpuWeight = (1 + ((*resourceConfig.CpuShares-2)*9999)/262142) - } - - quota := "max" - period := "100000" - if resourceConfig.CpuQuota != nil { - quota = strconv.FormatInt(*resourceConfig.CpuQuota, 10) - } - if resourceConfig.CpuPeriod != nil { - period = strconv.FormatUint(*resourceConfig.CpuPeriod, 10) - } - resources.CpuMax = fmt.Sprintf("%s %s", quota, period) + resources.CpuWeight = getCpuWeight(resourceConfig.CpuShares) + resources.CpuMax = getCpuMax(resourceConfig.CpuQuota, resourceConfig.CpuPeriod) } else { if resourceConfig.CpuShares != nil { resources.CpuShares = *resourceConfig.CpuShares diff --git a/pkg/kubelet/cm/container_manager_linux_test.go b/pkg/kubelet/cm/container_manager_linux_test.go index ce885868a33..a8a40a52f6a 100644 --- a/pkg/kubelet/cm/container_manager_linux_test.go +++ b/pkg/kubelet/cm/container_manager_linux_test.go @@ -24,6 +24,7 @@ import ( "path" "testing" + "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -63,6 +64,9 @@ func TestCgroupMountValidationSuccess(t *testing.T) { } func TestCgroupMountValidationMemoryMissing(t *testing.T) { + if cgroups.IsCgroup2UnifiedMode() { + t.Skip("skipping cgroup v1 test on a cgroup v2 system") + } mountInt := mount.NewFakeMounter( []mount.MountPoint{ { @@ -86,6 +90,9 @@ func TestCgroupMountValidationMemoryMissing(t *testing.T) { } func TestCgroupMountValidationMultipleSubsystem(t *testing.T) { + if cgroups.IsCgroup2UnifiedMode() { + t.Skip("skipping cgroup v1 test on a cgroup v2 system") + } mountInt := mount.NewFakeMounter( []mount.MountPoint{ { @@ -109,6 +116,9 @@ func TestCgroupMountValidationMultipleSubsystem(t *testing.T) { } func TestSoftRequirementsValidationSuccess(t *testing.T) { + if cgroups.IsCgroup2UnifiedMode() { + t.Skip("skipping cgroup v1 test on a cgroup v2 system") + } req := require.New(t) tempDir, err := ioutil.TempDir("", "") req.NoError(err) @@ -138,3 +148,28 @@ func TestSoftRequirementsValidationSuccess(t *testing.T) { assert.NoError(t, err) assert.True(t, f.cpuHardcapping, "cpu hardcapping is expected to be enabled") } + +func TestGetCpuWeight(t *testing.T) { + assert.Equal(t, uint64(0), getCpuWeight(nil)) + + v := uint64(2) + assert.Equal(t, uint64(1), getCpuWeight(&v)) + + v = uint64(262144) + assert.Equal(t, uint64(10000), getCpuWeight(&v)) + + v = uint64(1000000000) + assert.Equal(t, uint64(10000), getCpuWeight(&v)) +} + +func TestGetCpuMax(t *testing.T) { + assert.Equal(t, getCpuMax(nil, nil), "max 100000") + + quota := int64(50000) + period := uint64(200000) + assert.Equal(t, "50000 200000", getCpuMax("a, &period)) + + assert.Equal(t, "max 200000", getCpuMax(nil, &period)) + + assert.Equal(t, "50000 100000", getCpuMax("a, nil)) +}