k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/apis/core/helper/qos/qos.go (about) 1 /* 2 Copyright 2017 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 // NOTE: DO NOT use those helper functions through client-go, the 18 // package path will be changed in the future. 19 package qos 20 21 import ( 22 "k8s.io/apimachinery/pkg/api/resource" 23 "k8s.io/apimachinery/pkg/util/sets" 24 "k8s.io/kubernetes/pkg/apis/core" 25 ) 26 27 var supportedQoSComputeResources = sets.NewString(string(core.ResourceCPU), string(core.ResourceMemory)) 28 29 func isSupportedQoSComputeResource(name core.ResourceName) bool { 30 return supportedQoSComputeResources.Has(string(name)) 31 } 32 33 // GetPodQOS returns the QoS class of a pod persisted in the PodStatus.QOSClass field. 34 // If PodStatus.QOSClass is empty, it returns value of ComputePodQOS() which evaluates pod's QoS class. 35 func GetPodQOS(pod *core.Pod) core.PodQOSClass { 36 if pod.Status.QOSClass != "" { 37 return pod.Status.QOSClass 38 } 39 return ComputePodQOS(pod) 40 } 41 42 // ComputePodQOS evaluates the list of containers to determine a pod's QoS class. This function is more 43 // expensive than GetPodQOS which should be used for pods having a non-empty .Status.QOSClass. 44 // A pod is besteffort if none of its containers have specified any requests or limits. 45 // A pod is guaranteed only when requests and limits are specified for all the containers and they are equal. 46 // A pod is burstable if limits and requests do not match across all containers. 47 // When this function is updated please also update staging/src/k8s.io/kubectl/pkg/util/qos/qos.go 48 func ComputePodQOS(pod *core.Pod) core.PodQOSClass { 49 requests := core.ResourceList{} 50 limits := core.ResourceList{} 51 zeroQuantity := resource.MustParse("0") 52 isGuaranteed := true 53 // note, ephemeral containers are not considered for QoS as they cannot define resources 54 allContainers := []core.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(core.ResourceMemory), string(core.ResourceCPU)) { 92 isGuaranteed = false 93 } 94 } 95 if len(requests) == 0 && len(limits) == 0 { 96 return core.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 core.PodQOSGuaranteed 110 } 111 return core.PodQOSBurstable 112 }