Skip to content

Commit

Permalink
scheduler: allow configuring default preemption for system scheduler
Browse files Browse the repository at this point in the history
Some operators want a greater control over when preemption is enabled,
especially during an upgrade to limit potential side-effects.
  • Loading branch information
Mahmood Ali committed Jan 13, 2020
1 parent ac0fef1 commit 744c9a4
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 9 deletions.
7 changes: 7 additions & 0 deletions command/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,13 @@ func convertServerConfig(agentConfig *Config) (*nomad.Config, error) {
return nil, fmt.Errorf("server_service_name must be set when auto_advertise is enabled")
}

// handle system scheduler preemption default
if agentConfig.Server.SystemSchedulerPreemptionEnabledDefault != nil {
conf.SystemSchedulerPreemptionEnabledDefault = *agentConfig.Server.SystemSchedulerPreemptionEnabledDefault
} else {
conf.SystemSchedulerPreemptionEnabledDefault = true
}

// Add the Consul and Vault configs
conf.ConsulConfig = agentConfig.Consul
conf.VaultConfig = agentConfig.Vault
Expand Down
29 changes: 29 additions & 0 deletions command/agent/agent_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package agent

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
Expand Down Expand Up @@ -274,6 +275,34 @@ func TestAgent_ServerConfig(t *testing.T) {
}
}

func TestAgent_ServerConfig_SchedulerFlags(t *testing.T) {
cases := []struct {
input *bool
expected bool
}{
{nil, true},
{helper.BoolToPtr(false), false},
{helper.BoolToPtr(true), true},
}

for _, c := range cases {
t.Run(fmt.Sprintf("case: %v", c.input), func(t *testing.T) {
conf := DefaultConfig()
conf.Server.SystemSchedulerPreemptionEnabledDefault = c.input

a := &Agent{config: conf}
conf.AdvertiseAddrs.Serf = "127.0.0.1:4000"
conf.AdvertiseAddrs.RPC = "127.0.0.1:4001"
conf.AdvertiseAddrs.HTTP = "10.10.11.1:4005"
conf.ACL.Enabled = true
require.NoError(t, conf.normalizeAddrs())

out, err := a.serverConfig()
require.NoError(t, err)
require.Equal(t, c.expected, out.SystemSchedulerPreemptionEnabledDefault)
})
}
}
func TestAgent_ClientConfig(t *testing.T) {
t.Parallel()
conf := DefaultConfig()
Expand Down
3 changes: 3 additions & 0 deletions command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ type ServerConfig struct {
// ServerJoin contains information that is used to attempt to join servers
ServerJoin *ServerJoin `hcl:"server_join"`

// SystemSchedulerPreemptionEnabledDefault is used to determin whether to enable system preemption by default in a new cluster
SystemSchedulerPreemptionEnabledDefault *bool `hcl:"system_scheduler_preemption_enabled_default"`

// ExtraKeysHCL is used by hcl to surface unexpected keys
ExtraKeysHCL []string `hcl:",unusedKeys" json:"-"`
}
Expand Down
8 changes: 6 additions & 2 deletions nomad/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ type Config struct {
// dead servers.
AutopilotInterval time.Duration

// SystemSchedulerPreemptionEnabledDefault is used to determin whether to enable system preemption by default in a new cluster
SystemSchedulerPreemptionEnabledDefault bool

// PluginLoader is used to load plugins.
PluginLoader loader.PluginCatalog

Expand Down Expand Up @@ -377,8 +380,9 @@ func DefaultConfig() *Config {
MaxTrailingLogs: 250,
ServerStabilizationTime: 10 * time.Second,
},
ServerHealthInterval: 2 * time.Second,
AutopilotInterval: 10 * time.Second,
ServerHealthInterval: 2 * time.Second,
AutopilotInterval: 10 * time.Second,
SystemSchedulerPreemptionEnabledDefault: true,
}

// Enable all known schedulers by default
Expand Down
16 changes: 9 additions & 7 deletions nomad/leader.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ var minAutopilotVersion = version.Must(version.NewVersion("0.8.0"))
var minSchedulerConfigVersion = version.Must(version.NewVersion("0.9.0"))

// Default configuration for scheduler with preemption enabled for system jobs
var defaultSchedulerConfig = &structs.SchedulerConfiguration{
PreemptionConfig: structs.PreemptionConfig{
SystemSchedulerEnabled: true,
BatchSchedulerEnabled: false,
ServiceSchedulerEnabled: false,
},
func (s *Server) defaultSchedulerConfig() structs.SchedulerConfiguration {
return structs.SchedulerConfiguration{
PreemptionConfig: structs.PreemptionConfig{
SystemSchedulerEnabled: s.config.SystemSchedulerPreemptionEnabledDefault,
BatchSchedulerEnabled: false,
ServiceSchedulerEnabled: false,
},
}
}

// monitorLeadership is used to monitor if we acquire or lose our role
Expand Down Expand Up @@ -1319,7 +1321,7 @@ func (s *Server) getOrCreateSchedulerConfig() *structs.SchedulerConfiguration {
return nil
}

req := structs.SchedulerSetConfigRequest{Config: *defaultSchedulerConfig}
req := structs.SchedulerSetConfigRequest{Config: s.defaultSchedulerConfig()}
if _, _, err = s.raftApply(structs.SchedulerConfigRequestType, req); err != nil {
s.logger.Named("core").Error("failed to initialize config", "error", err)
return nil
Expand Down

0 comments on commit 744c9a4

Please sign in to comment.