Skip to content

Commit 0926587

Browse files
authored
Merge pull request kubernetes#128771 from tallclair/min-quota
[FG:InPlacePodVerticalScaling] Equate CPU limits below the minimum effective limit (10m)
2 parents af7581e + 18600f4 commit 0926587

File tree

8 files changed

+236
-118
lines changed

8 files changed

+236
-118
lines changed

pkg/kubelet/cm/helpers_linux.go

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ const (
5050
// defined here:
5151
// https://github.com/torvalds/linux/blob/cac03ac368fabff0122853de2422d4e17a32de08/kernel/sched/core.c#L10546
5252
MinQuotaPeriod = 1000
53+
54+
// From the inverse of the conversion in MilliCPUToQuota:
55+
// MinQuotaPeriod * MilliCPUToCPU / QuotaPeriod
56+
MinMilliCPULimit = 10
5357
)
5458

5559
// MilliCPUToQuota converts milliCPU to CFS quota and period values.

pkg/kubelet/cm/helpers_unsupported.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ limitations under the License.
2020
package cm
2121

2222
import (
23-
"k8s.io/api/core/v1"
23+
v1 "k8s.io/api/core/v1"
2424
"k8s.io/apimachinery/pkg/types"
2525
)
2626

@@ -31,8 +31,9 @@ const (
3131
SharesPerCPU = 0
3232
MilliCPUToCPU = 0
3333

34-
QuotaPeriod = 0
35-
MinQuotaPeriod = 0
34+
QuotaPeriod = 0
35+
MinQuotaPeriod = 0
36+
MinMilliCPULimit = 0
3637
)
3738

3839
// MilliCPUToQuota converts milliCPU and period to CFS quota values.

