我正在使用 Docker 的 Python API。如何限制一组 Docker 容器使用的内存?(不是在 Kubernetes 上,而是在普通的原始 Docker 机器上)。
假设我们有容器 A 和 B:两者的总和不应超过 4 GB。
我不想将每个限制为 2 GB。我想给他们一点灵活性。任何帮助都将不胜感激。
答案1
这是由 cgroups 提供的。默认情况下,每个容器都会获得一个具有其自身限制的单独 cgroup。但是,如果您创建自己的 cgroup,则可以将该组指定为父级的容器,并且父级限制将应用于所有容器。从docker run
,选项是--cgroup-parent
。创建 cgroup 的过程可能有所不同,但在 Debian 上,您可以通过创建适当的文件夹来创建它们。
首先,创建 cgroup,限制为 1 CPU、2,000,000,000 字节内存:
$ mkdir /sys/fs/cgroup/cpu/demo
$ echo 100000 > /sys/fs/cgroup/cpu/demo/cpu.cfs_quota_us
$ echo 100000 > /sys/fs/cgroup/cpu/demo/cpu.cfs_period_us
$ echo 2000000000 > /sys/fs/cgroup/memory/demo/memory.limit_in_bytes
运行几个使用大量内存的容器,这些容器本身没有限制,但设置了 cgroup-parent:
$ docker run -itd --cgroup-parent /demo/ busybox dd if=/dev/zero of=/dev/null bs=1500000000
9581e0bb181f1733034634bc2cb53660e6c8b196863ea7fb68d7d810b3fa8f2b
$ docker run -itd --cgroup-parent /demo/ busybox dd if=/dev/zero of=/dev/null bs=1500000000
12be031c65c47e13bf3a124dd9e5c9f4f1ef4358d9f5665dfb59f8d390dd979b
检查统计数据:
$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
12be031c65c4 blissful_payn 94.18% 1.401GiB / 31.17GiB 4.49% 3.85kB / 516B 1.18MB / 0B 1
9581e0bb181f optimistic_grothendieck 0.00% 0B / 0B 0.00% 0B / 0B 0B / 0B 0
看起来其中一个死了,检查一下:
$ docker inspect 9581e0bb181f
[
{
"Id": "9581e0bb181f1733034634bc2cb53660e6c8b196863ea7fb68d7d810b3fa8f2b",
"Created": "2021-04-30T20:08:51.738346833Z",
"Path": "dd",
"Args": [
"if=/dev/zero",
"of=/dev/null",
"bs=1500000000"
],
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": true,
"Dead": false,
"Pid": 0,
"ExitCode": 137,
"Error": "",
"StartedAt": "2021-04-30T20:08:52.31883901Z",
"FinishedAt": "2021-04-30T20:08:54.632646751Z"
},
看起来它是被 OOM 杀死了,因为每个容器都使用了 1.5G 内存,但只分配了约 2G。
答案2
根据 Docker 文档 带有内存、CPU 和 GPU 的运行时选项,所有约束都是针对每个容器的,而不是针对整个容器组。
可能存在支持此类限制的第三方容器管理系统,但我不认为纯 Docker 支持它。