报错的两类原因
容器相关写入报 no space left on device 时,先分清是空间不足还是 inode 耗尽:df -h 看容量,df -i 看 inode 数量。确认类型后从 /var/lib/docker 逐层下钻,用 du 找出究竟是容器日志、镜像层、构建缓存还是数据卷占了空间,再按类型选择对应的清理手段。
基本信息
| 容量检查 | df -h /var/lib/docker |
|---|---|
| inode 检查 | df -i /var/lib/docker |
| 下钻方式 | du -x --max-depth=1 逐层定位 |
| 常见占用源 | 容器日志、悬空镜像、构建缓存、未使用卷 |
| 适用平台 | Linux 宿主 |
典型使用场景
- 服务突然写不进文件,日志报 no space left
- 数据库容器异常退出,排查发现宿主磁盘已满
- 部署新镜像失败,本地磁盘没有空间解压层
- 巡检发现宿主磁盘长期高水位,需要定位大头
- df -h 还有余量却创建文件失败,实际是 inode 耗尽
定位与清理
定位与清理
df -h /var/lib/docker; df -i /var/lib/docker # 容量与 inode 一起看
sudo du -x --max-depth=1 /var/lib/docker | sort -h | tail -8
sudo du -sh /var/lib/docker/overlay2 /var/lib/docker/volumes /var/lib/docker/containers 2>/dev/null
du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -h | tail -5 # 定位大日志
truncate -s 0 /var/lib/docker/containers/<id>/<id>-json.log # 已写大的日志用清空方式回收占用源与清理手段
| 占用源 | 典型路径 | 清理手段 |
|---|---|---|
| 容器日志 | containers/<id>/*-json.log | 配置轮转参数,存量文件用 truncate 清空 |
| 镜像层 | overlay2/ | 删除不用的镜像与悬空镜像 |
| 构建缓存 | builder 相关目录 | docker builder prune |
| 数据卷 | volumes/ | 确认无业务数据的卷再执行 volume prune |
定位到来源之后再动手:日志问题用轮转参数根治,镜像问题用清理命令回收,卷问题要先确认没有需要保留的数据。
直接删除正在写入的日志文件不会立即释放空间,进程仍持有文件句柄,用 truncate 清空内容才会真正回收。
按来源选择清理手段
- 容器日志:daemon.json 或运行参数加 max-size 与 max-file,存量文件用 truncate
- 悬空镜像与未使用镜像:docker image prune 带时间过滤清理
- 构建缓存:docker builder prune,按保留时间控制
- 未使用的数据卷:先列清单确认没有业务数据,再做 volume prune
- 根因治理:把日志轮转与定期清理做成计划任务,避免重复告警
长期方案是给宿主的分区容量与 inode 使用率分别配置监控告警,并在阈值上留出清理动作的时间窗口。