容器资源配额限制防止进程抢占系统内存
容器内存配额限制可以精确控制单个容器能使用的最大内存,避免某个进程无故吃掉所有可用内存导致宿主机卡死或 OOM(内存溢出)。
即使是在一台云服务器上运行多个容器,只要合理设置内存上限,就能保证关键服务不会因为隔壁进程泄露内存而受影响。
本文面向零基础用户,按步骤演示从安装 Docker 到配置内存限额、验证效果的完整流程。
为什么必须限制容器内存
容器默认不限制资源,如果某个容器内的程序出现内存泄漏,它会持续占用宿主机物理内存和交换空间,最终触发系统 OOM Killer 杀掉其他进程。
更常见的情况是同一台服务器上运行了多个应用——比如数据库、 Web 服务、任务队列——如果不设置配额,一个繁忙的容器就可能挤占其他容器的内存,造成连锁故障。
内存配额就像是给每个容器划定一个“专属房间”,无论里面怎么折腾,都出不了房间的门。
准备工作:确认环境
在操作之前,确保你的云服务器已经安装了 Docker。
如果还没有,可以先参考《宝塔面板一键安装 Docker》或直接用系统包管理器安装:
# CentOS / Rocky Linux
sudo yum install -y docker
# Ubuntu / Debian
sudo apt install -y docker.io
# 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
确认 Docker 运行正常:
docker info | grep -i memory
如果输出中显示 Memory Limit: true,说明内核已支持内存配额,可以继续后续步骤。
使用 docker run 设置内存上限
启动容器时通过 -m 或 --memory 参数指定最大内存,同时建议配合 --memory-swap 来限制交换空间总量(设为与内存相同可禁用交换)。
示例:限制 Nginx 容器最多使用 256 MB 内存
docker run -d --name nginx-limited -m 256m --memory-swap 256m nginx:latest
参数说明:
-m 256m:容器最多使用 256 MB 物理内存。--memory-swap 256m:总内存+交换空间上限也是 256 MB,相当于禁止使用交换。如果不设此项,默认 swap 是内存的两倍,可能导致容器通过 swap 突破限制。--memory-swappiness:若需进一步调优,可设为 0 避免内核优先使用物理内存。
使用 docker-compose 时配置
version: '3'
services:
web:
image: nginx:latest
deploy:
resources:
limits:
memory: 256M
注意:deploy.resources.limits 仅在 Swarm 模式下生效;
普通 docker-compose up 时可用 mem_limit 字段:
version: '3'
services:
web:
image: nginx:latest
mem_limit: 256m
memswap_limit: 256m
容易踩的坑
- 忽略
--memory-swap:很多教程只设置-m,默认 swap 是内存的两倍,容器可以使用大量交换空间,依然可能影响宿主机性能。建议始终把 swap 设置为与内存相同数值。 - 在 docker-compose 中混用两种语法:同时写
mem_limit和deploy.resources会导致冲突,选择一种即可。 - 对容器的限制不适用于宿主机上的非容器进程:如果宿主机本身有其他服务,仍需配合系统级 cgroup 或监控工具。
- 内存软限制(
--memory-reservation)不保证执行:软限制只在内存竞争时触发,不能作为安全边界,零基础用户应优先使用硬限制(hard limit)。
验证配额是否生效
方法一:使用 docker stats 实时查看
docker stats nginx-limited
输出中 MEM USAGE / LIMIT 列会显示当前使用量和限制值,例如 10MiB / 256MiB。
方法二:进入容器查看 cgroup 文件
docker exec -it nginx-limited /bin/bash
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
# 输出应为 268435456(即 256 MB)
如果希望模拟内存超限,可在容器内安装 stress 工具测试:
apt update && apt install -y stress
stress --vm 1 --vm-bytes 300M --timeout 10s
此时观察 docker stats 会发现容器内存使用到达 256 MB 后被强制终止或触发 OOM(容器控制台会显示 Killed)。
常见问题
Q1:限制内存后容器启动失败是什么原因?
检查宿主机内核是否启用 cgroup 内存限制(docker info 显示 Memory Limit: true)。
某些国产轻量云默认内核参数可能未开启,需要修改 grub 启动参数,建议以云服务商官方文档为准。
Q2:容器被 OOM 杀死后如何自动重启?
在 docker run 时添加 --restart=always 即可,例如:
docker run -d --name myapp -m 512m --memory-swap 512m --restart=always nginx
Q3:已经运行的容器可以修改内存限制吗?
可以。
先停止容器,然后 docker update:
docker stop mycontainer
docker update -m 1g --memory-swap 1g mycontainer
docker start mycontainer
也可以在运行时动态更新(无需停止),但部分版本可能不支持,建议先停止再操作。
Q4:在云服务器上设置多少内存限额合适?
一般保留宿主机总内存的 20% 给系统和其他基础进程。
例如 8 GB 内存的主机,所有容器的内存上限总和建议不超过 6 GB。
具体数值根据业务负载调整,可以用 free -h 查看可用内存后估算。
稳定可靠的云服务器提供商如泽御云(具备正规 IDC 资质)提供的实例通常拥有稳定资源,但配额控制仍需用户自行配置。