docker容器限制内存
问题
当你使用 docker run --memory=10240m 启动容器时,理论上应该限制容器最多使用约 10GB 的内存。然而,如果你发现:
docker stats显示容器可以使用宿主机全部内存;
env
- centos7.9
- docker cgroupv1
分析
1. 使用 --network host 时,未开启 cgroup v2 或宿主机未正确配置 cgroups
检查是否为 cgroup v1 或 v2:
1 | mount | grep cgroup |
- 如果你看到
cgroup2,说明是 v2。 - 如果是传统的
cgroup(v1),部分内存限制在某些系统(尤其是老版本内核或某些发行版)不生效。
推荐:使用 cgroup v2 + systemd 管理资源限制,可以在现代 Linux(如 Ubuntu 20.04+/Debian 11+/CentOS 8+/Arch)中生效。
2. 启动容器的 Docker Daemon 没有正确启用内存限制功能
检查 docker info 输出中是否包含如下内容:
1 | docker info | grep -i cgroup |
应看到:
Cgroup Driver: systemd
Cgroup Version: 2 # or 1, 但要正确挂载 memory 子系统
若未启用限制,请检查内核参数:
编辑 /etc/default/grub 添加内核参数(仅限 grub 系统):
1 | GRUB_CMDLINE_LINUX="... systemd.unified_cgroup_hierarchy=1 cgroup_enable=memory swapaccount=1" |
然后执行:
1 | sudo update-grub |
3. 使用 --network=host 时,容器与宿主共享网络命名空间,不影响内存限制
这是很多人误会的点:**
--network host不会破坏 cgroup 限制!**
4. docker stats 显示的是 “宿主内存总量”,并不代表限制失效
示例解释:
1 | docker stats |
此处的 15GiB 可能是宿主机总内存,并不代表容器能用 15GB。
正确查看内存限制:
1 | cat /sys/fs/cgroup/memory/memory.limit_in_bytes |
在容器内执行也可以验证限制是否生效。
2.调整 run 命令为
1 | docker run \ |
其中 --memory-swap 默认值是内存限制的两倍,必须手动指定为与 --memory 相同,否则容器还是可能多用一些 swap。
3.验证是否生效
容器内执行:
1 | cat /sys/fs/cgroup/*/memory.max |
应看到限制为 10G。
4.附加建议
docker stats只是参考,不能当作内存限制的唯一验证工具。- 如在 K8s 中部署,建议使用
resources.limits.memory来限制。 - 不要在 run 时挂载宿主机的 cgroup 路径,避免绕过限制。