Docker容器资源限制,限制CPU内存防止抢占资源

当一台服务器上跑着多个 Docker 容器时,某个容器突然吃满 CPU 或内存,会导致其他服务响应变慢甚至被系统杀掉。
解决这个问题的核心思路是:在启动容器时通过参数给它设定 CPU 和内存上限,让资源分配可控。
本文从零开始,带你用 docker run 和 docker-compose 完成限制配置,并验证限制是否真正生效。

先确认你的环境支持资源限制

Docker 的资源限制依赖 Linux 内核的 cgroups 功能。
绝大多数现代 Linux 发行版默认已启用,不需要额外安装。

你可以执行下面命令快速检查:

docker info | grep -i cgroup

如果看到 Cgroup Driver: cgroupfs 或 systemd,同时 Cgroup Version 有输出,说明环境正常。
若提示找不到 cgroup,需要先确认内核版本和启动参数,建议查阅对应发行版官方文档。

另外,运行容器的用户需要有 sudo 权限或已加入 docker 用户组。

用 docker run 限制 CPU 和内存

内存限制

使用 --memory 或简写 -m 设置容器可用内存上限,单位可以是 m(兆)或 g(吉)。
例如限制为 512MB:

docker run -d --name myapp --memory="512m" nginx:latest

如果容器内存使用超过这个值,Docker 会尝试终止容器内的进程。
你也可以额外设置 --memory-swap 控制交换分区用量:

docker run -d --name myapp --memory="512m" --memory-swap="1g" nginx:latest

这里 --memory-swap 表示内存加交换分区总共可用 1GB,实际可用交换分区为 512MB。
如果不设置 --memory-swap,默认与 --memory 相同,即不使用交换分区。

CPU 限制

CPU 限制有两种常用方式:指定核心数或指定相对权重。

指定核心数(推荐):

docker run -d --name myapp --cpus="1.5" nginx:latest

这表示容器最多使用 1.5 个 CPU 核心的算力。

指定权重(适合多个容器竞争场景):

docker run -d --name myapp --cpu-shares=512 nginx:latest

--cpu-shares 默认值是 1024,数值越大,在 CPU 资源紧张时获得的份额越多。
它不设硬上限,只影响相对分配比例。

同时限制内存和 CPU

实际使用时通常两者一起设置:

docker run -d \
  --name myapp \
  --memory="1g" \
  --cpus="2" \
  --restart=unless-stopped \
  nginx:latest

执行后可以用 docker stats myapp 查看实时资源占用,确认限制是否生效。

docker-compose 中配置资源限制

如果你用 docker-compose 管理服务,
在 docker-compose.yml 中对应服务下添加 deploy.resources 或旧版 mem_limit、cpus 字段。

推荐写法(Compose V2 及以上):

services:
  myapp:
    image: nginx:latest
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 1g
        reservations:
          cpus: "0.5"
          memory: 256m

注意:deploy 块在非 Swarm 模式下部分字段可能被忽略,若发现限制无效,可以改用以下兼容写法:

services:
  myapp:
    image: nginx:latest
    mem_limit: 1g
    cpus: 2

修改后执行 docker-compose up -d 重建容器,再用 docker stats 检查。

容易踩坑的几个地方

  • 内存限制设得太低:比如给 Java 应用只分 256MB,JVM 还没启动就被 OOM 杀掉。建议先观察容器正常运行时实际占用,再留出 30% 余量。
  • 只看 --cpu-shares 就以为能限制上限:它只是权重,不是硬上限。真正限制 CPU 用量要用 --cpus 或 --cpu-quota。
  • 忘记检查宿主机内核是否支持:极少数精简系统或旧内核可能未启用 cgroup 内存子系统,导致限制不生效。
  • 容器内进程仍可能被系统 OOM Killer 终止:即使设置了内存限制,如果宿主机整体内存不足,内核仍可能杀掉容器进程。建议同时关注宿主机 free -h 和 dmesg 日志。

验证限制是否真正生效

启动一个带限制的容器后,用下面两个方法交叉验证:

方法一,查看容器详细信息:

docker inspect myapp | grep -i -E "memory|cpu"

输出中能看到 Memory、NanoCpus 等字段,确认数值与设定一致。

方法二,实时监控:

docker stats myapp

MEM USAGE / LIMIT 列会显示当前用量和上限,CPU % 列会显示相对于单核的百分比。
如果上限显示为 0B 或 0%,说明限制未生效,需要回到上一步检查配置。

常见疑问

限制内存后容器启动失败,报错 Cannot allocate memory,怎么办?

先确认 --memory 值是否低于应用最小需求。
可以临时去掉限制启动一次,用 docker stats 观察峰值,再重新设定一个合理值。

--cpus 可以设成小数吗?

可以。--cpus="0.5" 表示半个核心的算力,适合低负载服务。

设置了限制,但容器还是占用了很多 CPU?

检查是否只设置了 --cpu-shares。
如果宿主机 CPU 空闲,容器仍然可以短时跑满核心,这是权重机制的正常表现。
要硬限制请用 --cpus。

docker-compose 中 deploy 不生效怎么办?

非 Swarm 模式下改用 mem_limit 和 cpus 字段,并确保 Compose 版本支持。
修改后记得 docker-compose down 再 up -d,让配置完全重建。

完成以上配置后,建议在业务低峰期做一次压力测试,观察限制值是否满足服务正常运行。
如果后续调整了应用内存需求,同步更新启动参数或 compose 文件即可。

分享到:
上一篇
Redis哨兵Sentinel高可用部署
下一篇
Shell脚本监控SSL证书到期,提前邮件告警提醒
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意