Просмотр исходного кода

Add adjustmentRate to ComputeIdleAllocations

Niko Kovacevic 5 лет назад
Родитель
Сommit
38604f99c5
1 измененных файлов с 31 добавлено и 9 удалено
  1. 31 9
      pkg/kubecost/allocation.go

+ 31 - 9
pkg/kubecost/allocation.go

@@ -1108,17 +1108,15 @@ func (as *AllocationSet) Clone() *AllocationSet {
 // ComputeIdleAllocations computes the idle allocations for the AllocationSet,
 // given a set of Assets. Ideally, assetSet should contain only Nodes, but if
 // it contains other Assets, they will be ignored; only CPU, GPU and RAM are
-// considered for idle allocation. One idle allocation per-cluster will be
-// computed and returned, keyed by cluster_id.
+// considered for idle allocation. If the Nodes have adjustments, then apply
+// the adjustments proportionally to each of the resources so that total
+// allocation with idle reflects the adjusted node costs. One idle allocation
+// per-cluster will be computed and returned, keyed by cluster_id.
 func (as *AllocationSet) ComputeIdleAllocations(assetSet *AssetSet) (map[string]*Allocation, error) {
 	if as == nil {
 		return nil, fmt.Errorf("cannot compute idle allocation for nil AllocationSet")
 	}
 
-	// TODO: external allocation: remove after testing and benchmarking
-	profStart := time.Now()
-	defer log.Profile(profStart, fmt.Sprintf("ComputeIdleAllocations: %s", as.Window))
-
 	if assetSet == nil {
 		return nil, fmt.Errorf("cannot compute idle allocation with nil AssetSet")
 	}
@@ -1137,9 +1135,33 @@ func (as *AllocationSet) ComputeIdleAllocations(assetSet *AssetSet) (map[string]
 			if _, ok := assetClusterResourceCosts[node.Properties().Cluster]; !ok {
 				assetClusterResourceCosts[node.Properties().Cluster] = map[string]float64{}
 			}
-			assetClusterResourceCosts[node.Properties().Cluster]["cpu"] += node.CPUCost * (1.0 - node.Discount)
-			assetClusterResourceCosts[node.Properties().Cluster]["gpu"] += node.GPUCost * (1.0 - node.Discount)
-			assetClusterResourceCosts[node.Properties().Cluster]["ram"] += node.RAMCost * (1.0 - node.Discount)
+
+			// adjustmentRate is used to scale resource costs proportionally
+			// by the adjustment. This is necessary because we only get one
+			// adjustment per Node, not one per-resource-per-Node.
+			//
+			// e.g. total cost = $90, adjustment = -$10 => 0.9
+			// e.g. total cost = $150, adjustment = -$300 => 0.3333
+			// e.g. total cost = $150, adjustment = $50 => 1.5
+			adjustmentRate := 1.0
+			if node.TotalCost()-node.Adjustment() == 0 {
+				// If (totalCost - adjustment) is 0.0 then adjustment cancels
+				// the entire node cost and we should make everything 0
+				// without dividing by 0.
+				adjustmentRate = 0.0
+			} else if node.Adjustment() != 0.0 {
+				// adjustmentRate is the ratio of cost-with-adjustment (i.e. TotalCost)
+				// to cost-without-adjustment (i.e. TotalCost - Adjustment).
+				adjustmentRate = node.TotalCost() / (node.TotalCost() - node.Adjustment())
+			}
+
+			cpuCost := node.CPUCost * (1.0 - node.Discount) * adjustmentRate
+			gpuCost := node.GPUCost * (1.0 - node.Discount) * adjustmentRate
+			ramCost := node.RAMCost * (1.0 - node.Discount) * adjustmentRate
+
+			assetClusterResourceCosts[node.Properties().Cluster]["cpu"] += cpuCost
+			assetClusterResourceCosts[node.Properties().Cluster]["gpu"] += gpuCost
+			assetClusterResourceCosts[node.Properties().Cluster]["ram"] += ramCost
 		}
 	})