在生产环境中,建议通过 Docker 启动参数或 Compose 文件明确限制容器的 CPU 和内存上限,防止单个容器占用过多宿主机资源导致其他服务不可用。
先说结论:配置资源限制是生产环境的标准动作,但需要基于实际业务压力测试设定数值。
- 适合:多租户共享宿主机、防止内存泄漏拖垮主机、需要保障关键服务资源的场景。
- 先准备:通过监控工具观察容器正常运行时的资源水位,预留一定缓冲空间。
- 验收:限制生效后观察业务日志是否有 OOM Kill 记录,确认服务响应时间无明显抖动。
快速命令
如果你需要快速给容器加上限制,可以直接在启动或运行中使用以下参数。注意参数前不要加多余符号,确保可直接复制执行。
# 启动新容器时限制内存为 512MB,CPU 为 1.5 核
docker run -d `--memory`="512m" `--cpus`="1.5" nginx
# 对正在运行的容器动态调整限制
docker update `--memory`="1g" `--cpus`="2" <container_id>Compose 配置示例
Docker Compose 配置需注意模式差异,deploy 字段仅在 Swarm 模式下生效,普通 standalone 模式请使用服务层级配置。
1. 普通 Standalone 模式(推荐本地及单机使用)
services:
web:
image: nginx
mem_limit: 512m
cpus: 1.52. Swarm 模式
services:
web:
image: nginx
deploy:
resources:
limits:
cpus: '1.5'
memory: 512M原理简述
Docker 容器默认情况下可以占用宿主机所有可用的 CPU 和内存。如果某个容器出现内存泄漏或死循环,可能会耗尽宿主机资源,导致其他容器甚至宿主机本身无响应。
底层原理上,Docker 依赖 Linux 内核的 Cgroups(控制组)功能来实现资源隔离和限制。设置内存限制后,容器进程使用的内存超过阈值会被内核触发 OOM Kill 机制终止;设置 CPU 限制后,容器在指定时间片内只能使用指定比例的 CPU 时间,超出部分会被节流(Throttling)。
操作步骤
1. 观察基线水位
在设置限制前,先让容器在正常业务负载下运行一段时间,使用以下命令观察资源使用情况:
docker stats `--no-stream`记录 CPU 和 MEM 的平均使用值及峰值。
2. 设定限制值
根据观察到的峰值,增加 20%-30% 的缓冲空间作为限制值。如果不确定,可以先设置一个较宽松的值,再逐步收紧。
修改启动命令或 Compose 文件,加入 `--memory` 和 `--cpus` 参数。
3. 应用配置
对于新容器,直接使用带限制的启动命令。对于已运行的容器,使用 docker update 命令生效,无需重启服务。
验证方法
1. 实时查看
使用 docker stats 观察容器,MEM 使用量不应超过设定值。如果接近限制值,容器可能会频繁重启。
2. inspect 检查
通过以下命令查看容器底层配置,确认 HostConfig 中的 Memory 和 NanoCpus 字段已更新:
docker inspect <container_id> | grep -A 5 HostConfig3. 检查系统日志
如果内存限制过紧,容器进程可能被系统杀死。查看宿主机内核日志确认是否有 OOM 记录:
dmesg | grep -i "out of memory"常见风险
1. 内存限制过低导致频繁重启
Java 等依赖 JVM 的应用,堆内存设置需要小于容器内存限制,否则 JVM 可能认为可用内存多于容器限制,导致超出容器限制被 Kill。建议 JVM 堆内存设置为容器内存限制的 70%-80%。
2. CPU 限制是节流而非预留
限制 CPU 为 1.5 核并不意味着容器总能用到 1.5 核,而是上限。如果宿主机负载高,容器可能只能用到更少。如果需要保障最低 CPU 用量,需要配置 CPU 权重(cpu-shares),但这不保证绝对资源。
3. Swap 交换分区的影响
默认情况下,Docker 允许容器使用部分 Swap 内存。如果需要严格限制物理内存,需要同时设置 `--memory-swap` 等于 `--memory` 的值,禁止使用 Swap。
4. 取消限制的注意事项
若需取消限制,较稳妥的方式是重新创建容器。部分版本支持 docker update `--memory`=-1 解除内存限制,但 CPU 限制解除行为因版本而异(`--cpus`=0 不一定代表无限制),建议查阅当前版本文档或重建容器以确保配置干净。
参考来源
- Docker 官方文档 - Docker run reference
- Docker 官方文档 - Compose file reference