Skip to content

Commit a894aec

Browse files
committed
Add --oom-score-adjust to daemon
This adds an `--oom-score-adjust` flag to the daemon so that the value provided can be set for the docker daemon's process. The default value for the flag is -500. This will allow the docker daemon to have a less chance of being killed before containers do. The default value for processes is 0 with a min/max of -1000/1000. -500 is a good middle ground because it is less than the default for most processes and still not -1000 which basically means never kill this process in an OOM condition on the host machine. The only processes on my machine that have a score less than -500 are dbus at -900 and sshd and xfce( my window manager ) at -1000. I don't think docker should be set lower, by default, than dbus or sshd so that is why I chose -500. Signed-off-by: Michael Crosby <[email protected]>
1 parent a44f010 commit a894aec

File tree

8 files changed

+65
-3
lines changed

8 files changed

+65
-3
lines changed

Diff for: cmd/dockerd/daemon_unix.go

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func (cli *DaemonCli) setupConfigReloadTrap() {
6161
func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
6262
opts := []libcontainerd.RemoteOption{
6363
libcontainerd.WithDebugLog(cli.Config.Debug),
64+
libcontainerd.WithOOMScore(cli.Config.OOMScoreAdjust),
6465
}
6566
if cli.Config.ContainerdAddr != "" {
6667
opts = append(opts, libcontainerd.WithRemoteAddr(cli.Config.ContainerdAddr))

Diff for: daemon/config_unix.go

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Config struct {
3434
Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"`
3535
Runtimes map[string]types.Runtime `json:"runtimes,omitempty"`
3636
DefaultRuntime string `json:"default-runtime,omitempty"`
37+
OOMScoreAdjust int `json:"oom-score-adjust,omitempty"`
3738
}
3839

3940
// bridgeConfig stores all the bridge driver specific
@@ -90,6 +91,7 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin
9091
config.Runtimes = make(map[string]types.Runtime)
9192
cmd.Var(runconfigopts.NewNamedRuntimeOpt("runtimes", &config.Runtimes, stockRuntimeName), []string{"-add-runtime"}, usageFn("Register an additional OCI compatible runtime"))
9293
cmd.StringVar(&config.DefaultRuntime, []string{"-default-runtime"}, stockRuntimeName, usageFn("Default OCI runtime to be used"))
94+
cmd.IntVar(&config.OOMScoreAdjust, []string{"-oom-score-adjust"}, -500, usageFn("Set the oom_score_adj for the daemon"))
9395

9496
config.attachExperimentalFlags(cmd, usageFn)
9597
}

Diff for: daemon/daemon.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,11 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot
434434
}
435435
}
436436

437-
if err = setupDaemonRoot(config, realRoot, rootUID, rootGID); err != nil {
437+
if err := setupDaemonRoot(config, realRoot, rootUID, rootGID); err != nil {
438+
return nil, err
439+
}
440+
441+
if err := setupDaemonProcess(config); err != nil {
438442
return nil, err
439443
}
440444

Diff for: daemon/daemon_solaris.go

+4
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,7 @@ func (daemon *Daemon) setDefaultIsolation() error {
161161
func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
162162
return types.RootFS{}
163163
}
164+
165+
func setupDaemonProcess(config *Config) error {
166+
return nil
167+
}

Diff for: daemon/daemon_unix.go

+16
Original file line numberDiff line numberDiff line change
@@ -1139,3 +1139,19 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
11391139
Layers: layers,
11401140
}
11411141
}
1142+
1143+
// setupDaemonProcess sets various settings for the daemon's process
1144+
func setupDaemonProcess(config *Config) error {
1145+
// setup the daemons oom_score_adj
1146+
return setupOOMScoreAdj(config.OOMScoreAdjust)
1147+
}
1148+
1149+
func setupOOMScoreAdj(score int) error {
1150+
f, err := os.OpenFile("/proc/self/oom_score_adj", os.O_WRONLY, 0)
1151+
if err != nil {
1152+
return err
1153+
}
1154+
_, err = f.WriteString(strconv.Itoa(score))
1155+
f.Close()
1156+
return err
1157+
}

Diff for: daemon/daemon_windows.go

+4
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,7 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
431431
BaseLayer: rootfs.BaseLayer,
432432
}
433433
}
434+
435+
func setupDaemonProcess(config *Config) error {
436+
return nil
437+
}

Diff for: docs/reference/commandline/dockerd.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ weight = -1
5454
--label=[] Set key=value labels to the daemon
5555
--log-driver="json-file" Default driver for container logs
5656
--log-opt=[] Log driver specific options
57-
--mtu=0 Set the containers network MTU
5857
--max-concurrent-downloads=3 Set the max concurrent downloads for each pull
5958
--max-concurrent-uploads=5 Set the max concurrent uploads for each push
59+
--mtu=0 Set the containers network MTU
60+
--oom-score-adjust=-500 Set the oom_score_adj for the daemon
6061
--disable-legacy-registry Do not contact legacy registries
6162
-p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file
6263
--raw-logs Full timestamps without ANSI coloring
@@ -1057,6 +1058,7 @@ This is a full example of the allowed configuration options on Linux:
10571058
"insecure-registries": [],
10581059
"disable-legacy-registry": false,
10591060
"default-runtime": "runc",
1061+
"oom-score-adjust": -500,
10601062
"runtimes": {
10611063
"runc": {
10621064
"path": "runc"

Diff for: libcontainerd/remote_linux.go

+30-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type remote struct {
5454
runtimeArgs []string
5555
daemonWaitCh chan struct{}
5656
liveRestore bool
57+
oomScore int
5758
}
5859

5960
// New creates a fresh instance of libcontainerd remote.
@@ -402,7 +403,10 @@ func (r *remote) runContainerdDaemon() error {
402403
return err
403404
}
404405
logrus.Infof("New containerd process, pid: %d", cmd.Process.Pid)
405-
406+
if err := setOOMScore(cmd.Process.Pid, r.oomScore); err != nil {
407+
utils.KillProcess(cmd.Process.Pid)
408+
return err
409+
}
406410
if _, err := f.WriteString(fmt.Sprintf("%d", cmd.Process.Pid)); err != nil {
407411
utils.KillProcess(cmd.Process.Pid)
408412
return err
@@ -417,6 +421,16 @@ func (r *remote) runContainerdDaemon() error {
417421
return nil
418422
}
419423

424+
func setOOMScore(pid, score int) error {
425+
f, err := os.OpenFile(fmt.Sprintf("/proc/%d/oom_score_adj", pid), os.O_WRONLY, 0)
426+
if err != nil {
427+
return err
428+
}
429+
_, err = f.WriteString(strconv.Itoa(score))
430+
f.Close()
431+
return err
432+
}
433+
420434
// WithRemoteAddr sets the external containerd socket to connect to.
421435
func WithRemoteAddr(addr string) RemoteOption {
422436
return rpcAddr(addr)
@@ -510,3 +524,18 @@ func (l liveRestore) Apply(r Remote) error {
510524
}
511525
return fmt.Errorf("WithLiveRestore option not supported for this remote")
512526
}
527+
528+
// WithOOMScore defines the oom_score_adj to set for the containerd process.
529+
func WithOOMScore(score int) RemoteOption {
530+
return oomScore(score)
531+
}
532+
533+
type oomScore int
534+
535+
func (o oomScore) Apply(r Remote) error {
536+
if remote, ok := r.(*remote); ok {
537+
remote.oomScore = int(o)
538+
return nil
539+
}
540+
return fmt.Errorf("WithOOMScore option not supported for this remote")
541+
}

0 commit comments

Comments
 (0)