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 <crosbymichael@gmail.com>
| ... | ... |
@@ -61,6 +61,7 @@ func (cli *DaemonCli) setupConfigReloadTrap() {
|
| 61 | 61 |
func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
|
| 62 | 62 |
opts := []libcontainerd.RemoteOption{
|
| 63 | 63 |
libcontainerd.WithDebugLog(cli.Config.Debug), |
| 64 |
+ libcontainerd.WithOOMScore(cli.Config.OOMScoreAdjust), |
|
| 64 | 65 |
} |
| 65 | 66 |
if cli.Config.ContainerdAddr != "" {
|
| 66 | 67 |
opts = append(opts, libcontainerd.WithRemoteAddr(cli.Config.ContainerdAddr)) |
| ... | ... |
@@ -34,6 +34,7 @@ type Config struct {
|
| 34 | 34 |
Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"` |
| 35 | 35 |
Runtimes map[string]types.Runtime `json:"runtimes,omitempty"` |
| 36 | 36 |
DefaultRuntime string `json:"default-runtime,omitempty"` |
| 37 |
+ OOMScoreAdjust int `json:"oom-score-adjust,omitempty"` |
|
| 37 | 38 |
} |
| 38 | 39 |
|
| 39 | 40 |
// bridgeConfig stores all the bridge driver specific |
| ... | ... |
@@ -90,6 +91,7 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin |
| 90 | 90 |
config.Runtimes = make(map[string]types.Runtime) |
| 91 | 91 |
cmd.Var(runconfigopts.NewNamedRuntimeOpt("runtimes", &config.Runtimes, stockRuntimeName), []string{"-add-runtime"}, usageFn("Register an additional OCI compatible runtime"))
|
| 92 | 92 |
cmd.StringVar(&config.DefaultRuntime, []string{"-default-runtime"}, stockRuntimeName, usageFn("Default OCI runtime to be used"))
|
| 93 |
+ cmd.IntVar(&config.OOMScoreAdjust, []string{"-oom-score-adjust"}, -500, usageFn("Set the oom_score_adj for the daemon"))
|
|
| 93 | 94 |
|
| 94 | 95 |
config.attachExperimentalFlags(cmd, usageFn) |
| 95 | 96 |
} |
| ... | ... |
@@ -434,7 +434,11 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot |
| 434 | 434 |
} |
| 435 | 435 |
} |
| 436 | 436 |
|
| 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 {
|
|
| 438 | 442 |
return nil, err |
| 439 | 443 |
} |
| 440 | 444 |
|
| ... | ... |
@@ -1139,3 +1139,19 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
|
| 1139 | 1139 |
Layers: layers, |
| 1140 | 1140 |
} |
| 1141 | 1141 |
} |
| 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 |
+} |
| ... | ... |
@@ -54,9 +54,10 @@ weight = -1 |
| 54 | 54 |
--label=[] Set key=value labels to the daemon |
| 55 | 55 |
--log-driver="json-file" Default driver for container logs |
| 56 | 56 |
--log-opt=[] Log driver specific options |
| 57 |
- --mtu=0 Set the containers network MTU |
|
| 58 | 57 |
--max-concurrent-downloads=3 Set the max concurrent downloads for each pull |
| 59 | 58 |
--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 |
|
| 60 | 61 |
--disable-legacy-registry Do not contact legacy registries |
| 61 | 62 |
-p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file |
| 62 | 63 |
--raw-logs Full timestamps without ANSI coloring |
| ... | ... |
@@ -1057,6 +1058,7 @@ This is a full example of the allowed configuration options on Linux: |
| 1057 | 1057 |
"insecure-registries": [], |
| 1058 | 1058 |
"disable-legacy-registry": false, |
| 1059 | 1059 |
"default-runtime": "runc", |
| 1060 |
+ "oom-score-adjust": -500, |
|
| 1060 | 1061 |
"runtimes": {
|
| 1061 | 1062 |
"runc": {
|
| 1062 | 1063 |
"path": "runc" |
| ... | ... |
@@ -54,6 +54,7 @@ type remote struct {
|
| 54 | 54 |
runtimeArgs []string |
| 55 | 55 |
daemonWaitCh chan struct{}
|
| 56 | 56 |
liveRestore bool |
| 57 |
+ oomScore int |
|
| 57 | 58 |
} |
| 58 | 59 |
|
| 59 | 60 |
// New creates a fresh instance of libcontainerd remote. |
| ... | ... |
@@ -402,7 +403,10 @@ func (r *remote) runContainerdDaemon() error {
|
| 402 | 402 |
return err |
| 403 | 403 |
} |
| 404 | 404 |
logrus.Infof("New containerd process, pid: %d", cmd.Process.Pid)
|
| 405 |
- |
|
| 405 |
+ if err := setOOMScore(cmd.Process.Pid, r.oomScore); err != nil {
|
|
| 406 |
+ utils.KillProcess(cmd.Process.Pid) |
|
| 407 |
+ return err |
|
| 408 |
+ } |
|
| 406 | 409 |
if _, err := f.WriteString(fmt.Sprintf("%d", cmd.Process.Pid)); err != nil {
|
| 407 | 410 |
utils.KillProcess(cmd.Process.Pid) |
| 408 | 411 |
return err |
| ... | ... |
@@ -417,6 +421,16 @@ func (r *remote) runContainerdDaemon() error {
|
| 417 | 417 |
return nil |
| 418 | 418 |
} |
| 419 | 419 |
|
| 420 |
+func setOOMScore(pid, score int) error {
|
|
| 421 |
+ f, err := os.OpenFile(fmt.Sprintf("/proc/%d/oom_score_adj", pid), os.O_WRONLY, 0)
|
|
| 422 |
+ if err != nil {
|
|
| 423 |
+ return err |
|
| 424 |
+ } |
|
| 425 |
+ _, err = f.WriteString(strconv.Itoa(score)) |
|
| 426 |
+ f.Close() |
|
| 427 |
+ return err |
|
| 428 |
+} |
|
| 429 |
+ |
|
| 420 | 430 |
// WithRemoteAddr sets the external containerd socket to connect to. |
| 421 | 431 |
func WithRemoteAddr(addr string) RemoteOption {
|
| 422 | 432 |
return rpcAddr(addr) |
| ... | ... |
@@ -510,3 +524,18 @@ func (l liveRestore) Apply(r Remote) error {
|
| 510 | 510 |
} |
| 511 | 511 |
return fmt.Errorf("WithLiveRestore option not supported for this remote")
|
| 512 | 512 |
} |
| 513 |
+ |
|
| 514 |
+// WithOOMScore defines the oom_score_adj to set for the containerd process. |
|
| 515 |
+func WithOOMScore(score int) RemoteOption {
|
|
| 516 |
+ return oomScore(score) |
|
| 517 |
+} |
|
| 518 |
+ |
|
| 519 |
+type oomScore int |
|
| 520 |
+ |
|
| 521 |
+func (o oomScore) Apply(r Remote) error {
|
|
| 522 |
+ if remote, ok := r.(*remote); ok {
|
|
| 523 |
+ remote.oomScore = int(o) |
|
| 524 |
+ return nil |
|
| 525 |
+ } |
|
| 526 |
+ return fmt.Errorf("WithOOMScore option not supported for this remote")
|
|
| 527 |
+} |