Docker 限制容器 CPU 和内存使用率怎么配置?

文章导读
在生产环境中,建议通过 Docker 启动参数或 Compose 文件明确限制容器的 CPU 和内存上限,防止单个容器占用过多宿主机资源导致其他服务不可用。
📋 目录
  1. 快速命令
  2. Compose 配置示例
  3. 原理简述
  4. 操作步骤
  5. 验证方法
  6. 常见风险
  7. 参考来源
A A

在生产环境中,建议通过 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.5

2. Swarm 模式

services:
  web:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '1.5'
          memory: 512M

原理简述

Docker 容器默认情况下可以占用宿主机所有可用的 CPU 和内存。如果某个容器出现内存泄漏或死循环,可能会耗尽宿主机资源,导致其他容器甚至宿主机本身无响应。

底层原理上,Docker 依赖 Linux 内核的 Cgroups(控制组)功能来实现资源隔离和限制。设置内存限制后,容器进程使用的内存超过阈值会被内核触发 OOM Kill 机制终止;设置 CPU 限制后,容器在指定时间片内只能使用指定比例的 CPU 时间,超出部分会被节流(Throttling)。

Docker 限制容器 CPU 和内存使用率怎么配置?

操作步骤

1. 观察基线水位

在设置限制前,先让容器在正常业务负载下运行一段时间,使用以下命令观察资源使用情况:

docker stats `--no-stream`

记录 CPU 和 MEM 的平均使用值及峰值。

2. 设定限制值

根据观察到的峰值,增加 20%-30% 的缓冲空间作为限制值。如果不确定,可以先设置一个较宽松的值,再逐步收紧。

修改启动命令或 Compose 文件,加入 `--memory``--cpus` 参数。

3. 应用配置

对于新容器,直接使用带限制的启动命令。对于已运行的容器,使用 docker update 命令生效,无需重启服务。

Docker 限制容器 CPU 和内存使用率怎么配置?

验证方法

1. 实时查看

使用 docker stats 观察容器,MEM 使用量不应超过设定值。如果接近限制值,容器可能会频繁重启。

2. inspect 检查

通过以下命令查看容器底层配置,确认 HostConfig 中的 Memory 和 NanoCpus 字段已更新:

docker inspect <container_id> | grep -A 5 HostConfig

3. 检查系统日志

如果内存限制过紧,容器进程可能被系统杀死。查看宿主机内核日志确认是否有 OOM 记录:

dmesg | grep -i "out of memory"

常见风险

1. 内存限制过低导致频繁重启

Docker 限制容器 CPU 和内存使用率怎么配置?

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