mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #114390 from tangwz/improve_NodeResourcesFit_replace_small_maps_with_slices
Improve performance of NodeResourcesFit scoring
This commit is contained in:
commit
419e0ec3d2
@ -78,28 +78,25 @@ func NewBalancedAllocation(baArgs runtime.Object, h framework.Handle, fts featur
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resToWeightMap := make(resourceToWeightMap)
|
|
||||||
|
|
||||||
for _, resource := range args.Resources {
|
|
||||||
resToWeightMap[v1.ResourceName(resource.Name)] = resource.Weight
|
|
||||||
}
|
|
||||||
|
|
||||||
return &BalancedAllocation{
|
return &BalancedAllocation{
|
||||||
handle: h,
|
handle: h,
|
||||||
resourceAllocationScorer: resourceAllocationScorer{
|
resourceAllocationScorer: resourceAllocationScorer{
|
||||||
Name: BalancedAllocationName,
|
Name: BalancedAllocationName,
|
||||||
scorer: balancedResourceScorer,
|
scorer: balancedResourceScorer,
|
||||||
useRequested: true,
|
useRequested: true,
|
||||||
resourceToWeightMap: resToWeightMap,
|
resources: args.Resources,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func balancedResourceScorer(requested, allocable resourceToValueMap) int64 {
|
func balancedResourceScorer(requested, allocable []int64) int64 {
|
||||||
var resourceToFractions []float64
|
var resourceToFractions []float64
|
||||||
var totalFraction float64
|
var totalFraction float64
|
||||||
for name, value := range requested {
|
for i := range requested {
|
||||||
fraction := float64(value) / float64(allocable[name])
|
if allocable[i] == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fraction := float64(requested[i]) / float64(allocable[i])
|
||||||
if fraction > 1 {
|
if fraction > 1 {
|
||||||
fraction = 1
|
fraction = 1
|
||||||
}
|
}
|
||||||
|
@ -49,27 +49,27 @@ const (
|
|||||||
// nodeResourceStrategyTypeMap maps strategy to scorer implementation
|
// nodeResourceStrategyTypeMap maps strategy to scorer implementation
|
||||||
var nodeResourceStrategyTypeMap = map[config.ScoringStrategyType]scorer{
|
var nodeResourceStrategyTypeMap = map[config.ScoringStrategyType]scorer{
|
||||||
config.LeastAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer {
|
config.LeastAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer {
|
||||||
resToWeightMap := resourcesToWeightMap(args.ScoringStrategy.Resources)
|
resources := args.ScoringStrategy.Resources
|
||||||
return &resourceAllocationScorer{
|
return &resourceAllocationScorer{
|
||||||
Name: string(config.LeastAllocated),
|
Name: string(config.LeastAllocated),
|
||||||
scorer: leastResourceScorer(resToWeightMap),
|
scorer: leastResourceScorer(resources),
|
||||||
resourceToWeightMap: resToWeightMap,
|
resources: resources,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
config.MostAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer {
|
config.MostAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer {
|
||||||
resToWeightMap := resourcesToWeightMap(args.ScoringStrategy.Resources)
|
resources := args.ScoringStrategy.Resources
|
||||||
return &resourceAllocationScorer{
|
return &resourceAllocationScorer{
|
||||||
Name: string(config.MostAllocated),
|
Name: string(config.MostAllocated),
|
||||||
scorer: mostResourceScorer(resToWeightMap),
|
scorer: mostResourceScorer(resources),
|
||||||
resourceToWeightMap: resToWeightMap,
|
resources: resources,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
config.RequestedToCapacityRatio: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer {
|
config.RequestedToCapacityRatio: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer {
|
||||||
resToWeightMap := resourcesToWeightMap(args.ScoringStrategy.Resources)
|
resources := args.ScoringStrategy.Resources
|
||||||
return &resourceAllocationScorer{
|
return &resourceAllocationScorer{
|
||||||
Name: string(config.RequestedToCapacityRatio),
|
Name: string(config.RequestedToCapacityRatio),
|
||||||
scorer: requestedToCapacityRatioScorer(resToWeightMap, args.ScoringStrategy.RequestedToCapacityRatio.Shape),
|
scorer: requestedToCapacityRatioScorer(resources, args.ScoringStrategy.RequestedToCapacityRatio.Shape),
|
||||||
resourceToWeightMap: resToWeightMap,
|
resources: resources,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
plfeature "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
plfeature "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
||||||
|
plugintesting "k8s.io/kubernetes/pkg/scheduler/framework/plugins/testing"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
"k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
||||||
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
@ -780,3 +781,115 @@ func TestFitScore(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var benchmarkResourceSet = []config.ResourceSpec{
|
||||||
|
{Name: string(v1.ResourceCPU), Weight: 1},
|
||||||
|
{Name: string(v1.ResourceMemory), Weight: 1},
|
||||||
|
{Name: string(v1.ResourcePods), Weight: 1},
|
||||||
|
{Name: string(v1.ResourceStorage), Weight: 1},
|
||||||
|
{Name: string(v1.ResourceEphemeralStorage), Weight: 1},
|
||||||
|
{Name: string(extendedResourceA), Weight: 1},
|
||||||
|
{Name: string(extendedResourceB), Weight: 1},
|
||||||
|
{Name: string(kubernetesIOResourceA), Weight: 1},
|
||||||
|
{Name: string(kubernetesIOResourceB), Weight: 1},
|
||||||
|
{Name: string(hugePageResourceA), Weight: 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTestFitScore(b *testing.B) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
nodeResourcesFitArgs config.NodeResourcesFitArgs
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "RequestedToCapacityRatio with defaultResources",
|
||||||
|
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||||
|
ScoringStrategy: &config.ScoringStrategy{
|
||||||
|
Type: config.RequestedToCapacityRatio,
|
||||||
|
Resources: defaultResources,
|
||||||
|
RequestedToCapacityRatio: &config.RequestedToCapacityRatioParam{
|
||||||
|
Shape: []config.UtilizationShapePoint{
|
||||||
|
{Utilization: 0, Score: 10},
|
||||||
|
{Utilization: 100, Score: 0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "RequestedToCapacityRatio with 10 resources",
|
||||||
|
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||||
|
ScoringStrategy: &config.ScoringStrategy{
|
||||||
|
Type: config.RequestedToCapacityRatio,
|
||||||
|
Resources: benchmarkResourceSet,
|
||||||
|
RequestedToCapacityRatio: &config.RequestedToCapacityRatioParam{
|
||||||
|
Shape: []config.UtilizationShapePoint{
|
||||||
|
{Utilization: 0, Score: 10},
|
||||||
|
{Utilization: 100, Score: 0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MostAllocated with defaultResources",
|
||||||
|
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||||
|
ScoringStrategy: &config.ScoringStrategy{
|
||||||
|
Type: config.MostAllocated,
|
||||||
|
Resources: defaultResources,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MostAllocated with 10 resources",
|
||||||
|
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||||
|
ScoringStrategy: &config.ScoringStrategy{
|
||||||
|
Type: config.MostAllocated,
|
||||||
|
Resources: benchmarkResourceSet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "LeastAllocated with defaultResources",
|
||||||
|
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||||
|
ScoringStrategy: &config.ScoringStrategy{
|
||||||
|
Type: config.LeastAllocated,
|
||||||
|
Resources: defaultResources,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "LeastAllocated with 10 resources",
|
||||||
|
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||||
|
ScoringStrategy: &config.ScoringStrategy{
|
||||||
|
Type: config.LeastAllocated,
|
||||||
|
Resources: benchmarkResourceSet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
b.Run(test.name, func(b *testing.B) {
|
||||||
|
existingPods := []*v1.Pod{
|
||||||
|
st.MakePod().Node("node1").Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "4000"}).Obj(),
|
||||||
|
}
|
||||||
|
nodes := []*v1.Node{
|
||||||
|
st.MakeNode().Name("node1").Capacity(map[v1.ResourceName]string{"cpu": "4000", "memory": "10000"}).Obj(),
|
||||||
|
}
|
||||||
|
state := framework.NewCycleState()
|
||||||
|
var nodeResourcesFunc = runtime.FactoryAdapter(plfeature.Features{}, NewFit)
|
||||||
|
pl := plugintesting.SetupPlugin(b, nodeResourcesFunc, &test.nodeResourcesFitArgs, cache.NewSnapshot(existingPods, nodes))
|
||||||
|
p := pl.(*Fit)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
requestedPod := st.MakePod().Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).Obj()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, status := p.Score(context.Background(), state, requestedPod, nodes[0].Name)
|
||||||
|
if !status.IsSuccess() {
|
||||||
|
b.Errorf("unexpected status: %v", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package noderesources
|
package noderesources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,12 +27,15 @@ import (
|
|||||||
//
|
//
|
||||||
// Details:
|
// Details:
|
||||||
// (cpu((capacity-requested)*MaxNodeScore*cpuWeight/capacity) + memory((capacity-requested)*MaxNodeScore*memoryWeight/capacity) + ...)/weightSum
|
// (cpu((capacity-requested)*MaxNodeScore*cpuWeight/capacity) + memory((capacity-requested)*MaxNodeScore*memoryWeight/capacity) + ...)/weightSum
|
||||||
func leastResourceScorer(resToWeightMap resourceToWeightMap) func(resourceToValueMap, resourceToValueMap) int64 {
|
func leastResourceScorer(resources []config.ResourceSpec) func([]int64, []int64) int64 {
|
||||||
return func(requested, allocable resourceToValueMap) int64 {
|
return func(requested, allocable []int64) int64 {
|
||||||
var nodeScore, weightSum int64
|
var nodeScore, weightSum int64
|
||||||
for resource := range requested {
|
for i := range requested {
|
||||||
weight := resToWeightMap[resource]
|
if allocable[i] == 0 {
|
||||||
resourceScore := leastRequestedScore(requested[resource], allocable[resource])
|
continue
|
||||||
|
}
|
||||||
|
weight := resources[i].Weight
|
||||||
|
resourceScore := leastRequestedScore(requested[i], allocable[i])
|
||||||
nodeScore += resourceScore * weight
|
nodeScore += resourceScore * weight
|
||||||
weightSum += weight
|
weightSum += weight
|
||||||
}
|
}
|
||||||
|
@ -360,6 +360,27 @@ func TestLeastAllocatedScoringStrategy(t *testing.T) {
|
|||||||
expectedScores: []framework.NodeScore{{Name: "node1", Score: 50}, {Name: "node2", Score: 60}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 50}, {Name: "node2", Score: 60}},
|
||||||
resources: extendedResourceSet,
|
resources: extendedResourceSet,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// If the node doesn't have a resource
|
||||||
|
// CPU Score: ((6000 - 3000) * 100) / 6000 = 50
|
||||||
|
// Memory Score: ((10000 - 4000) * 100) / 10000 = 60
|
||||||
|
// Node1 Score: (50 * 1 + 60 * 1) / (1 + 1) = 55
|
||||||
|
// Node2 Score: (50 * 1 + 60 * 1) / (1 + 1) = 55
|
||||||
|
name: "if the node doesn't have a resource",
|
||||||
|
requestedPod: st.MakePod().Node("node1").
|
||||||
|
Req(map[v1.ResourceName]string{"cpu": "3000", "memory": "4000"}).
|
||||||
|
Obj(),
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node1").Capacity(map[v1.ResourceName]string{"cpu": "6000", "memory": "10000"}).Obj(),
|
||||||
|
st.MakeNode().Name("node2").Capacity(map[v1.ResourceName]string{"cpu": "6000", "memory": "10000", v1.ResourceName(extendedRes): "4"}).Obj(),
|
||||||
|
},
|
||||||
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 55}, {Name: "node2", Score: 55}},
|
||||||
|
resources: []config.ResourceSpec{
|
||||||
|
{Name: extendedRes, Weight: 2},
|
||||||
|
{Name: string(v1.ResourceCPU), Weight: 1},
|
||||||
|
{Name: string(v1.ResourceMemory), Weight: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package noderesources
|
package noderesources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,12 +27,15 @@ import (
|
|||||||
//
|
//
|
||||||
// Details:
|
// Details:
|
||||||
// (cpu(MaxNodeScore * requested * cpuWeight / capacity) + memory(MaxNodeScore * requested * memoryWeight / capacity) + ...) / weightSum
|
// (cpu(MaxNodeScore * requested * cpuWeight / capacity) + memory(MaxNodeScore * requested * memoryWeight / capacity) + ...) / weightSum
|
||||||
func mostResourceScorer(resToWeightMap resourceToWeightMap) func(requested, allocable resourceToValueMap) int64 {
|
func mostResourceScorer(resources []config.ResourceSpec) func(requested, allocable []int64) int64 {
|
||||||
return func(requested, allocable resourceToValueMap) int64 {
|
return func(requested, allocable []int64) int64 {
|
||||||
var nodeScore, weightSum int64
|
var nodeScore, weightSum int64
|
||||||
for resource := range requested {
|
for i := range requested {
|
||||||
weight := resToWeightMap[resource]
|
if allocable[i] == 0 {
|
||||||
resourceScore := mostRequestedScore(requested[resource], allocable[resource])
|
continue
|
||||||
|
}
|
||||||
|
weight := resources[i].Weight
|
||||||
|
resourceScore := mostRequestedScore(requested[i], allocable[i])
|
||||||
nodeScore += resourceScore * weight
|
nodeScore += resourceScore * weight
|
||||||
weightSum += weight
|
weightSum += weight
|
||||||
}
|
}
|
||||||
|
@ -317,6 +317,27 @@ func TestMostAllocatedScoringStrategy(t *testing.T) {
|
|||||||
existingPods: nil,
|
existingPods: nil,
|
||||||
expectedScores: []framework.NodeScore{{Name: "node1", Score: 50}, {Name: "node2", Score: 40}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 50}, {Name: "node2", Score: 40}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// If the node doesn't have a resource
|
||||||
|
// CPU Score: (3000 * 100) / 6000 = 50
|
||||||
|
// Memory Score: (4000 * 100) / 10000 = 40
|
||||||
|
// Node1 Score: (50 * 1 + 40 * 1) / (1 + 1) = 45
|
||||||
|
// Node2 Score: (50 * 1 + 40 * 1) / (1 + 1) = 45
|
||||||
|
name: "if the node doesn't have a resource",
|
||||||
|
requestedPod: st.MakePod().Node("node1").
|
||||||
|
Req(map[v1.ResourceName]string{"cpu": "3000", "memory": "4000"}).
|
||||||
|
Obj(),
|
||||||
|
nodes: []*v1.Node{
|
||||||
|
st.MakeNode().Name("node1").Capacity(map[v1.ResourceName]string{"cpu": "6000", "memory": "10000"}).Obj(),
|
||||||
|
st.MakeNode().Name("node2").Capacity(map[v1.ResourceName]string{"cpu": "6000", "memory": "10000", v1.ResourceName(extendedRes): "4"}).Obj(),
|
||||||
|
},
|
||||||
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 45}, {Name: "node2", Score: 45}},
|
||||||
|
resources: []config.ResourceSpec{
|
||||||
|
{Name: extendedRes, Weight: 2},
|
||||||
|
{Name: string(v1.ResourceCPU), Weight: 1},
|
||||||
|
{Name: string(v1.ResourceMemory), Weight: 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -28,7 +28,7 @@ const maxUtilization = 100
|
|||||||
|
|
||||||
// buildRequestedToCapacityRatioScorerFunction allows users to apply bin packing
|
// buildRequestedToCapacityRatioScorerFunction allows users to apply bin packing
|
||||||
// on core resources like CPU, Memory as well as extended resources like accelerators.
|
// on core resources like CPU, Memory as well as extended resources like accelerators.
|
||||||
func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.FunctionShape, resourceToWeightMap resourceToWeightMap) func(resourceToValueMap, resourceToValueMap) int64 {
|
func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.FunctionShape, resources []config.ResourceSpec) func([]int64, []int64) int64 {
|
||||||
rawScoringFunction := helper.BuildBrokenLinearFunction(scoringFunctionShape)
|
rawScoringFunction := helper.BuildBrokenLinearFunction(scoringFunctionShape)
|
||||||
resourceScoringFunction := func(requested, capacity int64) int64 {
|
resourceScoringFunction := func(requested, capacity int64) int64 {
|
||||||
if capacity == 0 || requested > capacity {
|
if capacity == 0 || requested > capacity {
|
||||||
@ -37,11 +37,14 @@ func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.Fun
|
|||||||
|
|
||||||
return rawScoringFunction(requested * maxUtilization / capacity)
|
return rawScoringFunction(requested * maxUtilization / capacity)
|
||||||
}
|
}
|
||||||
return func(requested, allocable resourceToValueMap) int64 {
|
return func(requested, allocable []int64) int64 {
|
||||||
var nodeScore, weightSum int64
|
var nodeScore, weightSum int64
|
||||||
for resource := range requested {
|
for i := range requested {
|
||||||
weight := resourceToWeightMap[resource]
|
if allocable[i] == 0 {
|
||||||
resourceScore := resourceScoringFunction(requested[resource], allocable[resource])
|
continue
|
||||||
|
}
|
||||||
|
weight := resources[i].Weight
|
||||||
|
resourceScore := resourceScoringFunction(requested[i], allocable[i])
|
||||||
if resourceScore > 0 {
|
if resourceScore > 0 {
|
||||||
nodeScore += resourceScore * weight
|
nodeScore += resourceScore * weight
|
||||||
weightSum += weight
|
weightSum += weight
|
||||||
@ -54,7 +57,7 @@ func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.Fun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestedToCapacityRatioScorer(weightMap resourceToWeightMap, shape []config.UtilizationShapePoint) func(resourceToValueMap, resourceToValueMap) int64 {
|
func requestedToCapacityRatioScorer(resources []config.ResourceSpec, shape []config.UtilizationShapePoint) func([]int64, []int64) int64 {
|
||||||
shapes := make([]helper.FunctionShapePoint, 0, len(shape))
|
shapes := make([]helper.FunctionShapePoint, 0, len(shape))
|
||||||
for _, point := range shape {
|
for _, point := range shape {
|
||||||
shapes = append(shapes, helper.FunctionShapePoint{
|
shapes = append(shapes, helper.FunctionShapePoint{
|
||||||
@ -66,5 +69,5 @@ func requestedToCapacityRatioScorer(weightMap resourceToWeightMap, shape []confi
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildRequestedToCapacityRatioScorerFunction(shapes, weightMap)
|
return buildRequestedToCapacityRatioScorerFunction(shapes, resources)
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,6 @@ import (
|
|||||||
schedutil "k8s.io/kubernetes/pkg/scheduler/util"
|
schedutil "k8s.io/kubernetes/pkg/scheduler/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// resourceToWeightMap contains resource name and weight.
|
|
||||||
type resourceToWeightMap map[v1.ResourceName]int64
|
|
||||||
|
|
||||||
// scorer is decorator for resourceAllocationScorer
|
// scorer is decorator for resourceAllocationScorer
|
||||||
type scorer func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer
|
type scorer func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer
|
||||||
|
|
||||||
@ -35,14 +32,11 @@ type resourceAllocationScorer struct {
|
|||||||
Name string
|
Name string
|
||||||
// used to decide whether to use Requested or NonZeroRequested for
|
// used to decide whether to use Requested or NonZeroRequested for
|
||||||
// cpu and memory.
|
// cpu and memory.
|
||||||
useRequested bool
|
useRequested bool
|
||||||
scorer func(requested, allocable resourceToValueMap) int64
|
scorer func(requested, allocable []int64) int64
|
||||||
resourceToWeightMap resourceToWeightMap
|
resources []config.ResourceSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourceToValueMap is keyed with resource name and valued with quantity.
|
|
||||||
type resourceToValueMap map[v1.ResourceName]int64
|
|
||||||
|
|
||||||
// score will use `scorer` function to calculate the score.
|
// score will use `scorer` function to calculate the score.
|
||||||
func (r *resourceAllocationScorer) score(
|
func (r *resourceAllocationScorer) score(
|
||||||
pod *v1.Pod,
|
pod *v1.Pod,
|
||||||
@ -51,18 +45,21 @@ func (r *resourceAllocationScorer) score(
|
|||||||
if node == nil {
|
if node == nil {
|
||||||
return 0, framework.NewStatus(framework.Error, "node not found")
|
return 0, framework.NewStatus(framework.Error, "node not found")
|
||||||
}
|
}
|
||||||
if len(r.resourceToWeightMap) == 0 {
|
// resources not set, nothing scheduled,
|
||||||
|
if len(r.resources) == 0 {
|
||||||
return 0, framework.NewStatus(framework.Error, "resources not found")
|
return 0, framework.NewStatus(framework.Error, "resources not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
requested := make(resourceToValueMap)
|
requested := make([]int64, len(r.resources))
|
||||||
allocatable := make(resourceToValueMap)
|
allocatable := make([]int64, len(r.resources))
|
||||||
for resource := range r.resourceToWeightMap {
|
for i := range r.resources {
|
||||||
alloc, req := r.calculateResourceAllocatableRequest(nodeInfo, pod, resource)
|
alloc, req := r.calculateResourceAllocatableRequest(nodeInfo, pod, v1.ResourceName(r.resources[i].Name))
|
||||||
if alloc != 0 {
|
// Only fill the extended resource entry when it's non-zero.
|
||||||
// Only fill the extended resource entry when it's non-zero.
|
if alloc == 0 {
|
||||||
allocatable[resource], requested[resource] = alloc, req
|
continue
|
||||||
}
|
}
|
||||||
|
allocatable[i] = alloc
|
||||||
|
requested[i] = req
|
||||||
}
|
}
|
||||||
|
|
||||||
score := r.scorer(requested, allocatable)
|
score := r.scorer(requested, allocatable)
|
||||||
@ -137,12 +134,3 @@ func (r *resourceAllocationScorer) calculatePodResourceRequest(pod *v1.Pod, reso
|
|||||||
|
|
||||||
return podRequest
|
return podRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourcesToWeightMap make weightmap from resources spec
|
|
||||||
func resourcesToWeightMap(resources []config.ResourceSpec) resourceToWeightMap {
|
|
||||||
resourceToWeightMap := make(resourceToWeightMap)
|
|
||||||
for _, resource := range resources {
|
|
||||||
resourceToWeightMap[v1.ResourceName(resource.Name)] = resource.Weight
|
|
||||||
}
|
|
||||||
return resourceToWeightMap
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user