Skip to content

Commit add3a08

Browse files
author
Kubernetes Submit Queue
authored
Merge pull request kubernetes#39491 from jayunit100/sched_Histogram_error
Automatic merge from submit-queue (batch tested with PRs 34488, 39511, 39619, 38342, 39491) Update FitError as a message component into the PodConditionUpdater. Fixes kubernetes#20064 , after a roundabout volley of ideas, we ended up digging into existing Conditions for this, rather then a first class API object. This is just a quick sketch of the skeleton minimal implementation, it should pretty much "just work". I'll test it more later today. Release Note: ``` Histogram data of predicate failures is contained in pod conditions and thus available to users by kubectl commands. ```
2 parents ebf1a53 + 9cdc4ae commit add3a08

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

plugin/pkg/scheduler/generic_scheduler.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package scheduler
1818

1919
import (
20-
"bytes"
2120
"fmt"
2221
"sort"
2322
"strings"
@@ -45,10 +44,10 @@ type FitError struct {
4544

4645
var ErrNoNodesAvailable = fmt.Errorf("no nodes available to schedule pods")
4746

47+
const NoNodeAvailableMsg = "No nodes are available that match all of the following predicates:"
48+
4849
// Error returns detailed information of why the pod failed to fit on each node
4950
func (f *FitError) Error() string {
50-
var buf bytes.Buffer
51-
buf.WriteString(fmt.Sprintf("pod (%s) failed to fit in any node\n", f.Pod.Name))
5251
reasons := make(map[string]int)
5352
for _, predicates := range f.FailedPredicates {
5453
for _, pred := range predicates {
@@ -64,10 +63,8 @@ func (f *FitError) Error() string {
6463
sort.Strings(reasonStrings)
6564
return reasonStrings
6665
}
67-
68-
reasonMsg := fmt.Sprintf("fit failure summary on nodes : %v", strings.Join(sortReasonsHistogram(), ", "))
69-
buf.WriteString(reasonMsg)
70-
return buf.String()
66+
reasonMsg := fmt.Sprintf(NoNodeAvailableMsg+": %v.", strings.Join(sortReasonsHistogram(), ", "))
67+
return reasonMsg
7168
}
7269

7370
type genericScheduler struct {

plugin/pkg/scheduler/generic_scheduler_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"math"
2222
"reflect"
2323
"strconv"
24+
"strings"
2425
"testing"
2526
"time"
2627

@@ -397,6 +398,23 @@ func makeNode(node string, milliCPU, memory int64) *v1.Node {
397398
}
398399
}
399400

401+
func TestHumanReadableFitError(t *testing.T) {
402+
error := &FitError{
403+
Pod: &v1.Pod{ObjectMeta: v1.ObjectMeta{Name: "2"}},
404+
FailedPredicates: FailedPredicateMap{
405+
"1": []algorithm.PredicateFailureReason{algorithmpredicates.ErrNodeUnderMemoryPressure},
406+
"2": []algorithm.PredicateFailureReason{algorithmpredicates.ErrNodeUnderDiskPressure},
407+
"3": []algorithm.PredicateFailureReason{algorithmpredicates.ErrNodeUnderDiskPressure},
408+
},
409+
}
410+
if strings.Contains(error.Error(), "No nodes are available that match all of the following predicates") {
411+
if strings.Contains(error.Error(), "NodeUnderDiskPressure (2)") && strings.Contains(error.Error(), "NodeUnderMemoryPressure (1)") {
412+
return
413+
}
414+
}
415+
t.Errorf("Error message doesn't have all the information content: [" + error.Error() + "]")
416+
}
417+
400418
// The point of this test is to show that you:
401419
// - get the same priority for a zero-request pod as for a pod with the defaults requests,
402420
// both when the zero-request pod is already on the machine and when the zero-request pod

plugin/pkg/scheduler/scheduler.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,10 @@ func (s *Scheduler) scheduleOne() {
9898
s.config.Error(pod, err)
9999
s.config.Recorder.Eventf(pod, v1.EventTypeWarning, "FailedScheduling", "%v", err)
100100
s.config.PodConditionUpdater.Update(pod, &v1.PodCondition{
101-
Type: v1.PodScheduled,
102-
Status: v1.ConditionFalse,
103-
Reason: v1.PodReasonUnschedulable,
101+
Type: v1.PodScheduled,
102+
Status: v1.ConditionFalse,
103+
Reason: v1.PodReasonUnschedulable,
104+
Message: err.Error(),
104105
})
105106
return
106107
}

0 commit comments

Comments
 (0)