⚙️ 资源限制
为什么要限制资源?
一个容器如果不加限制,可以吃光你所有的 CPU 和内存。想象一下:你的 MySQL 容器跑了个全表扫描,直接把宿主机的内存吃满了,结果 Nginx 也被 OOM Kill——整个服务全挂。
资源限制就是给每个容器装上"限速器",防止单个容器拖垮整台机器。
CPU 限制
bash
# --cpus:限制最多使用 1.5 个 CPU 核心
docker run -d --cpus=1.5 myapp
# --cpu-shares:按比例分配 CPU(默认 1024)
docker run -d --cpu-shares=512 light-task # 低优先级
docker run -d --cpu-shares=2048 heavy-task # 高优先级(4倍权重)
# --cpuset-cpus:绑定到特定 CPU 核心
docker run -d --cpuset-cpus="0,1" myapp # 只用第 0 和 1 核
# 查看容器的 CPU 使用率
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
NAME CPU % MEM USAGE / LIMIT
nginx 0.50% 12.3MiB / 512MiB
mysql 45.20% 1.2GiB / 2GiB
redis 0.10% 3.8MiB / 128MiB内存限制
bash
# 限制最多使用 512MB 内存
docker run -d --memory=512m myapp
# 同时设置软限制和硬限制(软限制超过后会触发 GC,硬限制会 OOM Kill)
docker run -d --memory=512m --memory-swap=1g myapp
# memory-swap = memory + swap,所以 swap 分配了 512m
# 禁止使用 swap(memory-swap 与 memory 相同)
docker run -d --memory=512m --memory-swap=512m myapp
# ⚠️ 不要随意加 --oom-kill-disable:内存不够时不会杀容器,可能拖垮宿主机
# 查看 OOM 事件
docker inspect --format='{{.State.OOMKilled}}' myapp
false
# 查看容器内存使用
docker stats --no-stream myapp
NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
myapp 2.30% 256MiB / 512MiB 50.00% 1.2MB / 800kB 0B / 0B⚠️ 注意: ⚠️ 经验教训:Java 应用特别容易 OOM。给 Java 容器设
--memory时,记得同时在应用里设-Xmx或使用支持容器感知的 JVM 参数,否则 JVM 可能申请超过容器限制的内存。
磁盘 IO 和重启策略
bash
# 限制磁盘写入速率(10MB/s 读,5MB/s 写)
docker run -d --device-read-bps=/dev/sda:10mb --device-write-bps=/dev/sda:5mb myapp
# 重启策略(总是、失败时、除非手动停止)
docker run -d --restart=always myapp # 崩溃自动重启
docker run -d --restart=unless-stopped myapp # 除非手动 stop,否则自动重启
docker run -d --restart=on-failure:5 myapp # 最多重启 5 次
# 在 docker-compose.yml 中配置资源限制(本地 docker compose)
cat > docker-compose.yml << 'EOF'
services:
web:
image: nginx:alpine
cpus: "1.0"
mem_limit: 256m
mem_reservation: 128m
restart: unless-stopped
api:
build: ./api
cpus: "2.0"
mem_limit: 1g
restart: unless-stopped
EOF💡 提示:
deploy.resources主要用于 Swarm/stack 部署;本地docker compose up更推荐直接使用cpus、mem_limit、mem_reservation。如果你的 Compose 版本支持deploy.resources,也要先在目标环境验证限制是否真的生效。