一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何通过 cgroups 限制 Docker 容器的内存物理上限与 Swap 交换分区以防内存溢出

时间:2026-07-07 10:48:02 编辑:袖梨 来源:一聚教程网

Docker通过--memory和--memory-swap参数直接映射cgroups v1的memory.limit_in_bytes与memory.memsw.limit_in_bytes,前者限制物理内存上限,后者限制内存+swap总和(必须≥前者),共同防止宿主机OOM。

直接通过 Docker 的 --memory--memory-swap 参数就能生效,它们底层就是写入 cgroups v1 的 memory controller 文件。关键不是手动改 cgroup,而是理解这两个参数如何映射到物理内存与 swap 的硬性边界。

物理内存上限由 --memory 决定

该参数对应 cgroups v1 中的 memory.limit_in_bytes,限制容器能使用的最大物理内存字节数。超出即触发 OOM Killer 杀进程。

  • --memory=256m/sys/fs/cgroup/memory/docker/<id>/memory.limit_in_bytes 显示 268435456
  • 设为 0 表示不限制(不推荐),设太小会导致 Java 等应用启动失败
  • 注意:这个值只管物理内存,不管 swap;swap 是否可用、用多少,取决于 --memory-swap

Swap 总量由 --memory-swap 控制

--memory-swap 不是单独的 swap 上限,而是“物理内存 + swap”的总和上限,对应 memory.memsw.limit_in_bytes。它的值必须 ≥ --memory,否则报错。

  • --memory=256m --memory-swap=768m → 最多用 256MB 物理内存 + 512MB swap
  • --memory=256m --memory-swap=256m → swap 被禁用(memory.memsw.limit_in_bytes == memory.limit_in_bytes
  • --memory=256m --memory-swap=-1 → 物理内存仍限 256MB,但 swap 不设上限(需宿主机有 swap 分区)

验证 cgroups 是否真正生效

不能只看 free -hswapon -s,容器内通常看不到 swap 设备。要确认限制已写入 cgroups:

  • 进容器执行:cat /sys/fs/cgroup/memory/memory.limit_in_bytescat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes
  • 在宿主机查:docker inspect <容器名> | jq '.[0].HostConfig.Memory, .[0].HostConfig.MemorySwap'
  • 实时观察用量:docker stats <容器名> --no-stream,其中 “MEM USAGE / LIMIT” 的 LIMIT 是 memory+swap 总和

前提条件:cgroups swap 功能必须可用

如果配置了但没效果,大概率是内核或 Docker 没启用 swap accounting:

  • 检查内核是否开启:zgrep CONFIG_MEMCG_SWAP /proc/config.gzgrep MEMCG_SWAP /boot/config-$(uname -r),应为 y
  • 确认宿主机有活跃 swap:swapon --show 非空
  • Docker 启动时未加 --no-swappiness 类参数,且 /etc/docker/daemon.json 中未覆盖相关 ulimit 或 cgroup 设置

热门栏目