Docker容器限制CPU内存,防止资源占满
为什么需要限制Docker容器的CPU和内存
Docker容器限制CPU内存,防止资源占满,是服务器运维中很常见的需求。
如果不加限制,一个失控的容器可能吃光宿主机CPU或内存,导致其他服务卡顿甚至OOM。
本文面向零基础用户,给出docker run和docker-compose两种限制方法,以及部署后的验证手段。
适用场景:单台服务器跑多个容器、容器内应用内存泄漏、压测时防止影响宿主机。
操作前的准备条件
开始前确认以下三点:
- 已安装Docker,能执行
docker version和docker info不报错。 - 宿主机内核支持cgroup,一般CentOS 7+、Ubuntu 18.04+默认支持。
- 知道要限制的容器名称或镜像名,以及大致的内存和CPU配额。
查看当前容器资源占用,可以用:
docker stats --no-stream
如果某个容器MEM或CPU列持续接近宿主机上限,就适合做资源限制。
使用docker run限制CPU和内存
限制内存
-m 或 --memory 限制容器可用内存上限。
例如限制为512MB:
docker run -d --name myapp -m 512m nginx:latest
如果容器内存超限,Linux会触发OOM Killer,容器可能被杀死。
可以配合 --memory-swap 控制交换分区,--memory-swap 设为与 -m 相同值表示禁用swap。
限制CPU
--cpus 限制容器可以使用的CPU核数,支持小数。
例如限制为1.5核:
docker run -d --name myapp --cpus="1.5" nginx:latest
也可以用 --cpu-shares 设置相对权重,默认1024,值越小分到的CPU时间越少,但仅在CPU竞争时生效。
组合示例
docker run -d --name web \
-m 1g --memory-swap 1g \
--cpus="2.0" \
-p 80:80 \
nginx:latest
这条命令把容器内存限制在1GB,CPU限制在2核。
使用docker-compose限制资源
如果使用docker-compose管理容器,在 docker-compose.yml 中为服务添加 deploy.resources 或旧版 mem_limit、cpus。
推荐写法(Compose V3):
version: "3.8"
services:
app:
image: nginx:latest
deploy:
resources:
limits:
cpus: "1.5"
memory: 512M
reservations:
cpus: "0.5"
memory: 256M
注意:deploy.resources 在 docker-compose up 的默认模式下可能不生效,需要配合 docker stack deploy 或使用 --compatibility 参数。
更兼容的写法是:
version: "2.4"
services:
app:
image: nginx:latest
mem_limit: 512m
cpus: 1.5
改完后执行:
docker-compose up -d --force-recreate
避坑指南
- 不要只限制内存不限制swap:如果没设
--memory-swap,容器可能使用swap,导致性能下降。建议--memory-swap与-m相同。 - CPU限制不是硬上限:
--cpus是上限,但空闲时容器仍可能使用更多CPU,具体取决于调度。 - deploy.resources不生效:在非Swarm模式下,用
docker-compose --compatibility up -d或改用mem_limit和cpus。 - 限制后容器启动失败:内存设得太小,应用可能无法启动。先查看日志
docker logs 容器名,适当调大限制。
验证限制是否生效
执行以下命令查看容器资源限制:
docker inspect 容器名 | grep -i -E "memory|cpu"
输出中应能看到 Memory 和 NanoCpus 等字段。
例如 NanoCpus 为 1500000000 表示1.5核。
再用 docker stats 观察实际占用,确认不会超过设定值。
常见疑问
限制后容器变慢怎么办? 先用 docker stats 看是否达到上限,如果长期跑满,说明配额偏小,适当调大CPU或内存。
需要限制磁盘IO吗? 可以,使用 --device-read-bps 和 --device-write-bps,但需要宿主机支持。
已经运行的容器能改限制吗? Docker不支持动态修改,需要停止容器后用新参数重新创建,或使用 docker update 命令(部分参数支持)。
结尾
Docker容器限制CPU内存是防止资源占满的有效手段,关键在启动时加对参数,并用 docker stats 和 docker inspect 验证。
生产环境建议为每个容器设置合理上限,避免单个服务拖垮整台服务器。