helpers.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package nodes
  2. import (
  3. corev1 "k8s.io/api/core/v1"
  4. "k8s.io/apimachinery/pkg/api/resource"
  5. )
  6. func getPodsTotalRequestsAndLimits(podList *corev1.PodList) (reqs map[corev1.ResourceName]resource.Quantity, limits map[corev1.ResourceName]resource.Quantity) {
  7. reqs, limits = map[corev1.ResourceName]resource.Quantity{}, map[corev1.ResourceName]resource.Quantity{}
  8. for _, pod := range podList.Items {
  9. podReqs, podLimits := podRequestsAndLimits(&pod)
  10. for podReqName, podReqValue := range podReqs {
  11. if value, ok := reqs[podReqName]; !ok {
  12. reqs[podReqName] = podReqValue.DeepCopy()
  13. } else {
  14. value.Add(podReqValue)
  15. reqs[podReqName] = value
  16. }
  17. }
  18. for podLimitName, podLimitValue := range podLimits {
  19. if value, ok := limits[podLimitName]; !ok {
  20. limits[podLimitName] = podLimitValue.DeepCopy()
  21. } else {
  22. value.Add(podLimitValue)
  23. limits[podLimitName] = value
  24. }
  25. }
  26. }
  27. return
  28. }
  29. func podRequestsAndLimits(pod *corev1.Pod) (reqs, limits corev1.ResourceList) {
  30. reqs, limits = corev1.ResourceList{}, corev1.ResourceList{}
  31. for _, container := range pod.Spec.Containers {
  32. addResourceList(reqs, container.Resources.Requests)
  33. addResourceList(limits, container.Resources.Limits)
  34. }
  35. // init containers define the minimum of any resource
  36. for _, container := range pod.Spec.InitContainers {
  37. maxResourceList(reqs, container.Resources.Requests)
  38. maxResourceList(limits, container.Resources.Limits)
  39. }
  40. // Add overhead for running a pod to the sum of requests and to non-zero limits:
  41. if pod.Spec.Overhead != nil {
  42. addResourceList(reqs, pod.Spec.Overhead)
  43. for name, quantity := range pod.Spec.Overhead {
  44. if value, ok := limits[name]; ok && !value.IsZero() {
  45. value.Add(quantity)
  46. limits[name] = value
  47. }
  48. }
  49. }
  50. return
  51. }
  52. // addResourceList adds the resources in newList to list
  53. func addResourceList(list, new corev1.ResourceList) {
  54. for name, quantity := range new {
  55. if value, ok := list[name]; !ok {
  56. list[name] = quantity.DeepCopy()
  57. } else {
  58. value.Add(quantity)
  59. list[name] = value
  60. }
  61. }
  62. }
  63. // maxResourceList sets list to the greater of list/newList for every resource
  64. // either list
  65. func maxResourceList(list, new corev1.ResourceList) {
  66. for name, quantity := range new {
  67. if value, ok := list[name]; !ok {
  68. list[name] = quantity.DeepCopy()
  69. continue
  70. } else {
  71. if quantity.Cmp(value) > 0 {
  72. list[name] = quantity.DeepCopy()
  73. }
  74. }
  75. }
  76. }
  77. // Returns the summatory of resources requested and their limits by a list of pods on a specific node in fraction values.
  78. func DescribeNodeResource(nodeNonTerminatedPodsList *corev1.PodList, node *corev1.Node) *NodeUsage {
  79. allocatable := node.Status.Capacity
  80. if len(node.Status.Allocatable) > 0 {
  81. allocatable = node.Status.Allocatable
  82. }
  83. reqs, limits := getPodsTotalRequestsAndLimits(nodeNonTerminatedPodsList)
  84. cpuReqs, cpuLimits, memoryReqs, memoryLimits, ephemeralstorageReqs, ephemeralstorageLimits := reqs[corev1.ResourceCPU], limits[corev1.ResourceCPU], reqs[corev1.ResourceMemory], limits[corev1.ResourceMemory], reqs[corev1.ResourceEphemeralStorage], limits[corev1.ResourceEphemeralStorage]
  85. fractionCpuReqs := float64(0)
  86. fractionCpuLimits := float64(0)
  87. if allocatable.Cpu().MilliValue() != 0 {
  88. fractionCpuReqs = float64(cpuReqs.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
  89. fractionCpuLimits = float64(cpuLimits.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
  90. }
  91. fractionMemoryReqs := float64(0)
  92. fractionMemoryLimits := float64(0)
  93. if allocatable.Memory().Value() != 0 {
  94. fractionMemoryReqs = float64(memoryReqs.Value()) / float64(allocatable.Memory().Value()) * 100
  95. fractionMemoryLimits = float64(memoryLimits.Value()) / float64(allocatable.Memory().Value()) * 100
  96. }
  97. fractionEphemeralStorageReqs := float64(0)
  98. fractionEphemeralStorageLimits := float64(0)
  99. if allocatable.StorageEphemeral().Value() != 0 {
  100. fractionEphemeralStorageReqs = float64(ephemeralstorageReqs.Value()) / float64(allocatable.StorageEphemeral().Value()) * 100
  101. fractionEphemeralStorageLimits = float64(ephemeralstorageLimits.Value()) / float64(allocatable.StorageEphemeral().Value()) * 100
  102. }
  103. return &NodeUsage{
  104. cpuReqs: cpuReqs.String(),
  105. memoryReqs: memoryReqs.String(),
  106. ephemeralStorageReqs: ephemeralstorageReqs.String(),
  107. fractionCpuReqs: fractionCpuReqs,
  108. fractionCpuLimits: fractionCpuLimits,
  109. fractionMemoryReqs: fractionMemoryReqs,
  110. fractionMemoryLimits: fractionMemoryLimits,
  111. fractionEphemeralStorageReqs: fractionEphemeralStorageReqs,
  112. fractionEphemeralStorageLimits: fractionEphemeralStorageLimits,
  113. }
  114. }