最常用、最可靠的方式是用--device-read-bps和--device-write-bps参数,基于cgroup blkio在块设备层硬性节流,需指定宿主机真实块设备路径(如/dev/sda),单位支持b/k/m/g(m为mb),可多设备叠加设置,且读写限速可独立配置。

直接用 --device-read-bps 和 --device-write-bps 参数,是最常用、最可靠的方式。它不依赖应用层逻辑,而是由内核 cgroup blkio 子系统在块设备层面硬性节流,只要设备路径对、参数写对,限速就生效。
找准宿主机真实块设备路径
容器里看到的 /data 或 /var/lib/docker 不是设备本身,得查它背后挂的是哪块物理盘:
- 进容器执行
df -h /data,看“Filesystem”列(比如/dev/nvme0n1p2) - 在宿主机运行
lsblk或findmnt -D /var/lib/docker,确认该路径是否对应真实盘(如/dev/sda、/dev/nvme0n1) - 避免用虚拟设备(如
/dev/loop*)、LVM 逻辑卷名或挂载点路径——cgroup 只认主次号匹配的真实块设备
启动时设置读写速率上限
单位支持 b/k/m/g(大小写敏感,m 表示 MB,不是 MiB):
-
--device-write-bps=/dev/sda:3mb→ 向/dev/sda写入不超过 3 MB/s -
--device-read-bps=/dev/sda:10mb --device-write-bps=/dev/sda:2mb→ 读快写慢,适合日志类服务 - 可叠加多个设备:
--device-write-bps=/dev/sda:2mb --device-write-bps=/dev/sdb:1mb - 注意:同一设备上不能同时设
read-bps和read-iops,后者会被静默忽略
验证限速是否真正起作用
别只看命令有没有加,要实测:
- 进容器,用
dd绕过缓存直写设备:dd if=/dev/zero of=/data/test.bin bs=4M count=50 oflag=direct - 观察输出末尾的
X MB/s是否稳定在设定值附近 - 同时在宿主机跑
iostat -x 1,检查对应设备的wkB/s(写)或rkB/s(读)是否被压在目标带宽内 - 更底层可查:
cat /sys/fs/cgroup/blkio/docker//blkio.throttle.io_service_bytes,有Throttled统计即表示节流已触发
配合日志截断,防磁盘空间耗尽
IO 限速管的是吞吐压力,但日志文件无限增长会直接撑爆磁盘:
- 全局配置
/etc/docker/daemon.json:{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } } - 执行
systemctl restart docker(仅新容器生效) - 紧急清理旧日志:
find /var/lib/docker/containers/ -name "*.log" -size +100M -delete
不复杂但容易忽略











