mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	Add NormalizeScore extension point for scheduler framework.
This commit is contained in:
		| @@ -38,9 +38,14 @@ type PrefilterPlugin struct { | ||||
| } | ||||
|  | ||||
| type ScorePlugin struct { | ||||
| 	failScore     bool | ||||
| 	numCalled     int | ||||
| 	highScoreNode string | ||||
| 	failScore      bool | ||||
| 	numScoreCalled int | ||||
| 	highScoreNode  string | ||||
| } | ||||
|  | ||||
| type ScoreWithNormalizePlugin struct { | ||||
| 	numScoreCalled          int | ||||
| 	numNormalizeScoreCalled int | ||||
| } | ||||
|  | ||||
| type FilterPlugin struct { | ||||
| @@ -91,19 +96,22 @@ type PermitPlugin struct { | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	prefilterPluginName = "prefilter-plugin" | ||||
| 	scorePluginName     = "score-plugin" | ||||
| 	filterPluginName    = "filter-plugin" | ||||
| 	reservePluginName   = "reserve-plugin" | ||||
| 	prebindPluginName   = "prebind-plugin" | ||||
| 	unreservePluginName = "unreserve-plugin" | ||||
| 	postbindPluginName  = "postbind-plugin" | ||||
| 	permitPluginName    = "permit-plugin" | ||||
| 	prefilterPluginName          = "prefilter-plugin" | ||||
| 	scorePluginName              = "score-plugin" | ||||
| 	scoreWithNormalizePluginName = "score-with-normalize-plugin" | ||||
| 	filterPluginName             = "filter-plugin" | ||||
| 	reservePluginName            = "reserve-plugin" | ||||
| 	prebindPluginName            = "prebind-plugin" | ||||
| 	unreservePluginName          = "unreserve-plugin" | ||||
| 	postbindPluginName           = "postbind-plugin" | ||||
| 	permitPluginName             = "permit-plugin" | ||||
| ) | ||||
|  | ||||
| var _ = framework.PrefilterPlugin(&PrefilterPlugin{}) | ||||
| var _ = framework.ScorePlugin(&ScorePlugin{}) | ||||
| var _ = framework.FilterPlugin(&FilterPlugin{}) | ||||
| var _ = framework.ScorePlugin(&ScorePlugin{}) | ||||
| var _ = framework.ScoreWithNormalizePlugin(&ScoreWithNormalizePlugin{}) | ||||
| var _ = framework.ReservePlugin(&ReservePlugin{}) | ||||
| var _ = framework.PrebindPlugin(&PrebindPlugin{}) | ||||
| var _ = framework.BindPlugin(&BindPlugin{}) | ||||
| @@ -111,6 +119,13 @@ var _ = framework.PostbindPlugin(&PostbindPlugin{}) | ||||
| var _ = framework.UnreservePlugin(&UnreservePlugin{}) | ||||
| var _ = framework.PermitPlugin(&PermitPlugin{}) | ||||
|  | ||||
| var scPlugin = &ScorePlugin{} | ||||
|  | ||||
| // NewScorePlugin is the factory for score plugin. | ||||
| func NewScorePlugin(_ *runtime.Unknown, _ framework.FrameworkHandle) (framework.Plugin, error) { | ||||
| 	return scPlugin, nil | ||||
| } | ||||
|  | ||||
| // Name returns name of the score plugin. | ||||
| func (sp *ScorePlugin) Name() string { | ||||
| 	return scorePluginName | ||||
| @@ -119,21 +134,19 @@ func (sp *ScorePlugin) Name() string { | ||||
| // reset returns name of the score plugin. | ||||
| func (sp *ScorePlugin) reset() { | ||||
| 	sp.failScore = false | ||||
| 	sp.numCalled = 0 | ||||
| 	sp.numScoreCalled = 0 | ||||
| 	sp.highScoreNode = "" | ||||
| } | ||||
|  | ||||
| var scPlugin = &ScorePlugin{} | ||||
|  | ||||
| // Score returns the score of scheduling a pod on a specific node. | ||||
| func (sp *ScorePlugin) Score(pc *framework.PluginContext, p *v1.Pod, nodeName string) (int, *framework.Status) { | ||||
| 	sp.numCalled++ | ||||
| 	sp.numScoreCalled++ | ||||
| 	if sp.failScore { | ||||
| 		return 0, framework.NewStatus(framework.Error, fmt.Sprintf("injecting failure for pod %v", p.Name)) | ||||
| 	} | ||||
|  | ||||
| 	score := 10 | ||||
| 	if sp.numCalled == 1 { | ||||
| 	if sp.numScoreCalled == 1 { | ||||
| 		// The first node is scored the highest, the rest is scored lower. | ||||
| 		sp.highScoreNode = nodeName | ||||
| 		score = 100 | ||||
| @@ -141,9 +154,34 @@ func (sp *ScorePlugin) Score(pc *framework.PluginContext, p *v1.Pod, nodeName st | ||||
| 	return score, nil | ||||
| } | ||||
|  | ||||
| // NewScorePlugin is the factory for score plugin. | ||||
| func NewScorePlugin(_ *runtime.Unknown, _ framework.FrameworkHandle) (framework.Plugin, error) { | ||||
| 	return scPlugin, nil | ||||
| var scoreWithNormalizePlguin = &ScoreWithNormalizePlugin{} | ||||
|  | ||||
| // Name returns name of the score plugin. | ||||
| func (sp *ScoreWithNormalizePlugin) Name() string { | ||||
| 	return scoreWithNormalizePluginName | ||||
| } | ||||
|  | ||||
| // reset returns name of the score plugin. | ||||
| func (sp *ScoreWithNormalizePlugin) reset() { | ||||
| 	sp.numScoreCalled = 0 | ||||
| 	sp.numNormalizeScoreCalled = 0 | ||||
| } | ||||
|  | ||||
| // Score returns the score of scheduling a pod on a specific node. | ||||
| func (sp *ScoreWithNormalizePlugin) Score(pc *framework.PluginContext, p *v1.Pod, nodeName string) (int, *framework.Status) { | ||||
| 	sp.numScoreCalled++ | ||||
| 	score := 10 | ||||
| 	return score, nil | ||||
| } | ||||
|  | ||||
| func (sp *ScoreWithNormalizePlugin) NormalizeScore(pc *framework.PluginContext, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status { | ||||
| 	sp.numNormalizeScoreCalled++ | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // NewScoreWithNormalizePlugin is the factory for score with normalize plugin. | ||||
| func NewScoreWithNormalizePlugin(_ *runtime.Unknown, _ framework.FrameworkHandle) (framework.Plugin, error) { | ||||
| 	return scoreWithNormalizePlguin, nil | ||||
| } | ||||
|  | ||||
| var filterPlugin = &FilterPlugin{} | ||||
| @@ -490,9 +528,6 @@ func TestPrefilterPlugin(t *testing.T) { | ||||
|  | ||||
| // TestScorePlugin tests invocation of score plugins. | ||||
| func TestScorePlugin(t *testing.T) { | ||||
| 	// Create a plugin registry for testing. Register only a score plugin. | ||||
| 	registry := framework.Registry{scorePluginName: NewScorePlugin} | ||||
|  | ||||
| 	// Setup initial score plugin for testing. | ||||
| 	plugins := &schedulerconfig.Plugins{ | ||||
| 		Score: &schedulerconfig.PluginSet{ | ||||
| @@ -503,22 +538,9 @@ func TestScorePlugin(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	// Set empty plugin config for testing | ||||
| 	emptyPluginConfig := []schedulerconfig.PluginConfig{} | ||||
|  | ||||
| 	// Create the master and the scheduler with the test plugin set. | ||||
| 	context := initTestSchedulerWithOptions(t, | ||||
| 		initTestMaster(t, "score-plugin", nil), | ||||
| 		false, nil, registry, plugins, emptyPluginConfig, false, time.Second) | ||||
| 	context, cs := initTestContextForScorePlugin(t, plugins) | ||||
| 	defer cleanupTest(t, context) | ||||
|  | ||||
| 	cs := context.clientSet | ||||
| 	// Add multiple nodes, one of them will be scored much higher than the others. | ||||
| 	_, err := createNodes(cs, "test-node", nil, 10) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Cannot create nodes: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	for i, fail := range []bool{false, true} { | ||||
| 		scPlugin.failScore = fail | ||||
| 		// Create a best effort pod. | ||||
| @@ -545,8 +567,8 @@ func TestScorePlugin(t *testing.T) { | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if scPlugin.numCalled == 0 { | ||||
| 			t.Errorf("Expected the reserve plugin to be called.") | ||||
| 		if scPlugin.numScoreCalled == 0 { | ||||
| 			t.Errorf("Expected the score plugin to be called.") | ||||
| 		} | ||||
|  | ||||
| 		scPlugin.reset() | ||||
| @@ -554,6 +576,42 @@ func TestScorePlugin(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestNormalizeScorePlugin tests invocation of normalize score plugins. | ||||
| func TestNormalizeScorePlugin(t *testing.T) { | ||||
| 	// Setup initial score plugin for testing. | ||||
| 	plugins := &schedulerconfig.Plugins{ | ||||
| 		Score: &schedulerconfig.PluginSet{ | ||||
| 			Enabled: []schedulerconfig.Plugin{ | ||||
| 				{ | ||||
| 					Name: scoreWithNormalizePluginName, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	context, cs := initTestContextForScorePlugin(t, plugins) | ||||
| 	defer cleanupTest(t, context) | ||||
|  | ||||
| 	// Create a best effort pod. | ||||
| 	pod, err := createPausePod(cs, | ||||
| 		initPausePod(cs, &pausePodConfig{Name: "test-pod", Namespace: context.ns.Name})) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Error while creating a test pod: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if err = waitForPodToSchedule(cs, pod); err != nil { | ||||
| 		t.Errorf("Expected the pod to be scheduled. error: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if scoreWithNormalizePlguin.numScoreCalled == 0 { | ||||
| 		t.Errorf("Expected the score plugin to be called.") | ||||
| 	} | ||||
| 	if scoreWithNormalizePlguin.numNormalizeScoreCalled == 0 { | ||||
| 		t.Error("Expected the normalize score plugin to be called") | ||||
| 	} | ||||
|  | ||||
| 	scoreWithNormalizePlguin.reset() | ||||
| } | ||||
|  | ||||
| // TestReservePlugin tests invocation of reserve plugins. | ||||
| func TestReservePlugin(t *testing.T) { | ||||
| 	// Create a plugin registry for testing. Register only a reserve plugin. | ||||
| @@ -1477,3 +1535,26 @@ func TestPreemptWithPermitPlugin(t *testing.T) { | ||||
| 	perPlugin.reset() | ||||
| 	cleanupPods(cs, t, []*v1.Pod{waitingPod, preemptorPod}) | ||||
| } | ||||
|  | ||||
| func initTestContextForScorePlugin(t *testing.T, plugins *schedulerconfig.Plugins) (*testContext, *clientset.Clientset) { | ||||
| 	// Create a plugin registry for testing. Register only a score plugin. | ||||
| 	registry := framework.Registry{ | ||||
| 		scorePluginName:              NewScorePlugin, | ||||
| 		scoreWithNormalizePluginName: NewScoreWithNormalizePlugin, | ||||
| 	} | ||||
|  | ||||
| 	// Set empty plugin config for testing | ||||
| 	emptyPluginConfig := []schedulerconfig.PluginConfig{} | ||||
|  | ||||
| 	// Create the master and the scheduler with the test plugin set. | ||||
| 	context := initTestSchedulerWithOptions(t, | ||||
| 		initTestMaster(t, "score-plugin", nil), | ||||
| 		false, nil, registry, plugins, emptyPluginConfig, false, time.Second) | ||||
|  | ||||
| 	cs := context.clientSet | ||||
| 	_, err := createNodes(cs, "test-node", nil, 10) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Cannot create nodes: %v", err) | ||||
| 	} | ||||
| 	return context, cs | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user