Change:
What happened: A pod that has init container with request for cpu and memory, and containers that make no request for cpu or memory reports a BestEffort QoS class. This is incorrect. What you expected to happen: Containers that make requests independent of lifecycle phase should impact quality of service calculation. Found in 1.12, looks to still be present in 1.14 dev. /cc
/priority important-soon
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
/lifecycle frozen
I think this doesn't work very well with the current cpu manager logic. The problem is that a pod can't now have QoS class Guaranteed if it has init containers which don't have matching requests/limits. This means that normal containers in such a pod don't then get dedicated cpus even though the init containers are long gone when the app containers (with matching requests/limits) are finally started. This is quite non-intuitive. I would propose separating at least Guaranteed class calculation so that the init container resource requests wouldn't affect the calculation. What do you think?

Discussion:
limits := core.ResourceList{} zeroQuantity := resource.MustParse("0") isGuaranteed := true <del> for _, container := range pod.Spec.Containers { </del> <ins> allContainers := []core.Container{} allContainers = append(allContainers, pod.Spec.Containers...) allContainers = append(allContainers, pod.Spec.InitContainers...) for _, container := range allContainers { </ins> // process requests for name, quantity := range container.Resources.Requests { if !isSupportedQoSComputeResource(name) {

package qos import ( <del> "k8s.io/api/core/v1" </del> <ins> v1 "k8s.io/api/core/v1" </ins> "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/kubernetes/pkg/apis/core"

limits := v1.ResourceList{} zeroQuantity := resource.MustParse("0") isGuaranteed := true <del> for _, container := range pod.Spec.Containers { </del> <ins> allContainers := []v1.Container{} allContainers = append(allContainers, pod.Spec.Containers...) allContainers = append(allContainers, pod.Spec.InitContainers...) for _, container := range allContainers { </ins> // process requests for name, quantity := range container.Resources.Requests { if !isSupportedQoSComputeResource(name) {

import ( "testing" <del> "k8s.io/api/core/v1" </del> <ins> v1 "k8s.io/api/core/v1" </ins> "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/apis/core"

}), expected: v1.PodQOSBestEffort, }, <ins> { pod: newPodWithInitContainers("init-container", []v1.Container{ newContainer("best-effort", getResourceList("", ""), getResourceList("", "")), }, []v1.Container{ newContainer("burstable", getResourceList("10m", "100Mi"), getResourceList("100m", "200Mi")), }), expected: v1.PodQOSBurstable, }, </ins> } for id, testCase := range testCases { if actual := GetPodQOS(testCase.pod); testCase.expected != actual {

}, } } <ins> func newPodWithInitContainers(name string, containers []v1.Container, initContainers []v1.Container) *v1.Pod { return &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, Spec: v1.PodSpec{ Containers:     containers, InitContainers: initContainers, }, } } </ins>