nodes.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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 NodeUsage struct {
  10. cpuReqs string
  11. memoryReqs string
  12. ephemeralStorageReqs string
  13. fractionCpuReqs float64
  14. fractionCpuLimits float64
  15. fractionMemoryReqs float64
  16. fractionMemoryLimits float64
  17. fractionEphemeralStorageReqs float64
  18. fractionEphemeralStorageLimits float64
  19. }
  20. type NodeWithUsageData struct {
  21. Name string `json:"name"`
  22. Labels map[string]string `json:"labels"`
  23. CpuReqs string `json:"cpu_reqs"`
  24. MemoryReqs string `json:"memory_reqs"`
  25. EphemeralStorageReqs string `json:"ephemeral_storage_reqs"`
  26. FractionCpuReqs float64 `json:"fraction_cpu_reqs"`
  27. FractionCpuLimits float64 `json:"fraction_cpu_limits"`
  28. FractionMemoryReqs float64 `json:"fraction_memory_reqs"`
  29. FractionMemoryLimits float64 `json:"fraction_memory_limits"`
  30. FractionEphemeralStorageReqs float64 `json:"fraction_ephemeral_storage_reqs"`
  31. FractionEphemeralStorageLimits float64 `json:"fraction_ephemeral_storage_limits"`
  32. Condition []v1.NodeCondition `json:"node_conditions"`
  33. }
  34. func (nu *NodeUsage) Externalize(node v1.Node) *NodeWithUsageData {
  35. return &NodeWithUsageData{
  36. Name: node.Name,
  37. Labels: node.Labels,
  38. CpuReqs: nu.cpuReqs,
  39. MemoryReqs: nu.memoryReqs,
  40. EphemeralStorageReqs: nu.ephemeralStorageReqs,
  41. FractionCpuReqs: nu.fractionCpuReqs,
  42. FractionCpuLimits: nu.fractionCpuLimits,
  43. FractionMemoryReqs: nu.fractionMemoryReqs,
  44. FractionMemoryLimits: nu.fractionMemoryLimits,
  45. FractionEphemeralStorageReqs: nu.fractionEphemeralStorageReqs,
  46. FractionEphemeralStorageLimits: nu.fractionEphemeralStorageLimits,
  47. Condition: node.Status.Conditions,
  48. }
  49. }
  50. func GetNodesUsage(clientset kubernetes.Interface) []*NodeWithUsageData {
  51. nodeList, _ := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
  52. extNodeList := make([]*NodeWithUsageData, len(nodeList.Items))
  53. var wg sync.WaitGroup
  54. for i := range nodeList.Items {
  55. index := i
  56. currentNode := &nodeList.Items[index]
  57. wg.Add(1)
  58. go func() {
  59. defer wg.Done()
  60. podList := getPodsForNode(clientset, currentNode.Name)
  61. nodeUsage := DescribeNodeResource(podList, currentNode)
  62. extNodeList[index] = nodeUsage.Externalize(*currentNode)
  63. }()
  64. }
  65. wg.Wait()
  66. return extNodeList
  67. }
  68. func getPodsForNode(clientset kubernetes.Interface, nodeName string) *v1.PodList {
  69. podList, _ := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{
  70. FieldSelector: "spec.nodeName=" + nodeName + ",status.phase=Running",
  71. })
  72. return podList
  73. }
  74. type NodeDetails struct {
  75. NodeWithUsageData
  76. AllocatableCpu int64 `json:"allocatable_cpu"`
  77. AllocatableMemory string `json:"allocatable_memory"`
  78. }
  79. func DescribeNode(clientset kubernetes.Interface, nodeName string) *NodeDetails {
  80. node, _ := clientset.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
  81. podList := getPodsForNode(clientset, node.Name)
  82. nodeUsage := DescribeNodeResource(podList, node)
  83. extNodeUsage := nodeUsage.Externalize(*node)
  84. return &NodeDetails{
  85. NodeWithUsageData: *extNodeUsage,
  86. AllocatableCpu: node.Status.Allocatable.Cpu().MilliValue(),
  87. AllocatableMemory: node.Status.Allocatable.Memory().String(),
  88. }
  89. }