helpers.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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 :=
  85. reqs[corev1.ResourceCPU], limits[corev1.ResourceCPU], reqs[corev1.ResourceMemory], limits[corev1.ResourceMemory], reqs[corev1.ResourceEphemeralStorage], limits[corev1.ResourceEphemeralStorage]
  86. fractionCpuReqs := float64(0)
  87. fractionCpuLimits := float64(0)
  88. if allocatable.Cpu().MilliValue() != 0 {
  89. fractionCpuReqs = float64(cpuReqs.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
  90. fractionCpuLimits = float64(cpuLimits.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
  91. }
  92. fractionMemoryReqs := float64(0)
  93. fractionMemoryLimits := float64(0)
  94. if allocatable.Memory().Value() != 0 {
  95. fractionMemoryReqs = float64(memoryReqs.Value()) / float64(allocatable.Memory().Value()) * 100
  96. fractionMemoryLimits = float64(memoryLimits.Value()) / float64(allocatable.Memory().Value()) * 100
  97. }
  98. fractionEphemeralStorageReqs := float64(0)
  99. fractionEphemeralStorageLimits := float64(0)
  100. if allocatable.StorageEphemeral().Value() != 0 {
  101. fractionEphemeralStorageReqs = float64(ephemeralstorageReqs.Value()) / float64(allocatable.StorageEphemeral().Value()) * 100
  102. fractionEphemeralStorageLimits = float64(ephemeralstorageLimits.Value()) / float64(allocatable.StorageEphemeral().Value()) * 100
  103. }
  104. return &NodeUsage{
  105. cpuReqs: cpuReqs.String(),
  106. memoryReqs: memoryReqs.String(),
  107. ephemeralStorageReqs: ephemeralstorageReqs.String(),
  108. fractionCpuReqs: fractionCpuReqs,
  109. fractionCpuLimits: fractionCpuLimits,
  110. fractionMemoryReqs: fractionMemoryReqs,
  111. fractionMemoryLimits: fractionMemoryLimits,
  112. fractionEphemeralStorageReqs: fractionEphemeralStorageReqs,
  113. fractionEphemeralStorageLimits: fractionEphemeralStorageLimits,
  114. }
  115. }