From 55634591785c132c416bfe70fc885772ad13ae59 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Tue, 10 Jun 2014 10:00:17 -0700 Subject: [PATCH] Fix the first fit scheduler to randomize. --- cmd/apiserver/apiserver.go | 4 +++- pkg/registry/scheduler.go | 13 ++++++++++--- pkg/registry/scheduler_test.go | 16 ++++++++++------ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/cmd/apiserver/apiserver.go b/cmd/apiserver/apiserver.go index a53981ecbd..40ae6cf2df 100644 --- a/cmd/apiserver/apiserver.go +++ b/cmd/apiserver/apiserver.go @@ -21,6 +21,7 @@ import ( "flag" "fmt" "log" + "math/rand" "net/http" "time" @@ -74,8 +75,9 @@ func main() { Port: 10250, } + random := rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) storage := map[string]apiserver.RESTStorage{ - "pods": registry.MakePodRegistryStorage(podRegistry, containerInfo, registry.MakeFirstFitScheduler(machineList, podRegistry)), + "pods": registry.MakePodRegistryStorage(podRegistry, containerInfo, registry.MakeFirstFitScheduler(machineList, podRegistry, random)), "replicationControllers": registry.MakeControllerRegistryStorage(controllerRegistry), "services": registry.MakeServiceRegistryStorage(serviceRegistry), } diff --git a/pkg/registry/scheduler.go b/pkg/registry/scheduler.go index 3ae4cfc86d..377e5d06a0 100644 --- a/pkg/registry/scheduler.go +++ b/pkg/registry/scheduler.go @@ -66,12 +66,14 @@ func (s *RoundRobinScheduler) Schedule(pod Pod) (string, error) { type FirstFitScheduler struct { machines []string registry PodRegistry + random *rand.Rand } -func MakeFirstFitScheduler(machines []string, registry PodRegistry) Scheduler { +func MakeFirstFitScheduler(machines []string, registry PodRegistry, random *rand.Rand) Scheduler { return &FirstFitScheduler{ machines: machines, registry: registry, + random: random, } } @@ -96,6 +98,7 @@ func (s *FirstFitScheduler) Schedule(pod Pod) (string, error) { host := scheduledPod.CurrentState.Host machineToPods[host] = append(machineToPods[host], scheduledPod) } + var machineOptions []string for _, machine := range s.machines { podFits := true for _, scheduledPod := range machineToPods[machine] { @@ -108,8 +111,12 @@ func (s *FirstFitScheduler) Schedule(pod Pod) (string, error) { } } if podFits { - return machine, nil + machineOptions = append(machineOptions, machine) } } - return "", fmt.Errorf("Failed to find fit for %#v", pod) + if len(machineOptions) == 0 { + return "", fmt.Errorf("Failed to find fit for %#v", pod) + } else { + return machineOptions[s.random.Int()%len(machineOptions)], nil + } } diff --git a/pkg/registry/scheduler_test.go b/pkg/registry/scheduler_test.go index 9c30da9909..f94d8b1adf 100644 --- a/pkg/registry/scheduler_test.go +++ b/pkg/registry/scheduler_test.go @@ -47,8 +47,9 @@ func TestRandomScheduler(t *testing.T) { func TestFirstFitSchedulerNothingScheduled(t *testing.T) { mockRegistry := MockPodRegistry{} - scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry) - expectSchedule(scheduler, Pod{}, "m1", t) + r := rand.New(rand.NewSource(0)) + scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r) + expectSchedule(scheduler, Pod{}, "m3", t) } func makePod(host string, hostPorts ...int) Pod { @@ -78,8 +79,9 @@ func TestFirstFitSchedulerFirstScheduled(t *testing.T) { makePod("m1", 8080), }, } - scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry) - expectSchedule(scheduler, makePod("", 8080), "m2", t) + r := rand.New(rand.NewSource(0)) + scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r) + expectSchedule(scheduler, makePod("", 8080), "m3", t) } func TestFirstFitSchedulerFirstScheduledComplicated(t *testing.T) { @@ -90,7 +92,8 @@ func TestFirstFitSchedulerFirstScheduledComplicated(t *testing.T) { makePod("m3", 80, 443, 8085), }, } - scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry) + r := rand.New(rand.NewSource(0)) + scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r) expectSchedule(scheduler, makePod("", 8080, 8081), "m3", t) } @@ -102,7 +105,8 @@ func TestFirstFitSchedulerFirstScheduledImpossible(t *testing.T) { makePod("m3", 8080), }, } - scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry) + r := rand.New(rand.NewSource(0)) + scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r) _, err := scheduler.Schedule(makePod("", 8080, 8081)) if err == nil { t.Error("Unexpected non-error.")