1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Soften limitation of update kernel memory

Kernel memory is not allowed to be updated if container is
running, it's not actually a precise kernel limitation.

Before kernel version 4.6, kernel memory will not be accounted
until kernel memory limit is set, if a container created with
kernel memory initialized, kernel memory is accounted as soon
as process created in container, so kernel memory limit update
is allowed afterward. If kernel memory is not initialized,
kernel memory consumed by processes in container will not be
accounted, so we can't update the limit because the account
will be wrong.

So update kernel memory of a running container with kernel memory
initialized is allowed, we should soften the limitation by docker.

Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
This commit is contained in:
Qiang Huang 2016-07-12 08:07:24 +08:00
parent 8f3be176d2
commit 08c7075c40
4 changed files with 53 additions and 18 deletions

View file

@ -61,10 +61,6 @@ func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) erro
return errCannotUpdate(container.ID, fmt.Errorf("Container is marked for removal and cannot be \"update\"."))
}
if container.IsRunning() && hostConfig.KernelMemory != 0 {
return errCannotUpdate(container.ID, fmt.Errorf("Can not update kernel memory to a running container, please stop it first."))
}
if err := container.UpdateContainer(hostConfig); err != nil {
restoreConfig = true
return errCannotUpdate(container.ID, err)

View file

@ -38,9 +38,23 @@ space-separated list of container names or IDs.
With the exception of the `--kernel-memory` value, you can specify these
options on a running or a stopped container. You can only update
`--kernel-memory` on a stopped container. When you run `docker update` on
stopped container, the next time you restart it, the container uses those
values.
`--kernel-memory` on a stopped container or on a running container with
kernel memory initialized. For example, if you started a container with
command:
# docker run -ti --name test --kernel-memory 50M ubuntu bash
You can update kernel memory of this running container:
# docker update --kernel-memory 80M test
If you started a container without kernel memory initialized:
# docker run -ti --name test2 --memory 300M ubuntu bash
Update kernel memory of running container `test2` will fail, you can only
stop the container and update kernel memory then. The next time you
restart it, the container uses the new value.
Another configuration you can change with this command is restart policy,
new restart policy will take effect instantly after you run `docker update`

View file

@ -120,17 +120,27 @@ func (s *DockerSuite) TestUpdateKernelMemory(c *check.C) {
name := "test-update-container"
dockerCmd(c, "run", "-d", "--name", name, "--kernel-memory", "50M", "busybox", "top")
_, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name)
// Update kernel memory to a running container is not allowed.
c.Assert(err, check.NotNil)
dockerCmd(c, "update", "--kernel-memory", "100M", name)
// Update kernel memory to a running container with failure should not change HostConfig
c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "52428800")
c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "104857600")
file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"
out, _ := dockerCmd(c, "exec", name, "cat", file)
c.Assert(strings.TrimSpace(out), checker.Equals, "104857600")
}
func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) {
testRequires(c, DaemonIsLinux, kernelMemorySupport)
name := "test-update-container"
dockerCmd(c, "run", "-d", "--name", name, "busybox", "top")
_, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name)
// Update kernel memory to a running container without kernel memory initialized is not allowed.
c.Assert(err, check.NotNil)
dockerCmd(c, "pause", name)
_, _, err = dockerCmdWithError("update", "--kernel-memory", "100M", name)
c.Assert(err, check.NotNil)
c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "52428800")
dockerCmd(c, "unpause", name)
dockerCmd(c, "stop", name)

View file

@ -30,9 +30,23 @@ provide space-separated list of container names or IDs.
With the exception of the `--kernel-memory` value, you can specify these
options on a running or a stopped container. You can only update
`--kernel-memory` on a stopped container. When you run `docker update` on
stopped container, the next time you restart it, the container uses those
values.
`--kernel-memory` on a stopped container or on a running container with
kernel memory initialized. For example, if you started a container with
command:
# docker run -ti --name test --kernel-memory 50M ubuntu bash
You can update kernel memory of this running container:
# docker update --kernel-memory 80M test
If you started a container without kernel memory initialized:
# docker run -ti --name test2 --memory 300M ubuntu bash
Update kernel memory of running container `test2` will fail, you can only
stop the container and update kernel memory then. The next time you
restart it, the container uses the new value.
Another configuration you can change with this command is restart policy,
new restart policy will take effect instantly after you run `docker update`
@ -63,8 +77,9 @@ on a container.
**--kernel-memory**=""
Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g)
Note that you can not update kernel memory to a running container, it can only
be updated to a stopped container, and affect after it's started.
Note that you can not update kernel memory to a running container if the container
is started without kernel memory initialized, in this case, it can only be updated
after it's stopped, and affect after it's started.
**-m**, **--memory**=""
Memory limit (format: <number><optional unit>, where unit = b, k, m or g)