在 Docker Compose 中,通过 mem_limit 设置 512M 内存上限和 cpus 设置 1.5 个 CPU 核心,可有效防止容器占用过多宿主机资源导致 OOM Kill。
原因分析
Docker 容器默认没有资源限制,可以使用系统所有资源。如果不设置内存限制,容器会消耗宿主机最大内存直至触发 OOM(Out-of-Memory)异常,系统会开始杀死进程释放内存,包括 Dockerd 和其他应用程序。根据 2024 年 9 月 3 日的资料,对于 Linux 主机,如果重要系统进程被 Kill,会导致整个系统宕机。资源限制依赖 Linux 内核的 Cgroups(Control Groups)技术实现,通过 cgroups v2 中的 memory.max 接口写入字节数值来设置内存上限,例如 echo "536870912" > /sys/fs/cgroup/mygroup/memory.max 可将内存限制为 512MB(2025 年 11 月 20 日资料)。
解决方案:Docker Compose 内存限制配置
在 Docker Compose 文件中,内存限制有两种配置方式。对于单机 Compose 环境,应使用顶级 mem_limit 字段:version: '3.8',services: app: image: myimage,mem_limit: 512M。对于 Docker Swarm 集群模式,应使用 deploy.resources.limits:deploy: resources: limits: memory: 500M。还可以设置内存软限制--memory-reservation 256m,当宿主机内存紧张时容器优先被回收到该阈值。同时可配置--memory-swap 设置内存 +Swap 总限制,默认等于-m 的 2 倍,例如-m 512m --memory-swap 512m 表示不允许使用 Swap。
解决方案:Docker Compose CPU 限制配置
CPU 限制推荐使用--cpus 参数直接限制核心数,支持小数,例如 cpus: '1.5' 表示最多使用 1.5 个 CPU 核心。另一种方式是使用--cpu-shares 设置相对权重,默认值为 1024,例如--cpu-shares 512 表示权重减半。根据 2024 年 5 月 7 日资料,--cpu-period 参数指定容器对 CPU 使用的分配周期,最小值为 1000,最大值为 1000000,默认值为 100000 微秒;--cpu-quota 指定在该周期内进程最多可使用的 CPU 时间,例如--cpu-period 1000000 --cpu-quota 100000 表示 1 秒内容器使用 CPU 最长为 0.1 秒。在 Compose 文件中配置为:cpus: '1.5' 或 deploy: resources: limits: cpus: '1.5'(Swarm 模式)。
注意事项
第一,deploy.resources 仅在使用 Docker Swarm 模式时生效,若在普通 Docker Compose 运行环境中应改用顶级 mem_limit 和 cpus 字段,否则配置不生效。第二,设置资源限制时应考虑容器实际需求,避免设置过小导致容器无法正常运行,例如内存限制过小会触发 OOM Killed,容器状态变为 Exited。第三,执行 docker info 命令检查内核支持,如果禁用某项功能会看到警告如"WARNING: No swap limit support"。第四,--cpu-shares 只在 CPU 资源紧张时生效,当系统中只有一个容器运行时该参数配置没有意义。第五,对于存储限制,在 devicemapper 存储驱动下可通过 dm.basesize=20G 限制容器大小为 20GB,需定期监控磁盘使用情况。
参考来源
来源:阿里云开发者社区 - 配置 Docker 容器的 CPU 内存与磁盘 IO 资源限制(2023 年 10 月 31 日)
来源:Docker 官方文档 - Docker Compose 资源限制概述(2024 年 5 月 17 日)
来源:技术博客 - Docker 详解 CPU 资源限额配置(2024 年 5 月 7 日)
来源:Linux 内核文档 - cgroups v2 memory.max 配置示例(2025 年 11 月 20 日)
原文链接:https://www.zjcp.cc/ask/9747.html
