github.com/kubewharf/katalyst-core@v0.5.3/pkg/util/native/pod_resource.go (about)

     1  /*
     2  Copyright 2022 The Katalyst 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 native
    18  
    19  import (
    20  	v1 "k8s.io/api/core/v1"
    21  	"k8s.io/klog/v2"
    22  	"k8s.io/kubernetes/pkg/apis/core/v1/helper/qos"
    23  )
    24  
    25  // PodResource key: namespace/name, value: pod requested ResourceList
    26  type PodResource map[string]v1.ResourceList
    27  
    28  func (pr *PodResource) AddPod(pod *v1.Pod) bool {
    29  	key := pod.Namespace + "/" + pod.Name
    30  
    31  	_, ok := (*pr)[key]
    32  	if ok {
    33  		klog.Warningf("add existing pod: %v", key)
    34  	}
    35  
    36  	requests := CalculateResource(pod)
    37  	(*pr)[key] = requests
    38  	return ok
    39  }
    40  
    41  func (pr *PodResource) DeletePod(pod *v1.Pod) bool {
    42  	key := pod.Namespace + "/" + pod.Name
    43  	_, ok := (*pr)[key]
    44  	if !ok {
    45  		klog.Warningf("delete missing pod: %v", key)
    46  	}
    47  	delete(*pr, key)
    48  	return ok
    49  }
    50  
    51  // CalculateResource resourceRequest = max(sum(podSpec.Containers), podSpec.InitContainers)
    52  func CalculateResource(pod *v1.Pod) v1.ResourceList {
    53  	resources := make(v1.ResourceList)
    54  
    55  	for _, c := range pod.Spec.Containers {
    56  		for resourceName, quantity := range c.Resources.Requests {
    57  			if q, ok := resources[resourceName]; ok {
    58  				quantity.Add(q)
    59  			}
    60  			resources[resourceName] = quantity
    61  		}
    62  	}
    63  
    64  	for _, c := range pod.Spec.InitContainers {
    65  		for resourceName, quantity := range c.Resources.Requests {
    66  			if q, ok := resources[resourceName]; ok && quantity.Cmp(q) <= 0 {
    67  				continue
    68  			}
    69  			resources[resourceName] = quantity
    70  		}
    71  	}
    72  	return resources
    73  }
    74  
    75  func PodGuaranteedCPUs(pod *v1.Pod) int {
    76  	// The maximum of requested CPUs by init containers.
    77  	requestedByInitContainers := 0
    78  	for _, container := range pod.Spec.InitContainers {
    79  		if _, ok := container.Resources.Requests[v1.ResourceCPU]; !ok {
    80  			continue
    81  		}
    82  		requestedCPU := guaranteedCPUs(pod, &container)
    83  		if requestedCPU > requestedByInitContainers {
    84  			requestedByInitContainers = requestedCPU
    85  		}
    86  	}
    87  	// The sum of requested CPUs by app containers.
    88  	requestedByAppContainers := 0
    89  	for _, container := range pod.Spec.Containers {
    90  		if _, ok := container.Resources.Requests[v1.ResourceCPU]; !ok {
    91  			continue
    92  		}
    93  		requestedByAppContainers += guaranteedCPUs(pod, &container)
    94  	}
    95  
    96  	if requestedByInitContainers > requestedByAppContainers {
    97  		return requestedByInitContainers
    98  	}
    99  	return requestedByAppContainers
   100  }
   101  
   102  func guaranteedCPUs(pod *v1.Pod, container *v1.Container) int {
   103  	if qos.GetPodQOS(pod) != v1.PodQOSGuaranteed {
   104  		return 0
   105  	}
   106  	cpuQuantity := container.Resources.Requests[v1.ResourceCPU]
   107  	if cpuQuantity.Value()*1000 != cpuQuantity.MilliValue() {
   108  		return 0
   109  	}
   110  
   111  	return int(cpuQuantity.Value())
   112  }