nodes.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package nodes
  2. import (
  3. "context"
  4. "sync"
  5. v1 "k8s.io/api/core/v1"
  6. "k8s.io/client-go/kubernetes"
  7. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  8. )
  9. type TotalAllocatable struct {
  10. CPU uint
  11. Memory uint
  12. }
  13. func GetAllocatableResources(clientset kubernetes.Interface) (*TotalAllocatable, error) {
  14. nodeList, err := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
  15. if err != nil {
  16. return nil, err
  17. }
  18. var totCPU uint64 = 0
  19. var totMem uint64 = 0
  20. for _, node := range nodeList.Items {
  21. capac := node.Status.Allocatable
  22. totCPU += uint64(capac.Cpu().MilliValue())
  23. totMem += capac.Memory().AsDec().UnscaledBig().Uint64()
  24. }
  25. return &TotalAllocatable{
  26. CPU: uint(totCPU),
  27. Memory: uint(totMem),
  28. }, nil
  29. }
  30. type NodeUsage struct {
  31. cpuReqs string
  32. memoryReqs string
  33. ephemeralStorageReqs string
  34. fractionCpuReqs float64
  35. fractionCpuLimits float64
  36. fractionMemoryReqs float64
  37. fractionMemoryLimits float64
  38. fractionEphemeralStorageReqs float64
  39. fractionEphemeralStorageLimits float64
  40. }
  41. type NodeWithUsageData struct {
  42. Name string `json:"name"`
  43. Labels map[string]string `json:"labels"`
  44. CpuReqs string `json:"cpu_reqs"`
  45. MemoryReqs string `json:"memory_reqs"`
  46. EphemeralStorageReqs string `json:"ephemeral_storage_reqs"`
  47. FractionCpuReqs float64 `json:"fraction_cpu_reqs"`
  48. FractionCpuLimits float64 `json:"fraction_cpu_limits"`
  49. FractionMemoryReqs float64 `json:"fraction_memory_reqs"`
  50. FractionMemoryLimits float64 `json:"fraction_memory_limits"`
  51. FractionEphemeralStorageReqs float64 `json:"fraction_ephemeral_storage_reqs"`
  52. FractionEphemeralStorageLimits float64 `json:"fraction_ephemeral_storage_limits"`
  53. Condition []v1.NodeCondition `json:"node_conditions"`
  54. }
  55. func (nu *NodeUsage) Externalize(node v1.Node) *NodeWithUsageData {
  56. return &NodeWithUsageData{
  57. Name: node.Name,
  58. Labels: node.Labels,
  59. CpuReqs: nu.cpuReqs,
  60. MemoryReqs: nu.memoryReqs,
  61. EphemeralStorageReqs: nu.ephemeralStorageReqs,
  62. FractionCpuReqs: nu.fractionCpuReqs,
  63. FractionCpuLimits: nu.fractionCpuLimits,
  64. FractionMemoryReqs: nu.fractionMemoryReqs,
  65. FractionMemoryLimits: nu.fractionMemoryLimits,
  66. FractionEphemeralStorageReqs: nu.fractionEphemeralStorageReqs,
  67. FractionEphemeralStorageLimits: nu.fractionEphemeralStorageLimits,
  68. Condition: node.Status.Conditions,
  69. }
  70. }
  71. func GetNodesUsage(clientset kubernetes.Interface) []*NodeWithUsageData {
  72. nodeList, _ := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
  73. extNodeList := make([]*NodeWithUsageData, len(nodeList.Items))
  74. var wg sync.WaitGroup
  75. for i := range nodeList.Items {
  76. index := i
  77. currentNode := &nodeList.Items[index]
  78. wg.Add(1)
  79. go func() {
  80. defer wg.Done()
  81. podList := getPodsForNode(clientset, currentNode.Name)
  82. nodeUsage := DescribeNodeResource(podList, currentNode)
  83. extNodeList[index] = nodeUsage.Externalize(*currentNode)
  84. }()
  85. }
  86. wg.Wait()
  87. return extNodeList
  88. }
  89. func getPodsForNode(clientset kubernetes.Interface, nodeName string) *v1.PodList {
  90. podList, _ := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{
  91. FieldSelector: "spec.nodeName=" + nodeName + ",status.phase=Running",
  92. })
  93. return podList
  94. }
  95. type NodeDetails struct {
  96. NodeWithUsageData
  97. AllocatableCpu int64 `json:"allocatable_cpu"`
  98. AllocatableMemory string `json:"allocatable_memory"`
  99. }
  100. func DescribeNode(clientset kubernetes.Interface, nodeName string) *NodeDetails {
  101. node, _ := clientset.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
  102. podList := getPodsForNode(clientset, node.Name)
  103. nodeUsage := DescribeNodeResource(podList, node)
  104. extNodeUsage := nodeUsage.Externalize(*node)
  105. return &NodeDetails{
  106. NodeWithUsageData: *extNodeUsage,
  107. AllocatableCpu: node.Status.Allocatable.Cpu().MilliValue(),
  108. AllocatableMemory: node.Status.Allocatable.Memory().String(),
  109. }
  110. }