Skip to content
This repository was archived by the owner on May 25, 2023. It is now read-only.

Commit 71cdd7b

Browse files
committed
Take init containers into account when getting pod resource request
1 parent fb8ae80 commit 71cdd7b

File tree

3 files changed

+126
-6
lines changed

3 files changed

+126
-6
lines changed

pkg/scheduler/api/job_info.go

+40-6
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,7 @@ func getJobID(pod *v1.Pod) JobID {
6161
}
6262

6363
func NewTaskInfo(pod *v1.Pod) *TaskInfo {
64-
req := EmptyResource()
65-
66-
// TODO(k82cn): also includes initContainers' resource.
67-
for _, c := range pod.Spec.Containers {
68-
req.Add(NewResource(c.Resources.Requests))
69-
}
64+
req := getResourceRequest(pod)
7065

7166
jobID := getJobID(pod)
7267

@@ -89,6 +84,45 @@ func NewTaskInfo(pod *v1.Pod) *TaskInfo {
8984
return ti
9085
}
9186

87+
// Refer k8s.io/kubernetes/pkg/scheduler/algorithm/predicates/predicates.go#GetResourceRequest.
88+
//
89+
// GetResourceRequest returns a *Resource that covers the largest width in each resource dimension.
90+
// Because init-containers run sequentially, we collect the max in each dimension iteratively.
91+
// In contrast, we sum the resource vectors for regular containers since they run simultaneously.
92+
//
93+
// Example:
94+
//
95+
// Pod:
96+
// InitContainers
97+
// IC1:
98+
// CPU: 2
99+
// Memory: 1G
100+
// IC2:
101+
// CPU: 2
102+
// Memory: 3G
103+
// Containers
104+
// C1:
105+
// CPU: 2
106+
// Memory: 1G
107+
// C2:
108+
// CPU: 1
109+
// Memory: 1G
110+
//
111+
// Result: CPU: 3, Memory: 3G
112+
func getResourceRequest(pod *v1.Pod) *Resource {
113+
result := EmptyResource()
114+
for _, container := range pod.Spec.Containers {
115+
result.Add(NewResource(container.Resources.Requests))
116+
}
117+
118+
// take max_resource(sum_pod, any_init_container)
119+
for _, container := range pod.Spec.InitContainers {
120+
result.SetMaxResource(NewResource(container.Resources.Requests))
121+
}
122+
123+
return result
124+
}
125+
92126
func (ti *TaskInfo) Clone() *TaskInfo {
93127
return &TaskInfo{
94128
UID: ti.UID,

pkg/scheduler/api/job_info_test.go

+69
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,72 @@ func TestDeleteTaskInfo(t *testing.T) {
195195
}
196196
}
197197
}
198+
199+
func TestGetResourceRequest(t *testing.T) {
200+
tests := []struct {
201+
name string
202+
pod *v1.Pod
203+
expectedResource *Resource
204+
}{
205+
{
206+
name: "get resource for pod without init containers",
207+
pod: &v1.Pod{
208+
Spec: v1.PodSpec{
209+
Containers: []v1.Container{
210+
{
211+
Resources: v1.ResourceRequirements{
212+
Requests: buildResourceList("1000m", "1G"),
213+
},
214+
},
215+
{
216+
Resources: v1.ResourceRequirements{
217+
Requests: buildResourceList("2000m", "1G"),
218+
},
219+
},
220+
},
221+
},
222+
},
223+
expectedResource: NewResource(buildResourceList("3000m", "2G")),
224+
},
225+
{
226+
name: "get resource for pod with init containers",
227+
pod: &v1.Pod{
228+
Spec: v1.PodSpec{
229+
InitContainers: []v1.Container{
230+
{
231+
Resources: v1.ResourceRequirements{
232+
Requests: buildResourceList("2000m", "5G"),
233+
},
234+
},
235+
{
236+
Resources: v1.ResourceRequirements{
237+
Requests: buildResourceList("2000m", "1G"),
238+
},
239+
},
240+
},
241+
Containers: []v1.Container{
242+
{
243+
Resources: v1.ResourceRequirements{
244+
Requests: buildResourceList("1000m", "1G"),
245+
},
246+
},
247+
{
248+
Resources: v1.ResourceRequirements{
249+
Requests: buildResourceList("2000m", "1G"),
250+
},
251+
},
252+
},
253+
},
254+
},
255+
expectedResource: NewResource(buildResourceList("3000m", "5G")),
256+
},
257+
}
258+
259+
for i, test := range tests {
260+
req := getResourceRequest(test.pod)
261+
if !reflect.DeepEqual(req, test.expectedResource) {
262+
t.Errorf("case %d(%s) failed: \n expected %v, \n got: %v \n",
263+
i, test.name, test.expectedResource, req)
264+
}
265+
}
266+
}

pkg/scheduler/api/resource_info.go

+17
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,23 @@ func (r *Resource) Sub(rr *Resource) *Resource {
109109
r, rr))
110110
}
111111

112+
// SetMaxResource compares with ResourceList and takes max value for each Resource.
113+
func (r *Resource) SetMaxResource(rr *Resource) {
114+
if r == nil || rr == nil {
115+
return
116+
}
117+
118+
if rr.MilliCPU > r.MilliCPU {
119+
r.MilliCPU = rr.MilliCPU
120+
}
121+
if rr.Memory > r.Memory {
122+
r.Memory = rr.Memory
123+
}
124+
if rr.MilliGPU > r.MilliGPU {
125+
r.MilliGPU = rr.MilliGPU
126+
}
127+
}
128+
112129
//Computes the delta between a resource oject representing available
113130
//resources an operand representing resources being requested. Any
114131
//field that is less than 0 after the operation represents an

0 commit comments

Comments
 (0)