Skip to content

Docker 资源限制与性能 ​

1. 为什么必须限制 ​

Docker 默认通常不限制容器资源,一个异常容器可能耗尽宿主机。限制值必须通过压测和监控确定,不应照抄模板。

bash
docker info
docker stats --no-stream

2. 内存 ​

bash
docker run -d --name api \
  --memory 512m \
  --memory-reservation 384m \
  --memory-swap 768m \
  team-api:latest
  • --memory:硬上限。
  • --memory-reservation:内存争用时的软目标,应低于硬上限。
  • --memory-swap:内存加 swap 的总额度,只有与 --memory 一起才有意义。
  • 将二者设为相同正值可禁用该容器 swap。

不要无内存限制地设置 --oom-kill-disable,这可能拖垮宿主机。

查看 OOM:

bash
docker inspect api \
  --format 'oom={{.State.OOMKilled}} exit={{.State.ExitCode}}'
sudo journalctl -k --since '1 hour ago' | grep -i oom

3. CPU ​

bash
docker run -d --name worker \
  --cpus 1.5 \
  --cpu-shares 512 \
  team-worker:latest
  • --cpus 是硬配额的便捷形式。
  • --cpu-shares 只在争用时表达相对权重,不是保证或上限。

固定核心:

bash
docker run --rm --cpuset-cpus 0-1 stress-image

CPU pinning 会限制调度灵活性,只有在 NUMA、延迟或许可证等明确需求下使用。

4. PID 限制 ​

bash
docker run -d --name api \
  --pids-limit 256 \
  team-api:latest

可减轻 fork bomb。设得太低会阻止线程或子进程创建:

bash
docker stats --no-stream api
docker top api

5. Block I/O ​

相对权重:

bash
docker run -d --blkio-weight 500 io-worker:latest

设备限速:

bash
docker run -d \
  --device-read-bps /dev/nvme0n1:50mb \
  --device-write-bps /dev/nvme0n1:20mb \
  io-worker:latest

设备、存储驱动、cgroup 版本和云盘层都会影响效果。先确认真实设备映射并压测。

6. ulimit ​

bash
docker run -d \
  --ulimit nofile=65536:65536 \
  --ulimit nproc=4096:4096 \
  team-api:latest

检查:

bash
docker exec api sh -c 'ulimit -n; ulimit -u'
docker inspect api --format '{{json .HostConfig.Ulimits}}'

提高 limit 不能修复文件描述符泄漏。

7. Shared memory ​

/dev/shm 默认大小可能不足浏览器、数据库或科学计算:

bash
docker run --rm --shm-size 1g browser-tests:latest

按压测设置;shared memory 仍占内存。

8. GPU ​

需要兼容驱动与 NVIDIA Container Toolkit:

bash
docker run --rm --gpus all \
  nvidia/cuda:TAG nvidia-smi

docker run --rm --gpus '"device=0"' \
  ml-app:latest

镜像 tag、宿主驱动与 CUDA 兼容矩阵必须核对。GPU 权限和多租户隔离需单独评审。

9. 动态更新 ​

bash
docker update \
  --cpus 2 \
  --memory 1g \
  --memory-swap 1g \
  api

变更前观察当前峰值,变更后检查 throttling、OOM、延迟和错误率。长期配置应同步回 Compose/部署清单,避免重建后丢失。

10. 观察 ​

bash
docker stats
docker stats --no-stream \
  --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}'
docker system df -v
docker events --since 10m

容器内 free 看到的 swap 等信息可能来自宿主机,不能完全反映 cgroup 配额。

11. 性能诊断顺序 ​

  1. 应用延迟、吞吐、错误率。
  2. docker stats 的 CPU、内存、PIDs、网络和 I/O。
  3. inspect 的限制是否与配置一致。
  4. 宿主机 load、内存、swap、磁盘延迟、inode、网络丢包。
  5. cgroup throttling/OOM 事件。
  6. 存储、DNS、Registry 或下游服务。

容器 CPU 100% 不一定是问题;若限制为 1 CPU,它可能表示已用满配额。

12. Compose 示例 ​

yaml
services:
  api:
    image: team-api:latest
    cpus: 1.5
    mem_limit: 768m
    mem_reservation: 512m
    pids_limit: 256
    shm_size: 128m
    ulimits:
      nofile:
        soft: 65536
        hard: 65536

使用当前 Compose config 验证字段确实生效,并用 docker inspect 核对运行态。

13. 官方参考 ​

继续阅读