Modified the Filter interface to pass in nodeinfo instead of node name.

This is necessary to support preemption, which relies on passing modified nodeinfo objects to the filters to simulate evicting lower-priority pods.
This commit is contained in:
Abdullah Gharaibeh 2019-09-18 15:48:26 -04:00
parent b8d8f1a35e
commit 89f936f6ac
8 changed files with 29 additions and 13 deletions

View File

@ -675,7 +675,7 @@ func (g *genericScheduler) podFitsOnNode(
}
}
status = g.framework.RunFilterPlugins(pluginContext, pod, info.Node().Name)
status = g.framework.RunFilterPlugins(pluginContext, pod, nodeInfoToUse)
if !status.IsSuccess() && !status.IsUnschedulable() {
return false, failedPredicates, status, status.AsError()
}

View File

@ -160,10 +160,10 @@ func (fp *FakeFilterPlugin) reset() {
// Filter is a test function that returns an error or nil, depending on the
// value of "failedNodeReturnCodeMap".
func (fp *FakeFilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
func (fp *FakeFilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *framework.Status {
atomic.AddInt32(&fp.numFilterCalled, 1)
if returnCode, ok := fp.failedNodeReturnCodeMap[nodeName]; ok {
if returnCode, ok := fp.failedNodeReturnCodeMap[nodeInfo.Node().Name]; ok {
return framework.NewStatus(returnCode, fmt.Sprintf("injecting failure for pod %v", pod.Name))
}

View File

@ -7,6 +7,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//pkg/scheduler/framework/v1alpha1:go_default_library",
"//pkg/scheduler/nodeinfo:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
],

View File

@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
"k8s.io/kubernetes/pkg/scheduler/nodeinfo"
)
// Filter is a plugin that implements the filter plugin and always returns Success.
@ -40,7 +41,7 @@ func (n Filter) Name() string {
}
// Filter invoked at the filter extension point.
func (n Filter) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
func (n Filter) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeInfo *nodeinfo.NodeInfo) *framework.Status {
return nil
}

View File

@ -311,9 +311,9 @@ func (f *framework) RunPreFilterPlugins(
// given node is not suitable for running pod.
// Meanwhile, the failure message and status are set for the given node.
func (f *framework) RunFilterPlugins(pc *PluginContext,
pod *v1.Pod, nodeName string) *Status {
pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status {
for _, pl := range f.filterPlugins {
status := pl.Filter(pc, pod, nodeName)
status := pl.Filter(pc, pod, nodeInfo)
if !status.IsSuccess() {
if !status.IsUnschedulable() {
errMsg := fmt.Sprintf("error while running %q filter plugin for pod %q: %v",

View File

@ -188,7 +188,14 @@ type FilterPlugin interface {
// the given node fits the pod. If Filter doesn't return "Success",
// please refer scheduler/algorithm/predicates/error.go
// to set error message.
Filter(pc *PluginContext, pod *v1.Pod, nodeName string) *Status
// For the node being evaluated, Filter plugins should look at the passed
// nodeInfo reference for this particular node's information (e.g., pods
// considered to be running on the node) instead of looking it up in the
// NodeInfoSnapshot because we don't guarantee that they will be the same.
// For example, during preemption, we may pass a copy of the original
// nodeInfo object that has some pods removed from it to evaluate the
// possibility of preempting them to schedule the target pod.
Filter(pc *PluginContext, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
}
// PostFilterPlugin is an interface for Post-filter plugin. Post-filter is an
@ -308,10 +315,16 @@ type Framework interface {
// cycle is aborted.
RunPreFilterPlugins(pc *PluginContext, pod *v1.Pod) *Status
// RunFilterPlugins runs the set of configured filter plugins for pod on the
// given host. If any of these plugins returns any status other than "Success",
// the given node is not suitable for running the pod.
RunFilterPlugins(pc *PluginContext, pod *v1.Pod, nodeName string) *Status
// RunFilterPlugins runs the set of configured filter plugins for pod on
// the given node. It returns directly if any of the filter plugins
// return any status other than "Success". Note that for the node being
// evaluated, the passed nodeInfo reference could be different from the
// one in NodeInfoSnapshot map (e.g., pods considered to be running on
// the node could be different). For example, during preemption, we may
// pass a copy of the original nodeInfo object that has some pods
// removed from it to evaluate the possibility of preempting them to
// schedule the target pod.
RunFilterPlugins(pc *PluginContext, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *Status
// RunPostFilterPlugins runs the set of configured post-filter plugins. If any
// of these plugins returns any status other than "Success", the given node is

View File

@ -171,7 +171,7 @@ func (*fakeFramework) RunPreFilterPlugins(pc *framework.PluginContext, pod *v1.P
return nil
}
func (*fakeFramework) RunFilterPlugins(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
func (*fakeFramework) RunFilterPlugins(pc *framework.PluginContext, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *framework.Status {
return nil
}

View File

@ -29,6 +29,7 @@ import (
clientset "k8s.io/client-go/kubernetes"
schedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
)
type PreFilterPlugin struct {
@ -197,7 +198,7 @@ func (fp *FilterPlugin) reset() {
// Filter is a test function that returns an error or nil, depending on the
// value of "failFilter".
func (fp *FilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
func (fp *FilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *framework.Status {
fp.numFilterCalled++
if fp.failFilter {