libcontainer v0.0.4 introduces setting `/proc/self/oom_score_adj` to
better tune oom killing preferences for container process. This patch
simply integrates OomScoreAdj libcontainer's config option and adjust
the cli with this new option.
Signed-off-by: Antonio Murdaca <amurdaca@redhat.com>
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
| ... | ... |
@@ -482,6 +482,7 @@ __docker_subcommand() {
|
| 482 | 482 |
"($help)--name=[Container name]:name: " |
| 483 | 483 |
"($help)--net=[Connect a container to a network]:network mode:(bridge none container host)" |
| 484 | 484 |
"($help)--oom-kill-disable[Disable OOM Killer]" |
| 485 |
+ "($help)--oom-score-adj[Tune the host's OOM preferences for containers (accepts -1000 to 1000)]" |
|
| 485 | 486 |
"($help -P --publish-all)"{-P,--publish-all}"[Publish all exposed ports]"
|
| 486 | 487 |
"($help)*"{-p=,--publish=}"[Expose a container's port to the host]:port:_ports"
|
| 487 | 488 |
"($help)--pid=[PID namespace to use]:PID: " |
| ... | ... |
@@ -345,6 +345,7 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
|
| 345 | 345 |
GIDMapping: gidMap, |
| 346 | 346 |
GroupAdd: c.hostConfig.GroupAdd, |
| 347 | 347 |
Ipc: ipc, |
| 348 |
+ OomScoreAdj: c.hostConfig.OomScoreAdj, |
|
| 348 | 349 |
Pid: pid, |
| 349 | 350 |
ReadonlyRootfs: c.hostConfig.ReadonlyRootfs, |
| 350 | 351 |
RemappedRoot: remappedRoot, |
| ... | ... |
@@ -246,6 +246,9 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC |
| 246 | 246 |
return warnings, fmt.Errorf("Your kernel does not support oom kill disable.")
|
| 247 | 247 |
} |
| 248 | 248 |
|
| 249 |
+ if hostConfig.OomScoreAdj < -1000 || hostConfig.OomScoreAdj > 1000 {
|
|
| 250 |
+ return warnings, fmt.Errorf("Invalid value %d, range for oom score adj is [-1000, 1000].", hostConfig.OomScoreAdj)
|
|
| 251 |
+ } |
|
| 249 | 252 |
if sysInfo.IPv4ForwardingDisabled {
|
| 250 | 253 |
warnings = append(warnings, "IPv4 forwarding is disabled. Networking will not work.") |
| 251 | 254 |
logrus.Warnf("IPv4 forwarding is disabled. Networking will not work")
|
| ... | ... |
@@ -113,6 +113,7 @@ type Command struct {
|
| 113 | 113 |
GIDMapping []idtools.IDMap `json:"gidmapping"` |
| 114 | 114 |
GroupAdd []string `json:"group_add"` |
| 115 | 115 |
Ipc *Ipc `json:"ipc"` |
| 116 |
+ OomScoreAdj int `json:"oom_score_adj"` |
|
| 116 | 117 |
Pid *Pid `json:"pid"` |
| 117 | 118 |
ReadonlyRootfs bool `json:"readonly_rootfs"` |
| 118 | 119 |
RemappedRoot *User `json:"remap_root"` |
| ... | ... |
@@ -83,6 +83,8 @@ func (d *Driver) createContainer(c *execdriver.Command, hooks execdriver.Hooks) |
| 83 | 83 |
return nil, err |
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 |
+ container.OomScoreAdj = c.OomScoreAdj |
|
| 87 |
+ |
|
| 86 | 88 |
if container.Readonlyfs {
|
| 87 | 89 |
for i := range container.Mounts {
|
| 88 | 90 |
switch container.Mounts[i].Destination {
|
| ... | ... |
@@ -107,12 +107,11 @@ This section lists each version from latest to oldest. Each listing includes a |
| 107 | 107 |
* `POST /volumes/create` to create a volume. |
| 108 | 108 |
* `GET /volumes/(name)` get low-level information about a volume. |
| 109 | 109 |
* `DELETE /volumes/(name)`remove a volume with the specified name. |
| 110 |
-* `VolumeDriver` has been moved from config to hostConfig to make the configuration portable. |
|
| 111 |
-* `GET /images/(name)/json` now returns information about tags and digests of the image. |
|
| 110 |
+* `VolumeDriver` was moved from `config` to `HostConfig` to make the configuration portable. |
|
| 111 |
+* `GET /images/(name)/json` now returns information about an image's `RepoTags` and `RepoDigests`. |
|
| 112 | 112 |
* The `config` option now accepts the field `StopSignal`, which specifies the signal to use to kill a container. |
| 113 | 113 |
* `GET /containers/(id)/stats` will return networking information respectively for each interface. |
| 114 |
-* The `hostConfig` option now accepts the field `DnsOptions`, which specifies a |
|
| 115 |
-list of DNS options to be used in the container. |
|
| 114 |
+* The `HostConfig` option now includes the `DnsOptions` field to configure the container's DNS options. |
|
| 116 | 115 |
* `POST /build` now optionally takes a serialized map of build-time variables. |
| 117 | 116 |
* `GET /events` now includes a `timenano` field, in addition to the existing `time` field. |
| 118 | 117 |
* `GET /events` now supports filtering by image and container labels. |
| ... | ... |
@@ -130,6 +129,9 @@ list of DNS options to be used in the container. |
| 130 | 130 |
`NetworkSettings.Gateway`, `NetworkSettings.IPAddress`, |
| 131 | 131 |
`NetworkSettings.IPPrefixLen`, and `NetworkSettings.MacAddress` fields, which |
| 132 | 132 |
are still returned for backward-compatibility, but will be removed in a future version. |
| 133 |
+* The `HostConfig` option now includes the `OomScoreAdj` field for adjusting the |
|
| 134 |
+ badness heuristic. This heuristic selects which processes the OOM killer kills |
|
| 135 |
+ under out-of-memory conditions. |
|
| 133 | 136 |
|
| 134 | 137 |
### v1.20 API changes |
| 135 | 138 |
|
| ... | ... |
@@ -217,7 +219,7 @@ container. Previously this was only available when starting a container. |
| 217 | 217 |
[Docker Remote API v1.14](docker_remote_api_v1.14.md) documentation |
| 218 | 218 |
|
| 219 | 219 |
* `DELETE /containers/(id)` when using `force`, the container will be immediately killed with SIGKILL. |
| 220 |
-* `POST /containers/(id)/start` the `hostConfig` option accepts the field `CapAdd`, which specifies a list of capabilities |
|
| 220 |
+* `POST /containers/(id)/start` the `HostConfig` option accepts the field `CapAdd`, which specifies a list of capabilities |
|
| 221 | 221 |
to add, and the field `CapDrop`, which specifies a list of capabilities to drop. |
| 222 | 222 |
* `POST /images/create` th `fromImage` and `repo` parameters support the |
| 223 | 223 |
`repo:tag` format. Consequently, the `tag` parameter is now obsolete. Using the |
| ... | ... |
@@ -190,6 +190,7 @@ Create a container |
| 190 | 190 |
"BlkioWeightDevice": [{}],
|
| 191 | 191 |
"MemorySwappiness": 60, |
| 192 | 192 |
"OomKillDisable": false, |
| 193 |
+ "OomScoreAdj": 500, |
|
| 193 | 194 |
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
|
| 194 | 195 |
"PublishAllPorts": false, |
| 195 | 196 |
"Privileged": false, |
| ... | ... |
@@ -243,9 +244,10 @@ Json Parameters: |
| 243 | 243 |
- **CpusetCpus** - String value containing the `cgroups CpusetCpus` to use. |
| 244 | 244 |
- **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. |
| 245 | 245 |
- **BlkioWeight** - Block IO weight (relative weight) accepts a weight value between 10 and 1000. |
| 246 |
- - **BlkioWeightDevice** - Block IO weight (relative device weight) in the form of: `"BlkioWeightDevice": [{"Path": "device_path", "Weight": weight}]`
|
|
| 246 |
+- **BlkioWeightDevice** - Block IO weight (relative device weight) in the form of: `"BlkioWeightDevice": [{"Path": "device_path", "Weight": weight}]`
|
|
| 247 | 247 |
- **MemorySwappiness** - Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. |
| 248 | 248 |
- **OomKillDisable** - Boolean value, whether to disable OOM Killer for the container or not. |
| 249 |
+- **OomScoreAdj** - An integer value containing the score given to the container in order to tune OOM killer preferences. |
|
| 249 | 250 |
- **AttachStdin** - Boolean value, attaches to `stdin`. |
| 250 | 251 |
- **AttachStdout** - Boolean value, attaches to `stdout`. |
| 251 | 252 |
- **AttachStderr** - Boolean value, attaches to `stderr`. |
| ... | ... |
@@ -416,6 +418,7 @@ Return low-level information on the container `id` |
| 416 | 416 |
"MemoryReservation": 0, |
| 417 | 417 |
"KernelMemory": 0, |
| 418 | 418 |
"OomKillDisable": false, |
| 419 |
+ "OomScoreAdj": 500, |
|
| 419 | 420 |
"NetworkMode": "bridge", |
| 420 | 421 |
"PortBindings": {},
|
| 421 | 422 |
"Privileged": false, |
| ... | ... |
@@ -1950,6 +1953,7 @@ Display system-wide information |
| 1950 | 1950 |
"NoProxy": "9.81.1.160", |
| 1951 | 1951 |
"OomKillDisable": true, |
| 1952 | 1952 |
"OSType": "linux", |
| 1953 |
+ "OomScoreAdj": 500, |
|
| 1953 | 1954 |
"OperatingSystem": "Boot2Docker", |
| 1954 | 1955 |
"RegistryConfig": {
|
| 1955 | 1956 |
"IndexConfigs": {
|
| ... | ... |
@@ -57,6 +57,7 @@ Creates a new container. |
| 57 | 57 |
--name="" Assign a name to the container |
| 58 | 58 |
--net="default" Set the Network mode for the container |
| 59 | 59 |
--oom-kill-disable=false Whether to disable OOM Killer for the container or not |
| 60 |
+ --oom-score-adj=0 Tune the host's OOM preferences for containers (accepts -1000 to 1000) |
|
| 60 | 61 |
-P, --publish-all=false Publish all exposed ports to random ports |
| 61 | 62 |
-p, --publish=[] Publish a container's port(s) to the host |
| 62 | 63 |
--pid="" PID namespace to use |
| ... | ... |
@@ -61,6 +61,7 @@ parent = "smn_cli" |
| 61 | 61 |
'host': use the host network stack inside the container |
| 62 | 62 |
'NETWORK': connects the container to user-created network using `docker network create` command |
| 63 | 63 |
--oom-kill-disable=false Whether to disable OOM Killer for the container or not |
| 64 |
+ --oom-score-adj=0 Tune the host's OOM preferences for containers (accepts -1000 to 1000) |
|
| 64 | 65 |
-P, --publish-all=false Publish all exposed ports to random ports |
| 65 | 66 |
-p, --publish=[] Publish a container's port(s) to the host |
| 66 | 67 |
--pid="" PID namespace to use |
| ... | ... |
@@ -1553,3 +1553,34 @@ func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C) |
| 1553 | 1553 |
expected = "Invalid value 42-3,1-- for cpuset mems.\n" |
| 1554 | 1554 |
c.Assert(string(body), check.Equals, expected, check.Commentf("Expected output to contain %q, got %q", expected, string(body)))
|
| 1555 | 1555 |
} |
| 1556 |
+ |
|
| 1557 |
+// check validation is done daemon side and not only in cli |
|
| 1558 |
+func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *check.C) {
|
|
| 1559 |
+ testRequires(c, DaemonIsLinux) |
|
| 1560 |
+ |
|
| 1561 |
+ config := struct {
|
|
| 1562 |
+ Image string |
|
| 1563 |
+ OomScoreAdj int |
|
| 1564 |
+ }{"busybox", 1001}
|
|
| 1565 |
+ name := "oomscoreadj-over" |
|
| 1566 |
+ status, b, err := sockRequest("POST", "/containers/create?name="+name, config)
|
|
| 1567 |
+ c.Assert(err, check.IsNil) |
|
| 1568 |
+ c.Assert(status, check.Equals, http.StatusInternalServerError) |
|
| 1569 |
+ expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]." |
|
| 1570 |
+ if !strings.Contains(string(b), expected) {
|
|
| 1571 |
+ c.Fatalf("Expected output to contain %q, got %q", expected, string(b))
|
|
| 1572 |
+ } |
|
| 1573 |
+ |
|
| 1574 |
+ config = struct {
|
|
| 1575 |
+ Image string |
|
| 1576 |
+ OomScoreAdj int |
|
| 1577 |
+ }{"busybox", -1001}
|
|
| 1578 |
+ name = "oomscoreadj-low" |
|
| 1579 |
+ status, b, err = sockRequest("POST", "/containers/create?name="+name, config)
|
|
| 1580 |
+ c.Assert(err, check.IsNil) |
|
| 1581 |
+ c.Assert(status, check.Equals, http.StatusInternalServerError) |
|
| 1582 |
+ expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]." |
|
| 1583 |
+ if !strings.Contains(string(b), expected) {
|
|
| 1584 |
+ c.Fatalf("Expected output to contain %q, got %q", expected, string(b))
|
|
| 1585 |
+ } |
|
| 1586 |
+} |
| ... | ... |
@@ -3761,3 +3761,31 @@ func (s *DockerSuite) TestRunInvalidReference(c *check.C) {
|
| 3761 | 3761 |
c.Fatalf(`Expected "invalid reference format" in output; got: %s`, out) |
| 3762 | 3762 |
} |
| 3763 | 3763 |
} |
| 3764 |
+ |
|
| 3765 |
+func (s *DockerSuite) TestRunWithOomScoreAdj(c *check.C) {
|
|
| 3766 |
+ testRequires(c, DaemonIsLinux) |
|
| 3767 |
+ |
|
| 3768 |
+ expected := "642" |
|
| 3769 |
+ out, _ := dockerCmd(c, "run", "--oom-score-adj", expected, "busybox", "cat", "/proc/self/oom_score_adj") |
|
| 3770 |
+ oomScoreAdj := strings.TrimSpace(out) |
|
| 3771 |
+ if oomScoreAdj != "642" {
|
|
| 3772 |
+ c.Fatalf("Expected oom_score_adj set to %q, got %q instead", expected, oomScoreAdj)
|
|
| 3773 |
+ } |
|
| 3774 |
+} |
|
| 3775 |
+ |
|
| 3776 |
+func (s *DockerSuite) TestRunWithOomScoreAdjInvalidRange(c *check.C) {
|
|
| 3777 |
+ testRequires(c, DaemonIsLinux) |
|
| 3778 |
+ |
|
| 3779 |
+ out, _, err := dockerCmdWithError("run", "--oom-score-adj", "1001", "busybox", "true")
|
|
| 3780 |
+ c.Assert(err, check.NotNil) |
|
| 3781 |
+ expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]." |
|
| 3782 |
+ if !strings.Contains(out, expected) {
|
|
| 3783 |
+ c.Fatalf("Expected output to contain %q, got %q instead", expected, out)
|
|
| 3784 |
+ } |
|
| 3785 |
+ out, _, err = dockerCmdWithError("run", "--oom-score-adj", "-1001", "busybox", "true")
|
|
| 3786 |
+ c.Assert(err, check.NotNil) |
|
| 3787 |
+ expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]." |
|
| 3788 |
+ if !strings.Contains(out, expected) {
|
|
| 3789 |
+ c.Fatalf("Expected output to contain %q, got %q instead", expected, out)
|
|
| 3790 |
+ } |
|
| 3791 |
+} |
| ... | ... |
@@ -46,6 +46,7 @@ docker-create - Create a new container |
| 46 | 46 |
[**--name**[=*NAME*]] |
| 47 | 47 |
[**--net**[=*"bridge"*]] |
| 48 | 48 |
[**--oom-kill-disable**[=*false*]] |
| 49 |
+[**--oom-score-adj**[=*0*]] |
|
| 49 | 50 |
[**-P**|**--publish-all**[=*false*]] |
| 50 | 51 |
[**-p**|**--publish**[=*[]*]] |
| 51 | 52 |
[**--pid**[=*[]*]] |
| ... | ... |
@@ -229,6 +230,9 @@ This value should always larger than **-m**, so you should always use this with |
| 229 | 229 |
**--oom-kill-disable**=*true*|*false* |
| 230 | 230 |
Whether to disable OOM Killer for the container or not. |
| 231 | 231 |
|
| 232 |
+**--oom-score-adj**="" |
|
| 233 |
+ Tune the host's OOM preferences for containers (accepts -1000 to 1000) |
|
| 234 |
+ |
|
| 232 | 235 |
**-P**, **--publish-all**=*true*|*false* |
| 233 | 236 |
Publish all exposed ports to random ports on the host interfaces. The default is *false*. |
| 234 | 237 |
|
| ... | ... |
@@ -47,6 +47,7 @@ docker-run - Run a command in a new container |
| 47 | 47 |
[**--name**[=*NAME*]] |
| 48 | 48 |
[**--net**[=*"bridge"*]] |
| 49 | 49 |
[**--oom-kill-disable**[=*false*]] |
| 50 |
+[**--oom-score-adj**[=*0*]] |
|
| 50 | 51 |
[**-P**|**--publish-all**[=*false*]] |
| 51 | 52 |
[**-p**|**--publish**[=*[]*]] |
| 52 | 53 |
[**--pid**[=*[]*]] |
| ... | ... |
@@ -341,6 +342,9 @@ and foreground Docker containers. |
| 341 | 341 |
**--oom-kill-disable**=*true*|*false* |
| 342 | 342 |
Whether to disable OOM Killer for the container or not. |
| 343 | 343 |
|
| 344 |
+**--oom-score-adj**="" |
|
| 345 |
+ Tune the host's OOM preferences for containers (accepts -1000 to 1000) |
|
| 346 |
+ |
|
| 344 | 347 |
**-P**, **--publish-all**=*true*|*false* |
| 345 | 348 |
Publish all exposed ports to random ports on the host interfaces. The default is *false*. |
| 346 | 349 |
|
| ... | ... |
@@ -211,6 +211,7 @@ type HostConfig struct {
|
| 211 | 211 |
GroupAdd []string // List of additional groups that the container process will run as |
| 212 | 212 |
IpcMode IpcMode // IPC namespace to use for the container |
| 213 | 213 |
Links []string // List of links (in the name:alias form) |
| 214 |
+ OomScoreAdj int // Container preference for OOM-killing |
|
| 214 | 215 |
OomKillDisable bool // Whether to disable OOM Killer or not |
| 215 | 216 |
PidMode PidMode // PID namespace to use for the container |
| 216 | 217 |
Privileged bool // Is the container in privileged mode |
| ... | ... |
@@ -79,6 +79,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 79 | 79 |
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
|
| 80 | 80 |
flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
|
| 81 | 81 |
flOomKillDisable = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer")
|
| 82 |
+ flOomScoreAdj = cmd.Int([]string{"-oom-score-adj"}, 0, "Tune host's OOM preferences (-1000 to 1000)")
|
|
| 82 | 83 |
flContainerIDFile = cmd.String([]string{"-cidfile"}, "", "Write the container ID to the file")
|
| 83 | 84 |
flEntrypoint = cmd.String([]string{"-entrypoint"}, "", "Overwrite the default ENTRYPOINT of the image")
|
| 84 | 85 |
flHostname = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
|
| ... | ... |
@@ -94,7 +95,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 94 | 94 |
flCpusetCpus = cmd.String([]string{"-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)")
|
| 95 | 95 |
flCpusetMems = cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)")
|
| 96 | 96 |
flBlkioWeight = cmd.Uint16([]string{"-blkio-weight"}, 0, "Block IO (relative weight), between 10 and 1000")
|
| 97 |
- flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tuning container memory swappiness (0 to 100)")
|
|
| 97 |
+ flSwappiness = cmd.Int64([]string{"-memory-swappiness"}, -1, "Tune container memory swappiness (0 to 100)")
|
|
| 98 | 98 |
flNetMode = cmd.String([]string{"-net"}, "default", "Set the Network for the container")
|
| 99 | 99 |
flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
|
| 100 | 100 |
flIpcMode = cmd.String([]string{"-ipc"}, "", "IPC namespace to use")
|
| ... | ... |
@@ -369,6 +370,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 369 | 369 |
hostConfig := &HostConfig{
|
| 370 | 370 |
Binds: binds, |
| 371 | 371 |
ContainerIDFile: *flContainerIDFile, |
| 372 |
+ OomScoreAdj: *flOomScoreAdj, |
|
| 372 | 373 |
OomKillDisable: *flOomKillDisable, |
| 373 | 374 |
Privileged: *flPrivileged, |
| 374 | 375 |
PortBindings: portBindings, |