diff --git a/pkg/controllers/status/cluster_status_controller.go b/pkg/controllers/status/cluster_status_controller.go index 67673856d..77f539592 100644 --- a/pkg/controllers/status/cluster_status_controller.go +++ b/pkg/controllers/status/cluster_status_controller.go @@ -456,8 +456,7 @@ func getAllocatingResource(podList []*corev1.Pod) corev1.ResourceList { var requestCPU, requestMem int64 for _, pod := range podList { if len(pod.Spec.NodeName) == 0 { - // TODO(Garrybest): calculate the init container resource when pod is not scheduled - podRes := addPodRequestResource(pod) + podRes := util.CalculateRequestResource(pod) requestCPU += podRes.MilliCPU requestMem += podRes.Memory } @@ -476,8 +475,7 @@ func getAllocatedResource(podList []*corev1.Pod) corev1.ResourceList { for _, pod := range podList { // When the phase of a pod is Succeeded or Failed, kube-scheduler would not consider its resource occupation. if len(pod.Spec.NodeName) != 0 && pod.Status.Phase != corev1.PodSucceeded && pod.Status.Phase != corev1.PodFailed { - // TODO(Garrybest): calculate the init container resource when pod is not scheduled - podRes := addPodRequestResource(pod) + podRes := util.CalculateRequestResource(pod) requestCPU += podRes.MilliCPU requestMem += podRes.Memory } @@ -490,39 +488,3 @@ func getAllocatedResource(podList []*corev1.Pod) corev1.ResourceList { return allocated } - -func addPodRequestResource(pod *corev1.Pod) requestResource { - res := calculateResource(pod) - return res -} - -func calculateResource(pod *corev1.Pod) (res requestResource) { - resPtr := &res - for _, c := range pod.Spec.Containers { - resPtr.addResource(c.Resources.Requests) - } - return -} - -// requestResource is a collection of compute resource. -type requestResource struct { - MilliCPU int64 - Memory int64 -} - -func (r *requestResource) addResource(rl corev1.ResourceList) { - if r == nil { - return - } - - for rName, rQuant := range rl { - switch rName { - case corev1.ResourceCPU: - r.MilliCPU += rQuant.MilliValue() - case corev1.ResourceMemory: - r.Memory += rQuant.Value() - default: - continue - } - } -} diff --git a/pkg/util/resource.go b/pkg/util/resource.go new file mode 100644 index 000000000..6503e232f --- /dev/null +++ b/pkg/util/resource.go @@ -0,0 +1,79 @@ +package util + +import corev1 "k8s.io/api/core/v1" + +// Resource is a collection of compute resource. +type Resource struct { + MilliCPU int64 + Memory int64 +} + +// EmptyResource creates a empty resource object and returns. +func EmptyResource() *Resource { + return &Resource{} +} + +// Add is used to add two resources. +func (r *Resource) Add(rl corev1.ResourceList) { + if r == nil { + return + } + + for rName, rQuant := range rl { + switch rName { + case corev1.ResourceCPU: + r.MilliCPU += rQuant.MilliValue() + case corev1.ResourceMemory: + r.Memory += rQuant.Value() + default: + continue + } + } +} + +// SetMaxResource compares with ResourceList and takes max value for each Resource. +func (r *Resource) SetMaxResource(rl corev1.ResourceList) { + if r == nil { + return + } + + for rName, rQuant := range rl { + switch rName { + case corev1.ResourceCPU: + if cpu := rQuant.MilliValue(); cpu > r.MilliCPU { + r.MilliCPU = cpu + } + case corev1.ResourceMemory: + if mem := rQuant.Value(); mem > r.Memory { + r.Memory = mem + } + default: + continue + } + } +} + +// CalculateRequestResourceWithoutInitContainers returns Pod's resource request, it does not contain +// init containers' resource request. +func CalculateRequestResourceWithoutInitContainers(pod *corev1.Pod) *Resource { + result := EmptyResource() + for _, container := range pod.Spec.Containers { + result.Add(container.Resources.Requests) + } + + return result +} + +// CalculateRequestResource calculates the resource required for pod, that is the higher of: +// - the sum of all app containers(spec.Containers) request for a resource. +// - the effective init containers(spec.InitContainers) request for a resource. +// The effective init containers request is the highest request on all init containers. +func CalculateRequestResource(pod *corev1.Pod) *Resource { + result := CalculateRequestResourceWithoutInitContainers(pod) + + for _, container := range pod.Spec.InitContainers { + result.SetMaxResource(container.Resources.Requests) + } + + return result +}