diff --git a/pkg/kubelet/qos/qos.go b/pkg/kubelet/qos/qos.go index 2c0d19d044b..df9b1b36402 100644 --- a/pkg/kubelet/qos/qos.go +++ b/pkg/kubelet/qos/qos.go @@ -19,6 +19,7 @@ package qos import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/util/sets" ) // isResourceGuaranteed returns true if the container's resource requirements are Guaranteed. @@ -53,6 +54,9 @@ func GetPodQOS(pod *api.Pod) QOSClass { for _, container := range pod.Spec.Containers { // process requests for name, quantity := range container.Resources.Requests { + if !supportedQoSComputeResources.Has(string(name)) { + continue + } if quantity.Cmp(zeroQuantity) == 1 { delta := quantity.Copy() if _, exists := requests[name]; !exists { @@ -65,6 +69,9 @@ func GetPodQOS(pod *api.Pod) QOSClass { } // process limits for name, quantity := range container.Resources.Limits { + if !supportedQoSComputeResources.Has(string(name)) { + continue + } if quantity.Cmp(zeroQuantity) == 1 { delta := quantity.Copy() if _, exists := limits[name]; !exists { @@ -75,7 +82,7 @@ func GetPodQOS(pod *api.Pod) QOSClass { } } } - if len(container.Resources.Limits) != len(supportedComputeResources) { + if len(limits) != len(supportedQoSComputeResources) { isGuaranteed = false } } @@ -92,8 +99,7 @@ func GetPodQOS(pod *api.Pod) QOSClass { } } if isGuaranteed && - len(requests) == len(limits) && - len(limits) == len(supportedComputeResources) { + len(requests) == len(limits) { return Guaranteed } return Burstable @@ -118,17 +124,14 @@ func GetQOS(container *api.Container) QOSList { return resourceToQOS } -// supportedComputeResources is the list of supported compute resources -var supportedComputeResources = []api.ResourceName{ - api.ResourceCPU, - api.ResourceMemory, -} +// supportedComputeResources is the list of compute resources for with QoS is supported. +var supportedQoSComputeResources = sets.NewString(string(api.ResourceCPU), string(api.ResourceMemory)) // allResources returns a set of all possible resources whose mapped key value is true if present on the container func allResources(container *api.Container) map[api.ResourceName]bool { resources := map[api.ResourceName]bool{} - for _, resource := range supportedComputeResources { - resources[resource] = false + for _, resource := range supportedQoSComputeResources.List() { + resources[api.ResourceName(resource)] = false } for resource := range container.Resources.Requests { resources[resource] = true diff --git a/pkg/kubelet/qos/qos_test.go b/pkg/kubelet/qos/qos_test.go index ae356d8e586..f32d568ca2e 100644 --- a/pkg/kubelet/qos/qos_test.go +++ b/pkg/kubelet/qos/qos_test.go @@ -34,6 +34,11 @@ func getResourceList(cpu, memory string) api.ResourceList { return res } +func addResource(rName, value string, rl api.ResourceList) api.ResourceList { + rl[api.ResourceName(rName)] = resource.MustParse(value) + return rl +} + func getResourceRequirements(requests, limits api.ResourceList) api.ResourceRequirements { res := api.ResourceRequirements{} res.Requests = requests @@ -70,6 +75,12 @@ func TestGetPodQOS(t *testing.T) { }), expected: Guaranteed, }, + { + pod: newPod("guaranteed-with-gpu", []api.Container{ + newContainer("guaranteed", getResourceList("100m", "100Mi"), addResource("nvidia-gpu", "2", getResourceList("100m", "100Mi"))), + }), + expected: Guaranteed, + }, { pod: newPod("guaranteed-guaranteed", []api.Container{ newContainer("guaranteed", getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")), @@ -77,6 +88,13 @@ func TestGetPodQOS(t *testing.T) { }), expected: Guaranteed, }, + { + pod: newPod("guaranteed-guaranteed-with-gpu", []api.Container{ + newContainer("guaranteed", getResourceList("100m", "100Mi"), addResource("nvidia-gpu", "2", getResourceList("100m", "100Mi"))), + newContainer("guaranteed", getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")), + }), + expected: Guaranteed, + }, { pod: newPod("best-effort-best-effort", []api.Container{ newContainer("best-effort", getResourceList("", ""), getResourceList("", "")), @@ -85,21 +103,28 @@ func TestGetPodQOS(t *testing.T) { expected: BestEffort, }, { - pod: newPod("best-effort", []api.Container{ + pod: newPod("best-effort-best-effort-with-gpu", []api.Container{ + newContainer("best-effort", getResourceList("", ""), addResource("nvidia-gpu", "2", getResourceList("", ""))), newContainer("best-effort", getResourceList("", ""), getResourceList("", "")), }), expected: BestEffort, }, + { + pod: newPod("best-effort-with-gpu", []api.Container{ + newContainer("best-effort", getResourceList("", ""), addResource("nvidia-gpu", "2", getResourceList("", ""))), + }), + expected: BestEffort, + }, { pod: newPod("best-effort-burstable", []api.Container{ - newContainer("best-effort", getResourceList("", ""), getResourceList("", "")), + newContainer("best-effort", getResourceList("", ""), addResource("nvidia-gpu", "2", getResourceList("", ""))), newContainer("burstable", getResourceList("1", ""), getResourceList("2", "")), }), expected: Burstable, }, { pod: newPod("best-effort-guaranteed", []api.Container{ - newContainer("best-effort", getResourceList("", ""), getResourceList("", "")), + newContainer("best-effort", getResourceList("", ""), addResource("nvidia-gpu", "2", getResourceList("", ""))), newContainer("guaranteed", getResourceList("10m", "100Mi"), getResourceList("10m", "100Mi")), }), expected: Burstable, @@ -118,21 +143,21 @@ func TestGetPodQOS(t *testing.T) { expected: Burstable, }, { - pod: newPod("burstable", []api.Container{ + pod: newPod("burstable-1", []api.Container{ newContainer("burstable", getResourceList("10m", "100Mi"), getResourceList("100m", "200Mi")), }), expected: Burstable, }, { - pod: newPod("burstable", []api.Container{ - newContainer("burstable", getResourceList("0", "0"), getResourceList("100m", "200Mi")), + pod: newPod("burstable-2", []api.Container{ + newContainer("burstable", getResourceList("0", "0"), addResource("nvidia-gpu", "2", getResourceList("100m", "200Mi"))), }), expected: Burstable, }, } - for _, testCase := range testCases { + for id, testCase := range testCases { if actual := GetPodQOS(testCase.pod); testCase.expected != actual { - t.Errorf("invalid qos pod %s, expected: %s, actual: %s", testCase.pod.Name, testCase.expected, actual) + t.Errorf("[%d]: invalid qos pod %s, expected: %s, actual: %s", id, testCase.pod.Name, testCase.expected, actual) } } }