pkg/kubelet/kubelet_pods.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -1806,7 +1806,9 @@ func allocatedResourcesMatchStatus(allocatedPod *v1.Pod, podStatus *kubecontaine
18061806
if !cpuLim.IsZero() {
18071807
return false
18081808
}
1809-
} else if !cpuLim.Equal(*cs.Resources.CPULimit) {
1809+
} else if !cpuLim.Equal(*cs.Resources.CPULimit) &&
1810+
(cpuLim.MilliValue() > cm.MinMilliCPULimit || cs.Resources.CPULimit.MilliValue() > cm.MinMilliCPULimit) {
1811+
// If both allocated & status CPU limits are at or below the minimum limit, then they are considered equal.
18101812
return false
18111813
}
18121814
}
@@ -2152,7 +2154,12 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *v1.Pod, podStatus *kubecon
21522154
resources := alloc
21532155
if resources.Limits != nil {
21542156
if cStatus.Resources != nil && cStatus.Resources.CPULimit != nil {
2155-
resources.Limits[v1.ResourceCPU] = cStatus.Resources.CPULimit.DeepCopy()
2157+
// If both the allocated & actual resources are at or below the minimum effective limit, preserve the
2158+
// allocated value in the API to avoid confusion and simplify comparisons.
2159+
if cStatus.Resources.CPULimit.MilliValue() > cm.MinMilliCPULimit ||
2160+
resources.Limits.Cpu().MilliValue() > cm.MinMilliCPULimit {
2161+
resources.Limits[v1.ResourceCPU] = cStatus.Resources.CPULimit.DeepCopy()
2162+
}
21562163
} else {
21572164
preserveOldResourcesValue(v1.ResourceCPU, oldStatus.Resources.Limits, resources.Limits)
21582165
}

pkg/kubelet/kubelet_pods_test.go

+58-12
Original file line numberDiff line numberDiff line change
@@ -4797,22 +4797,33 @@ func TestConvertToAPIContainerStatusesForResources(t *testing.T) {
47974797
},
47984798
},
47994799
"BurstableQoSPod with below min CPU": {
4800-
Resources: v1.ResourceRequirements{Requests: v1.ResourceList{
4801-
v1.ResourceMemory: resource.MustParse("100M"),
4802-
v1.ResourceCPU: resource.MustParse("1m"),
4803-
}},
4800+
Resources: v1.ResourceRequirements{
4801+
Requests: v1.ResourceList{
4802+
v1.ResourceMemory: resource.MustParse("100M"),
4803+
v1.ResourceCPU: resource.MustParse("1m"),
4804+
},
4805+
Limits: v1.ResourceList{
4806+
v1.ResourceCPU: resource.MustParse("5m"),
4807+
},
4808+
},
48044809
ActualResources: &kubecontainer.ContainerResources{
48054810
CPURequest: resource.NewMilliQuantity(2, resource.DecimalSI),
4811+
CPULimit: resource.NewMilliQuantity(10, resource.DecimalSI),
48064812
},
48074813
OldStatus: v1.ContainerStatus{
48084814
Name: testContainerName,
48094815
Image: "img",
48104816
ImageID: "img1234",
48114817
State: v1.ContainerState{Running: &v1.ContainerStateRunning{}},
4812-
Resources: &v1.ResourceRequirements{Requests: v1.ResourceList{
4813-
v1.ResourceMemory: resource.MustParse("100M"),
4814-
v1.ResourceCPU: resource.MustParse("1m"),
4815-
}},
4818+
Resources: &v1.ResourceRequirements{
4819+
Requests: v1.ResourceList{
4820+
v1.ResourceMemory: resource.MustParse("100M"),
4821+
v1.ResourceCPU: resource.MustParse("1m"),
4822+
},
4823+
Limits: v1.ResourceList{
4824+
v1.ResourceCPU: resource.MustParse("5m"),
4825+
},
4826+
},
48164827
},
48174828
Expected: v1.ContainerStatus{
48184829
Name: testContainerName,
@@ -4824,10 +4835,15 @@ func TestConvertToAPIContainerStatusesForResources(t *testing.T) {
48244835
v1.ResourceMemory: resource.MustParse("100M"),
48254836
v1.ResourceCPU: resource.MustParse("1m"),
48264837
},
4827-
Resources: &v1.ResourceRequirements{Requests: v1.ResourceList{
4828-
v1.ResourceMemory: resource.MustParse("100M"),
4829-
v1.ResourceCPU: resource.MustParse("1m"),
4830-
}},
4838+
Resources: &v1.ResourceRequirements{
4839+
Requests: v1.ResourceList{
4840+
v1.ResourceMemory: resource.MustParse("100M"),
4841+
v1.ResourceCPU: resource.MustParse("1m"),
4842+
},
4843+
Limits: v1.ResourceList{
4844+
v1.ResourceCPU: resource.MustParse("5m"),
4845+
},
4846+
},
48314847
},
48324848
},
48334849
"GuaranteedQoSPod with CPU and memory CRI status, with ephemeral storage": {
@@ -6790,6 +6806,36 @@ func TestAllocatedResourcesMatchStatus(t *testing.T) {
67906806
CPURequest: resource.NewMilliQuantity(2, resource.DecimalSI),
67916807
},
67926808
expectMatch: true,
6809+
}, {
6810+
name: "burstable: min cpu limit",
6811+
allocatedResources: v1.ResourceRequirements{
6812+
Requests: v1.ResourceList{
6813+
v1.ResourceCPU: resource.MustParse("10m"),
6814+
},
6815+
Limits: v1.ResourceList{
6816+
v1.ResourceCPU: resource.MustParse("10m"),
6817+
},
6818+
},
6819+
statusResources: &kubecontainer.ContainerResources{
6820+
CPURequest: resource.NewMilliQuantity(10, resource.DecimalSI),
6821+
CPULimit: resource.NewMilliQuantity(10, resource.DecimalSI),
6822+
},
6823+
expectMatch: true,
6824+
}, {
6825+
name: "burstable: below min cpu limit",
6826+
allocatedResources: v1.ResourceRequirements{
6827+
Requests: v1.ResourceList{
6828+
v1.ResourceCPU: resource.MustParse("5m"),
6829+
},
6830+
Limits: v1.ResourceList{
6831+
v1.ResourceCPU: resource.MustParse("5m"),
6832+
},
6833+
},
6834+
statusResources: &kubecontainer.ContainerResources{
6835+
CPURequest: resource.NewMilliQuantity(5, resource.DecimalSI),
6836+
CPULimit: resource.NewMilliQuantity(10, resource.DecimalSI),
6837+
},
6838+
expectMatch: true,
67936839
}, {
67946840
name: "best effort",
67956841
allocatedResources: v1.ResourceRequirements{},

0 commit comments

Comments
 (0)