diff --git a/pkg/kubelet/kuberuntime/helpers_linux.go b/pkg/kubelet/kuberuntime/helpers_linux.go index ab3b3405625..4f56d62b82e 100644 --- a/pkg/kubelet/kuberuntime/helpers_linux.go +++ b/pkg/kubelet/kuberuntime/helpers_linux.go @@ -26,48 +26,13 @@ import ( "k8s.io/kubernetes/pkg/kubelet/cm" ) -const ( - milliCPUToCPU = 1000 - - // 100000 microseconds is equivalent to 100ms - quotaPeriod = 100000 - // 1000 microseconds is equivalent to 1ms - // defined here: - // https://github.com/torvalds/linux/blob/cac03ac368fabff0122853de2422d4e17a32de08/kernel/sched/core.c#L10546 - minQuotaPeriod = 1000 -) - -// milliCPUToQuota converts milliCPU to CFS quota and period values -// Input parameters and resulting value is number of microseconds. -func milliCPUToQuota(milliCPU int64, period int64) (quota int64) { - // CFS quota is measured in two values: - // - cfs_period_us=100ms (the amount of time to measure usage across) - // - cfs_quota=20ms (the amount of cpu time allowed to be used across a period) - // so in the above example, you are limited to 20% of a single CPU - // for multi-cpu environments, you just scale equivalent amounts - // see https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt for details - if milliCPU == 0 { - return - } - - // we then convert your milliCPU to a value normalized over a period - quota = (milliCPU * period) / milliCPUToCPU - - // quota needs to be a minimum of 1ms. - if quota < minQuotaPeriod { - quota = minQuotaPeriod - } - - return -} - // sharesToMilliCPU converts CpuShares (cpu.shares) to milli-CPU value // TODO(vinaykul,InPlacePodVerticalScaling): Address issue that sets min req/limit to 2m/10m before beta // See: https://github.com/kubernetes/kubernetes/pull/102884#discussion_r662552642 func sharesToMilliCPU(shares int64) int64 { milliCPU := int64(0) if shares >= int64(cm.MinShares) { - milliCPU = int64(math.Ceil(float64(shares*milliCPUToCPU) / float64(cm.SharesPerCPU))) + milliCPU = int64(math.Ceil(float64(shares*cm.MilliCPUToCPU) / float64(cm.SharesPerCPU))) } return milliCPU } @@ -77,7 +42,7 @@ func quotaToMilliCPU(quota int64, period int64) int64 { if quota == -1 { return int64(0) } - return (quota * milliCPUToCPU) / period + return (quota * cm.MilliCPUToCPU) / period } func subtractOverheadFromResourceConfig(resCfg *cm.ResourceConfig, pod *v1.Pod) *cm.ResourceConfig { diff --git a/pkg/kubelet/kuberuntime/helpers_linux_test.go b/pkg/kubelet/kuberuntime/helpers_linux_test.go index a5157244f2d..9d457321526 100644 --- a/pkg/kubelet/kuberuntime/helpers_linux_test.go +++ b/pkg/kubelet/kuberuntime/helpers_linux_test.go @@ -25,10 +25,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/cm" ) @@ -36,184 +33,6 @@ func seccompLocalhostRef(profileName string) string { return filepath.Join(fakeSeccompProfileRoot, profileName) } -func TestMilliCPUToQuota(t *testing.T) { - for _, testCase := range []struct { - msg string - input int64 - expected int64 - period uint64 - }{ - { - msg: "all-zero", - input: int64(0), - expected: int64(0), - period: uint64(0), - }, - { - msg: "5 input default quota and period", - input: int64(5), - expected: int64(1000), - period: uint64(100000), - }, - { - msg: "9 input default quota and period", - input: int64(9), - expected: int64(1000), - period: uint64(100000), - }, - { - msg: "10 input default quota and period", - input: int64(10), - expected: int64(1000), - period: uint64(100000), - }, - { - msg: "200 input 20k quota and default period", - input: int64(200), - expected: int64(20000), - period: uint64(100000), - }, - { - msg: "500 input 50k quota and default period", - input: int64(500), - expected: int64(50000), - period: uint64(100000), - }, - { - msg: "1k input 100k quota and default period", - input: int64(1000), - expected: int64(100000), - period: uint64(100000), - }, - { - msg: "1500 input 150k quota and default period", - input: int64(1500), - expected: int64(150000), - period: uint64(100000), - }} { - t.Run(testCase.msg, func(t *testing.T) { - quota := milliCPUToQuota(testCase.input, int64(testCase.period)) - if quota != testCase.expected { - t.Errorf("Input %v and %v, expected quota %v, but got quota %v", testCase.input, testCase.period, testCase.expected, quota) - } - }) - } -} - -func TestMilliCPUToQuotaWithCustomCPUCFSQuotaPeriod(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CPUCFSQuotaPeriod, true) - - for _, testCase := range []struct { - msg string - input int64 - expected int64 - period uint64 - }{ - { - msg: "all-zero", - input: int64(0), - expected: int64(0), - period: uint64(0), - }, - { - msg: "5 input default quota and period", - input: int64(5), - expected: minQuotaPeriod, - period: uint64(100000), - }, - { - msg: "9 input default quota and period", - input: int64(9), - expected: minQuotaPeriod, - period: uint64(100000), - }, - { - msg: "10 input default quota and period", - input: int64(10), - expected: minQuotaPeriod, - period: uint64(100000), - }, - { - msg: "200 input 20k quota and default period", - input: int64(200), - expected: int64(20000), - period: uint64(100000), - }, - { - msg: "500 input 50k quota and default period", - input: int64(500), - expected: int64(50000), - period: uint64(100000), - }, - { - msg: "1k input 100k quota and default period", - input: int64(1000), - expected: int64(100000), - period: uint64(100000), - }, - { - msg: "1500 input 150k quota and default period", - input: int64(1500), - expected: int64(150000), - period: uint64(100000), - }, - { - msg: "5 input 10k period and default quota expected", - input: int64(5), - period: uint64(10000), - expected: minQuotaPeriod, - }, - { - msg: "5 input 5k period and default quota expected", - input: int64(5), - period: uint64(5000), - expected: minQuotaPeriod, - }, - { - msg: "9 input 10k period and default quota expected", - input: int64(9), - period: uint64(10000), - expected: minQuotaPeriod, - }, - { - msg: "10 input 200k period and 2000 quota expected", - input: int64(10), - period: uint64(200000), - expected: int64(2000), - }, - { - msg: "200 input 200k period and 40k quota", - input: int64(200), - period: uint64(200000), - expected: int64(40000), - }, - { - msg: "500 input 20k period and 20k expected quota", - input: int64(500), - period: uint64(20000), - expected: int64(10000), - }, - { - msg: "1000 input 10k period and 10k expected quota", - input: int64(1000), - period: uint64(10000), - expected: int64(10000), - }, - { - msg: "1500 input 5000 period and 7500 expected quota", - input: int64(1500), - period: uint64(5000), - expected: int64(7500), - }} { - t.Run(testCase.msg, func(t *testing.T) { - quota := milliCPUToQuota(testCase.input, int64(testCase.period)) - if quota != testCase.expected { - t.Errorf("Input %v and %v, expected quota %v, but got quota %v", testCase.input, testCase.period, testCase.expected, quota) - } - }) - } -} - func TestGetSeccompProfile(t *testing.T) { _, _, m, err := createTestRuntimeManager() require.NoError(t, err) diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go index 92321bd9bd4..7129a98773f 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go @@ -294,13 +294,13 @@ func (m *kubeGenericRuntimeManager) calculateLinuxResources(cpuRequest, cpuLimit if m.cpuCFSQuota { // if cpuLimit.Amount is nil, then the appropriate default value is returned // to allow full usage of cpu resource. - cpuPeriod := int64(quotaPeriod) + cpuPeriod := int64(cm.QuotaPeriod) if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUCFSQuotaPeriod) { // kubeGenericRuntimeManager.cpuCFSQuotaPeriod is provided in time.Duration, // but we need to convert it to number of microseconds which is used by kernel. cpuPeriod = int64(m.cpuCFSQuotaPeriod.Duration / time.Microsecond) } - cpuQuota := milliCPUToQuota(cpuLimit.MilliValue(), cpuPeriod) + cpuQuota := cm.MilliCPUToQuota(cpuLimit.MilliValue(), cpuPeriod) resources.CpuQuota = cpuQuota if disableCPUQuota { resources.CpuQuota = int64(-1)