Docker Compose 如何限制容器内存和 CPU 资源部署配置

文章导读
在 Docker Compose 中限制资源,最稳妥的方式是根据是否使用 Swarm 模式选择配置字段:普通 compose up 使用顶层 cpus 和 mem_limit,Swarm 模式使用 deploy.resources,避免配置无效导致容器失控。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

在 Docker Compose 中限制资源,最稳妥的方式是根据是否使用 Swarm 模式选择配置字段:普通 compose up 使用顶层 cpus 和 mem_limit,Swarm 模式使用 deploy.resources,避免配置无效导致容器失控。

先说结论:配置方式取决于编排模式,非 Swarm 环境直接用顶层字段最可靠,生产环境务必设置内存硬限制防止宿主机崩溃。

  • 适合:多容器共存、防止单服务耗尽主机资源、需要资源隔离的场景
  • 先准备:确认 Docker 是否运行在 Swarm 模式,统计宿主机可用物理内存
  • 验收:启动后通过 docker stats 观察实际占用,确认未触发 OOM Kill

命令速用版

直接编辑 docker-compose.yml,根据环境选择以下两种写法之一:

方案 A:普通 Compose 环境(推荐大多数用户)

version: '3.8'
services:
  web:
    image: nginx:alpine
    cpus: '0.5'
    mem_limit: 512m
    mem_reservation: 256m

方案 B:Docker Swarm 模式

version: '3.8'
services:
  web:
    image: nginx:alpine
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          memory: 256M

为什么会这样

Docker 依赖 Linux 内核的 cgroups 技术实现资源隔离。如果不加限制,单个容器可能因代码缺陷或突发流量耗尽宿主机内存,触发内核的 OOM Killer 机制,导致宿主机上其他关键进程被随机杀死。设置硬限制(mem_limit)相当于给容器加了保险丝,超过阈值直接终止容器,保护宿主机安全。CPU 限制则是通过时间片配额(CFS)防止单服务占满核心,影响其他服务响应。

分步处理

1. 确认运行模式
执行 docker info | grep Swarm 查看模式。若 Swarm 为 inactive,请使用方案 A;若为 active,方案 A 和 B 均可,但方案 B 更贴合调度器。

2. 计算合理阈值
内存限制建议设置为物理内存的 1/4 到 1/2 之间,预留部分给系统缓冲。CPU 核数不要超过宿主机实际核心总数。

3. 编写配置文件
根据第一步的选择,将对应的配置片段写入 docker-compose.yml 的服务层级下。注意单位书写,内存支持 m、g 后缀,CPU 支持小数。

Docker Compose 如何限制容器内存和 CPU 资源部署配置

4. 重启服务
执行 docker-compose up -d 或 docker stack deploy 应用配置。若修改了现有服务,可能需要先 down 再 up。

怎么验证是否生效

1. 实时观察
运行 docker stats 命令,观察 CPU% 和 MEM USAGE 列。尝试在容器内制造负载,看数值是否被限制在设定值附近。

2. inspect 检查
运行 docker inspect <容器 ID>,查找 HostConfig 下的 Memory 和 NanoCpus 字段,确认数值与配置一致。

3. 查看日志
若配置过小,容器可能频繁重启。运行 docker logs <容器 ID> 查看是否有 OOMKilled 相关记录。

常见坑

1. deploy 字段在普通模式无效
很多文档默认展示 deploy.resources 写法,但在非 Swarm 模式下执行 docker-compose up 时,该字段会被忽略,导致限制不生效。

2. 内存单位混淆
配置中 m 与 M 通常通用,但建议统一小写或大写。某些版本对 b/kib/mib/gib 支持不同,使用 m 或 g 兼容性更好。

3. 忽略 Swap 影响
默认情况下容器可能使用 Swap。若需严格限制,需配合 memswap_limit 设置,否则内存限制可能因交换空间而变得不精确。

4. 限制过严导致启动失败
Java 等应用启动时需要较多内存,若 mem_limit 小于启动峰值,容器会直接退出。建议先宽松限制,监控后再收紧。

参考来源

  • Docker Compose 资源配额管理实现限制容器 CPU 与内存使用
  • 揭秘 Docker Compose 服务资源瓶颈:如何通过 deploy 精准限制 CPU 与内存-CSDN 博客
  • 如何用 Docker Compose 限制容器只使用 2 核 CPU 和 4GB 内存?详细配置教程
  • Docker 容器如何实现资源限制 (如 CPU 和内存)?