Skip to content

Commit 4b7c2c9

Browse files
authored
Merge pull request #1771 from a7i/native-sidecar
fix: pod resource calculation to consider native sidecars
2 parents 582641c + 06cab8e commit 4b7c2c9

File tree

6 files changed

+535
-89
lines changed

6 files changed

+535
-89
lines changed

pkg/descheduler/node/node.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func fitsRequest(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, nod
241241
return false, fmt.Errorf("insufficient %v", resource)
242242
}
243243
}
244-
// check pod num, at least one pod number is avaibalbe
244+
// check pod num, at least one pod number is available
245245
if quantity, ok := availableResources[v1.ResourcePods]; ok && quantity.MilliValue() <= 0 {
246246
return false, fmt.Errorf("insufficient %v", v1.ResourcePods)
247247
}

pkg/descheduler/node/node_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"k8s.io/apimachinery/pkg/runtime"
2929
"k8s.io/client-go/informers"
3030
"k8s.io/client-go/kubernetes/fake"
31+
"k8s.io/utils/ptr"
3132
podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod"
3233
"sigs.k8s.io/descheduler/test"
3334
)
@@ -1020,6 +1021,64 @@ func TestNodeFit(t *testing.T) {
10201021
node: node,
10211022
podsOnNode: []*v1.Pod{},
10221023
},
1024+
{
1025+
description: "Pod with native sidecars with too much cpu does not fit on node",
1026+
pod: test.BuildTestPod("p1", 1, 100, "", func(pod *v1.Pod) {
1027+
pod.Spec.InitContainers = append(pod.Spec.InitContainers, v1.Container{
1028+
RestartPolicy: ptr.To(v1.ContainerRestartPolicyAlways), // native sidecar
1029+
Resources: v1.ResourceRequirements{
1030+
Requests: createResourceList(100000, 100*1000*1000, 0),
1031+
},
1032+
})
1033+
}),
1034+
node: node,
1035+
podsOnNode: []*v1.Pod{},
1036+
err: errors.New("insufficient cpu"),
1037+
},
1038+
{
1039+
description: "Pod with native sidecars with too much memory does not fit on node",
1040+
pod: test.BuildTestPod("p1", 1, 100, "", func(pod *v1.Pod) {
1041+
pod.Spec.InitContainers = append(pod.Spec.InitContainers, v1.Container{
1042+
RestartPolicy: ptr.To(v1.ContainerRestartPolicyAlways), // native sidecar
1043+
Resources: v1.ResourceRequirements{
1044+
Requests: createResourceList(100, 1000*1000*1000*1000, 0),
1045+
},
1046+
})
1047+
}),
1048+
node: node,
1049+
podsOnNode: []*v1.Pod{},
1050+
err: errors.New("insufficient memory"),
1051+
},
1052+
{
1053+
description: "Pod with small native sidecars fits on node",
1054+
pod: test.BuildTestPod("p1", 1, 100, "", func(pod *v1.Pod) {
1055+
pod.Spec.InitContainers = append(pod.Spec.InitContainers, v1.Container{
1056+
RestartPolicy: ptr.To(v1.ContainerRestartPolicyAlways), // native sidecar
1057+
Resources: v1.ResourceRequirements{
1058+
Requests: createResourceList(100, 100*1000*1000, 0),
1059+
},
1060+
})
1061+
}),
1062+
node: node,
1063+
podsOnNode: []*v1.Pod{},
1064+
},
1065+
{
1066+
description: "Pod with large overhead does not fit on node",
1067+
pod: test.BuildTestPod("p1", 1, 100, "", func(pod *v1.Pod) {
1068+
pod.Spec.Overhead = createResourceList(100000, 100*1000*1000, 0)
1069+
}),
1070+
node: node,
1071+
podsOnNode: []*v1.Pod{},
1072+
err: errors.New("insufficient cpu"),
1073+
},
1074+
{
1075+
description: "Pod with small overhead fits on node",
1076+
pod: test.BuildTestPod("p1", 1, 100, "", func(pod *v1.Pod) {
1077+
pod.Spec.Overhead = createResourceList(1, 1*1000*1000, 0)
1078+
}),
1079+
node: node,
1080+
podsOnNode: []*v1.Pod{},
1081+
},
10231082
}
10241083

