Merge pull request #28104 from ping035627/ping035627-patch-4

Automatic merge from submit-queue

SchedulerExtender: add failedPredicateMap in Filter() returns

Fix #25797. modify extender.Filter for adding extenders information to “failedPredicateMap” in findNodesThatFit.
When all the filtered nodes that passed "predicateFuncs" don’t pass the extenders filter, the failedPredicateMap hasn’t the extenders information, should add it, I think. So when the length of the “filteredNodes.Items” is 0, we can know the integral information. (The length of the “filteredNodes.Items” is 0, may be because the extenders filter failed.)
This commit is contained in:
Kubernetes Submit Queue 2016-08-06 20:50:33 -07:00 committed by GitHub
commit 711b63e78b
7 changed files with 40 additions and 16 deletions

View File

@ -26,8 +26,9 @@ import (
// managed by Kubernetes.
type SchedulerExtender interface {
// Filter based on extender-implemented predicate functions. The filtered list is
// expected to be a subset of the supplied list.
Filter(pod *api.Pod, nodes []*api.Node) (filteredNodes []*api.Node, err error)
// expected to be a subset of the supplied list. failedNodesMap optionally contains
// the list of failed nodes and failure reasons.
Filter(pod *api.Pod, nodes []*api.Node) (filteredNodes []*api.Node, failedNodesMap schedulerapi.FailedNodesMap, err error)
// Prioritize based on extender-implemented priority functions. The returned scores & weight
// are used to compute the weighted score for an extender. The weighted scores are added to

View File

@ -139,10 +139,15 @@ type ExtenderArgs struct {
Nodes api.NodeList `json:"nodes"`
}
// FailedNodesMap represents the filtered out nodes, with node names and failure messages
type FailedNodesMap map[string]string
// ExtenderFilterResult represents the results of a filter call to an extender
type ExtenderFilterResult struct {
// Filtered set of nodes where the pod can be scheduled
Nodes api.NodeList `json:"nodes,omitempty"`
// Filtered out nodes where the pod can't be scheduled and the failure messages
FailedNodes FailedNodesMap `json:"failedNodes,omitempty"`
// Error message indicating failure
Error string `json:"error,omitempty"`
}

View File

@ -139,10 +139,15 @@ type ExtenderArgs struct {
Nodes apiv1.NodeList `json:"nodes"`
}
// FailedNodesMap represents the filtered out nodes, with node names and failure messages
type FailedNodesMap map[string]string
// ExtenderFilterResult represents the results of a filter call to an extender
type ExtenderFilterResult struct {
// Filtered set of nodes where the pod can be scheduled
Nodes apiv1.NodeList `json:"nodes,omitempty"`
// Filtered out nodes where the pod can't be scheduled and the failure messages
FailedNodes FailedNodesMap `json:"failedNodes,omitempty"`
// Error message indicating failure
Error string `json:"error,omitempty"`
}

View File

@ -92,12 +92,13 @@ func NewHTTPExtender(config *schedulerapi.ExtenderConfig, apiVersion string) (al
}
// Filter based on extender implemented predicate functions. The filtered list is
// expected to be a subset of the supplied list.
func (h *HTTPExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, error) {
// expected to be a subset of the supplied list. failedNodesMap optionally contains
// the list of failed nodes and failure reasons.
func (h *HTTPExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, schedulerapi.FailedNodesMap, error) {
var result schedulerapi.ExtenderFilterResult
if h.filterVerb == "" {
return nodes, nil
return nodes, schedulerapi.FailedNodesMap{}, nil
}
nodeItems := make([]api.Node, 0, len(nodes))
@ -110,16 +111,17 @@ func (h *HTTPExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, err
}
if err := h.send(h.filterVerb, &args, &result); err != nil {
return nil, err
return nil, nil, err
}
if result.Error != "" {
return nil, fmt.Errorf(result.Error)
return nil, nil, fmt.Errorf(result.Error)
}
nodeResult := make([]*api.Node, 0, len(result.Nodes.Items))
for i := range result.Nodes.Items {
nodeResult = append(nodeResult, &result.Nodes.Items[i])
}
return nodeResult, nil
return nodeResult, result.FailedNodes, nil
}
// Prioritize based on extender implemented priority functions. Weight*priority is added

View File

@ -107,14 +107,15 @@ type FakeExtender struct {
weight int
}
func (f *FakeExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, error) {
func (f *FakeExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, schedulerapi.FailedNodesMap, error) {
filtered := []*api.Node{}
failedNodesMap := schedulerapi.FailedNodesMap{}
for _, node := range nodes {
fits := true
for _, predicate := range f.predicates {
fit, err := predicate(pod, node)
if err != nil {
return []*api.Node{}, err
return []*api.Node{}, schedulerapi.FailedNodesMap{}, err
}
if !fit {
fits = false
@ -123,9 +124,11 @@ func (f *FakeExtender) Filter(pod *api.Pod, nodes []*api.Node) ([]*api.Node, err
}
if fits {
filtered = append(filtered, node)
} else {
failedNodesMap[node.Name] = "FakeExtender failed"
}
}
return filtered, nil
return filtered, failedNodesMap, nil
}
func (f *FakeExtender) Prioritize(pod *api.Pod, nodes []*api.Node) (*schedulerapi.HostPriorityList, int, error) {

View File

@ -183,10 +183,14 @@ func findNodesThatFit(
if len(filtered) > 0 && len(extenders) != 0 {
for _, extender := range extenders {
filteredList, err := extender.Filter(pod, filtered)
filteredList, failedMap, err := extender.Filter(pod, filtered)
if err != nil {
return []*api.Node{}, FailedPredicateMap{}, err
}
for failedNodeName, failedMsg := range failedMap {
failedPredicateMap[failedNodeName] = failedMsg
}
filtered = filteredList
if len(filtered) == 0 {
break

View File

@ -79,11 +79,12 @@ func (e *Extender) serveHTTP(t *testing.T, w http.ResponseWriter, req *http.Requ
if strings.Contains(req.URL.Path, filter) {
resp := &schedulerapi.ExtenderFilterResult{}
nodes, err := e.Filter(&args.Pod, &args.Nodes)
nodes, failedNodes, err := e.Filter(&args.Pod, &args.Nodes)
if err != nil {
resp.Error = err.Error()
} else {
resp.Nodes = *nodes
resp.FailedNodes = failedNodes
}
if err := encoder.Encode(resp); err != nil {
@ -102,14 +103,15 @@ func (e *Extender) serveHTTP(t *testing.T, w http.ResponseWriter, req *http.Requ
}
}
func (e *Extender) Filter(pod *api.Pod, nodes *api.NodeList) (*api.NodeList, error) {
func (e *Extender) Filter(pod *api.Pod, nodes *api.NodeList) (*api.NodeList, schedulerapi.FailedNodesMap, error) {
filtered := []api.Node{}
failedNodesMap := schedulerapi.FailedNodesMap{}
for _, node := range nodes.Items {
fits := true
for _, predicate := range e.predicates {
fit, err := predicate(pod, &node)
if err != nil {
return &api.NodeList{}, err
return &api.NodeList{}, schedulerapi.FailedNodesMap{}, err
}
if !fit {
fits = false
@ -118,9 +120,11 @@ func (e *Extender) Filter(pod *api.Pod, nodes *api.NodeList) (*api.NodeList, err
}
if fits {
filtered = append(filtered, node)
} else {
failedNodesMap[node.Name] = fmt.Sprintf("extender failed: %s", e.name)
}
}
return &api.NodeList{Items: filtered}, nil
return &api.NodeList{Items: filtered}, failedNodesMap, nil
}
func (e *Extender) Prioritize(pod *api.Pod, nodes *api.NodeList) (*schedulerapi.HostPriorityList, error) {