k8s.io/kubernetes@v1.29.3/pkg/apis/core/v1/helper/qos/qos.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package qos 18 19 import ( 20 v1 "k8s.io/api/core/v1" 21 "k8s.io/apimachinery/pkg/api/resource" 22 "k8s.io/apimachinery/pkg/util/sets" 23 "k8s.io/kubernetes/pkg/apis/core" 24 ) 25 26 var supportedQoSComputeResources = sets.NewString(string(core.ResourceCPU), string(core.ResourceMemory)) 27 28 // QOSList is a set of (resource name, QoS class) pairs. 29 type QOSList map[v1.ResourceName]v1.PodQOSClass 30 31 func isSupportedQoSComputeResource(name v1.ResourceName) bool { 32 return supportedQoSComputeResources.Has(string(name)) 33 } 34 35 // GetPodQOS returns the QoS class of a pod persisted in the PodStatus.QOSClass field. 36 // If PodStatus.QOSClass is empty, it returns value of ComputePodQOS() which evaluates pod's QoS class. 37 func GetPodQOS(pod *v1.Pod) v1.PodQOSClass { 38 if pod.Status.QOSClass != "" { 39 return pod.Status.QOSClass 40 } 41 return ComputePodQOS(pod) 42 } 43 44 // ComputePodQOS evaluates the list of containers to determine a pod's QoS class. This function is more 45 // expensive than GetPodQOS which should be used for pods having a non-empty .Status.QOSClass. 46 // A pod is besteffort if none of its containers have specified any requests or limits. 47 // A pod is guaranteed only when requests and limits are specified for all the containers and they are equal. 48 // A pod is burstable if limits and requests do not match across all containers. 49 func ComputePodQOS(pod *v1.Pod) v1.PodQOSClass { 50 requests := v1.ResourceList{} 51 limits := v1.ResourceList{} 52 zeroQuantity := resource.MustParse("0") 53 isGuaranteed := true 54 allContainers := []v1.Container{} 55 allContainers = append(allContainers, pod.Spec.Containers...) 56 allContainers = append(allContainers, pod.Spec.InitContainers...) 57 for _, container := range allContainers { 58 // process requests 59 for name, quantity := range container.Resources.Requests { 60 if !isSupportedQoSComputeResource(name) { 61 continue 62 } 63 if quantity.Cmp(zeroQuantity) == 1 { 64 delta := quantity.DeepCopy() 65 if _, exists := requests[name]; !exists { 66 requests[name] = delta 67 } else { 68 delta.Add(requests[name]) 69 requests[name] = delta 70 } 71 } 72 } 73 // process limits 74 qosLimitsFound := sets.NewString() 75 for name, quantity := range container.Resources.Limits { 76 if !isSupportedQoSComputeResource(name) { 77 continue 78 } 79 if quantity.Cmp(zeroQuantity) == 1 { 80 qosLimitsFound.Insert(string(name)) 81 delta := quantity.DeepCopy() 82 if _, exists := limits[name]; !exists { 83 limits[name] = delta 84 } else { 85 delta.Add(limits[name]) 86 limits[name] = delta 87 } 88 } 89 } 90 91 if !qosLimitsFound.HasAll(string(v1.ResourceMemory), string(v1.ResourceCPU)) { 92 isGuaranteed = false 93 } 94 } 95 if len(requests) == 0 && len(limits) == 0 { 96 return v1.PodQOSBestEffort 97 } 98 // Check is requests match limits for all resources. 99 if isGuaranteed { 100 for name, req := range requests { 101 if lim, exists := limits[name]; !exists || lim.Cmp(req) != 0 { 102 isGuaranteed = false 103 break 104 } 105 } 106 } 107 if isGuaranteed && 108 len(requests) == len(limits) { 109 return v1.PodQOSGuaranteed 110 } 111 return v1.PodQOSBurstable 112 }