10251084
for _, tc := range tests {

pkg/utils/pod.go

Lines changed: 6 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,10 @@ import (
1111
v1 "k8s.io/api/core/v1"
1212
"k8s.io/apimachinery/pkg/api/resource"
1313
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
resourcehelper "k8s.io/component-helpers/resource"
1415
"k8s.io/klog/v2"
1516
)
1617

17-
// GetResourceRequest finds and returns the request value for a specific resource.
18-
func GetResourceRequest(pod *v1.Pod, resource v1.ResourceName) int64 {
19-
if resource == v1.ResourcePods {
20-
return 1
21-
}
22-
23-
requestQuantity := GetResourceRequestQuantity(pod, resource)
24-
25-
if resource == v1.ResourceCPU {
26-
return requestQuantity.MilliValue()
27-
}
28-
29-
return requestQuantity.Value()
30-
}
31-
3218
// GetResourceRequestQuantity finds and returns the request quantity for a specific resource.
3319
func GetResourceRequestQuantity(pod *v1.Pod, resourceName v1.ResourceName) resource.Quantity {
3420
requestQuantity := resource.Quantity{}
@@ -42,26 +28,8 @@ func GetResourceRequestQuantity(pod *v1.Pod, resourceName v1.ResourceName) resou
4228
requestQuantity = resource.Quantity{Format: resource.DecimalSI}
4329
}
4430

45-
for _, container := range pod.Spec.Containers {
46-
if rQuantity, ok := container.Resources.Requests[resourceName]; ok {
47-
requestQuantity.Add(rQuantity)
48-
}
49-
}
50-
51-
for _, container := range pod.Spec.InitContainers {
52-
if rQuantity, ok := container.Resources.Requests[resourceName]; ok {
53-
if requestQuantity.Cmp(rQuantity) < 0 {
54-
requestQuantity = rQuantity.DeepCopy()
55-
}
56-
}
57-
}
58-
59-
// We assume pod overhead feature gate is enabled.
60-
// We can't import the scheduler settings so we will inherit the default.
61-
if pod.Spec.Overhead != nil {
62-
if podOverhead, ok := pod.Spec.Overhead[resourceName]; ok && !requestQuantity.IsZero() {
63-
requestQuantity.Add(podOverhead)
64-
}
31+
if rQuantity, ok := resourcehelper.PodRequests(pod, resourcehelper.PodResourcesOptions{})[resourceName]; ok {
32+
requestQuantity.Add(rQuantity)
6533
}
6634

6735
return requestQuantity
@@ -171,59 +139,9 @@ func GetPodSource(pod *v1.Pod) (string, error) {
171139
// containers of the pod. If PodOverhead feature is enabled, pod overhead is added to the
172140
// total container resource requests and to the total container limits which have a
173141
// non-zero quantity.
174-
func PodRequestsAndLimits(pod *v1.Pod) (reqs, limits v1.ResourceList) {
175-
reqs, limits = v1.ResourceList{}, v1.ResourceList{}
176-
for _, container := range pod.Spec.Containers {
177-
addResourceList(reqs, container.Resources.Requests)
178-
addResourceList(limits, container.Resources.Limits)
179-
}
180-
// init containers define the minimum of any resource
181-
for _, container := range pod.Spec.InitContainers {
182-
maxResourceList(reqs, container.Resources.Requests)
183-
maxResourceList(limits, container.Resources.Limits)
184-
}
185-
186-
// We assume pod overhead feature gate is enabled.
187-
// We can't import the scheduler settings so we will inherit the default.
188-
if pod.Spec.Overhead != nil {
189-
addResourceList(reqs, pod.Spec.Overhead)
190-
191-
for name, quantity := range pod.Spec.Overhead {
192-
if value, ok := limits[name]; ok && !value.IsZero() {
193-
value.Add(quantity)
194-
limits[name] = value
195-
}
196-
}
197-
}
198-
199-
return
200-
}
201-
202-
// addResourceList adds the resources in newList to list
203-
func addResourceList(list, newList v1.ResourceList) {
204-
for name, quantity := range newList {
205-
if value, ok := list[name]; !ok {
206-
list[name] = quantity.DeepCopy()
207-
} else {
208-
value.Add(quantity)
209-
list[name] = value
210-
}
211-
}
212-
}
213-
214-
// maxResourceList sets list to the greater of list/newList for every resource
215-
// either list
216-
func maxResourceList(list, new v1.ResourceList) {
217-
for name, quantity := range new {
218-
if value, ok := list[name]; !ok {
219-
list[name] = quantity.DeepCopy()
220-
continue
221-
} else {
222-
if quantity.Cmp(value) > 0 {
223-
list[name] = quantity.DeepCopy()
224-
}
225-
}
226-
}
142+
func PodRequestsAndLimits(pod *v1.Pod) (v1.ResourceList, v1.ResourceList) {
143+
opts := resourcehelper.PodResourcesOptions{}
144+
return resourcehelper.PodRequests(pod, opts), resourcehelper.PodLimits(pod, opts)
227145
}
228146

229147
// PodToleratesTaints returns true if a pod tolerates one node's taints

vendor/k8s.io/component-helpers/resource/OWNERS

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)