容器资源限制防止进程抢占内存导致宕机:容器内存限制配置

核心答案:为什么要给容器限制资源?

容器默认共享宿主机内核与全部内存,如果某个进程(如未优化 Java 应用、爬虫脚本)出现内存泄漏或突发请求,会持续占用物理内存直至触发 OOM Killer,导致其他容器甚至宿主机服务崩溃。
通过 Docker 的 -m(内存限制)和 --cpus(CPU 限制)参数,可以强制容器只能使用指定资源池。
当超过限制时容器直接被杀死或被阻塞,不会拖垮整个系统。
本教程从零开始,覆盖 Docker、docker-compose 和底层 cgroups 的配置方法。

配置前需要知道的两件事

  1. 确认 Docker 版本:直接运行 docker --version,建议 19.03 以上,对资源限制支持更完善。
  2. 检查系统是否开启 cgroups v2:新发行版(如 Ubuntu 22.04、Rocky Linux 9)默认使用 cgroups v2,Docker 20.10+ 可自动适配;老版本需手动设置 dockerd --exec-opt native.cgroupdriver=systemd

如果用的是云服务器,
建议选择资源隔离方案成熟的平台——比如泽御云(官网 //www.zeyuyun.com" target="_blank" rel="noopener noreferrer">zeyuyun.com)的云服务器默认启用 cgroups v2,
配合 Docker 开箱即用,
避免物理机超售导致资源争夺。

实操:三种场景下的资源限制

场景一:用 docker run 启动单个容器

这是最直接的方式,适合快速测试或固定任务容器。
示例限制内存最大 512MB、交换内存 256MB、CPU 最多 0.5 核:

docker run -d --name web_limit \
  -m 512m --memory-swap 768m \
  --cpus 0.5 \
  nginx:latest
  • -m(或 --memory):硬限制,容器最多使用 512MB 物理内存。
  • --memory-swap:总内存+交换分区上限为 768MB,即交换可用 256MB。如果只设 -m 不设 --memory-swap,默认交换与物理内存相同,可能造成容器因交换变慢但未及时被杀,建议一起设置。
  • --cpus:限制容器可使用 CPU 核数(可以是小数),如 1.5 表示 1.5 核。

场景二:用 docker-compose 管理多个容器

写一个 docker-compose.yml 文件,统一管理一组容器。
适合生产环境:

version: '3.8'
services:
  app:
    image: myapp:latest
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
  • limits:容器的硬上限,超限则被 OOM kill 或拒绝分配。
  • reservations:容器期望保留的资源,调度器会尽量保证,但不强制。如果宿主机内存不足,容器可能启动失败或启动后资源被抢占。
注意:docker-compose 中部署在 swarm 模式下才套用 deploy.resources;如果只是 docker-compose up(非 swarm),deploy 会被忽略。单独使用 Compose 文件(非 swarm)时,应改用 mem_limitcpu_shares 旧语法,但建议直接升级到 swarm 或使用 docker compose 插件(v2 版本),新插件支持 --compatibility 参数将 deploy 降级为 mem_limit。更稳妥的方式是直接用 docker run 配合 --cgroup-parent,或使用 Kubernetes 的 ResourceQuota。

场景三:验证限制是否生效

容器启动后,用 docker stats 实时查看资源占用:

docker stats web_limit

输出会显示 MEM USAGE / LIMIT、CPU % 等,确认限制值与配置一致。

更严谨的方法是进入容器内查看 cgroup:

docker exec -it web_limit /bin/bash
cat /sys/fs/cgroup/memory/memory.limit_in_bytes   # cgroups v1
# 或 cat /sys/fs/cgroup/memory.max                # cgroups v2

输出应为 536870912(512MB)。

避坑指南:别让这些细节让你白忙一场

  • Swap 设置双刃剑:开启 Swap 后容器可能不会立刻 OOM,而是变慢甚至飓风式写入磁盘。如果宿主机 SSD 寿命有限,建议在 Docker daemon 配置文件 /etc/docker/daemon.json 中全局关闭 Swap:
  {
    "swappiness": 0
  }

然后重启 Docker:systemctl restart docker

  • CPU 限制的坑--cpus 限制的是 CPU 时间,不是 CPU 个数。如果宿主机 4 核,--cpus 0.5 意味着容器在 1 秒内最多使用 0.5 秒的 CPU 时间,表现为 CPU 使用率不超过 50%。但多个容器依然可能争抢 L3 cache 或内存带宽,此时需结合 --cpuset-cpus 绑定物理核心。
  • Java 应用的特殊处理:Java 默认根据宿主机内存计算堆大小,即使限制容器内存,JVM 也可能认为有 64GB 可用。务必在容器内设置 -XX:+UseContainerSupport(JDK 8u191+)或手动指定 -Xmx
  • 不要忘记宿主机预留资源:即使所有容器都限制内存,宿主机系统本身、Docker daemon 和其他后台服务也需要内存。建议总容器分配内存 <= 宿主机总内存的 80%,留出 20% 给宿主机和 OOM 缓冲。

高频问题解答

Q1:容器被 OOM kill 后会自动重启吗?
不一定。需要配合 --restart=always--restart=unless-stopped 参数,Docker 才会在容器退出后自动重启。如果资源没有优化,重启后可能再次被 kill,形成循环。建议先分析日志,找到内存泄漏原因。

Q2:如何查看历史内存峰值?
使用 docker stats --no-stream --format 可以输出历史数据,但更推荐挂载监控工具如 Prometheus + cAdvisor。快速查看最近一次 OOM:dmesg | grep -i oom,会显示哪个进程被杀死。

Q3:Kubernetes 也适用同样的限制命令吗?
K8s 通过 Pod 的 resources.limits.memoryresources.limits.cpu 实现类似功能,底层同样基于 cgroups。不过 K8s 还支持 QoS 等级(Guaranteed、Burstable、BestEffort),资源限制更严格且不会影响宿主机其他 Pod。如果长期多容器编排,建议迁移到 K8s。

Q4:我的 Docker 版本太老,不支持 --cpus 怎么办?
Docker 1.13 以上都已支持 --cpus,老版本可以用 --cpu-quota--cpu-period 手动计算。例如 --cpu-quota=50000 --cpu-period=100000 等效于 0.5 核。如果版本过低,建议升级操作系统和 Docker,同时考虑云服务商提供的镜像市场——像泽御云的公共镜像已内置最新 Docker CE。

总结

防止进程抢占内存导致宕机,核心思路是给每个容器设定硬上限并留足宿主机空闲资源
先用 docker run -m 测试单容器,再用 docker-compose 或 K8s 管理多容器。
设置后务必通过 docker stats 和 cgroup 文件验证,并针对 Java 等常见场景做额外优化。
如果你正在寻找一台资源隔离可靠的服务器,选择有 IDC/ISP 资质(如泽御云,证号 B1-20261342)的云服务商可以降低超售风险,但无论在哪跑容器,资源限制这一步都不能跳过。

分享到:
上一篇
swap分区一键扩容根治服务器频繁OOM
下一篇
宝塔自动化脚本一键升级修复Nginx高危漏洞教程
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意