11进阶:日志与磁盘治理

1343 字
7 分钟
11进阶:日志与磁盘治理

第 11 关 日志与磁盘治理#

本关的产出:知道磁盘被谁吃、容器的日志落在哪、怎么给它设上限,以及为什么「清一遍」不等于解决。

11.1 空间被谁吃了#

第 1 关用过 docker system df,现在把它的四行看仔细:

docker system df

分别是 镜像、容器、卷、构建缓存。加 -v 能看到每一项具体是谁:

docker system df -v

第 1 关只到「怎么看、怎么收」。这一关解决两个问题:这些东西是怎么长起来的,以及为什么随手一清治不了根。

11.2 日志:落在哪,能长多大#

先分清两种「日志」——第 1 关提过一次:docker logs 给的是容器里主进程往标准输出(stdout/stderr)写的那点东西,不是 Docker 自己的日志。

这些输出,Docker 会一路接住、存成文件。文件在哪:

docker inspect --format '{{.LogPath}}' <容器>

打出来是 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log。docker logs 读的就是它。

要注意的两点:

  1. 这个路径在「跑 Docker 引擎的那台机器」上,不一定就是你面前这台:Linux 上它就是本机路径,能直接打开(多半要 root);macOS、Windows 上 Docker 跑在虚拟机里,宿主机够不到它。
  2. 默认没有任何上限。 只要容器在往 stdout 写,这个文件就一直长——一个话多的容器,能把磁盘写满。这是「磁盘莫名被吃掉」最常见的一个来源。

要观察:容器一删,这个文件跟着删(它就在容器的目录底下)。所以 docker system prune 清掉一个已停止的容器时,顺带把它那份日志也清了。

11.3 给它设个上限#

不给上限,就只能等它出事。两个地方可以设。

一次性的,写在 run 里:

docker run -d --log-opt max-size=10m --log-opt max-file=3 nginx

max-size 是单个日志文件的上限,max-file 是最多留几个。写满了就轮转——新的进来,最旧的丢掉。

一次设好、全局生效(推荐)。Docker 那个守护进程(第 1 关说的「服务端」)有一份自己的配置文件,叫 daemon.json——它启动时读一遍,里面的设置对所有容器生效。日志上限就写在这儿:

{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}

文件在哪,随平台不同:

  • Linux:/etc/docker/daemon.json,直接编辑;
  • macOS / Windows(Docker Desktop):这文件在它的虚拟机里,不去摸路径——用 Settings → Docker Engine 那个界面改,改的就是同一个文件。

改完重启 Docker 生效。之后每个新容器都自带这套上限。compose 里也可以用 logging: 段设同样两项。

代价要讲清:轮转意味着旧日志会被丢。docker logs 只能看到最后几个文件里的内容。真要长期留,得把日志送到别处(日志系统的活,不在本系列)。

易踩的坑:改 daemon.json 只对新起的容器生效,已经在跑的容器不受影响——要它们也受约束,得重建。

11.4 为什么 prune 治不了根#

docker system prune 清的是:已停止的容器、没在用的网络、悬空镜像、构建缓存。它有两个够不着的地方:

  1. 它不碰正在跑的容器的日志。 日志不在它管的四类里——一个跑着的容器把磁盘写满,prune 一点忙都帮不上。
  2. 清完很快就长回来。 构建缓存会再攒、匿名卷会再造(第 4 关和第 9 关都点过)、日志会再写。

所以 prune 是扫帚,不是堵源头。真要让空间不出事,靠的是前面几关那些源头上的约束:

  • 日志设上限(11.3);
  • .dockerignore 挡掉不该进镜像的东西(第 3 关);
  • RUN 里装完就清、清在同一条指令里(第 9 关);
  • 别随手造匿名卷(第 4 关、第 9 关的 VOLUME)。

错觉:就算清掉了虚拟机里的东西,也不一定立刻还给宿主机。Docker Desktop 那块磁盘镜像(在设置里能看到的那个上限)是只长不缩的。所以 df 里回收了、宿主机的可用空间却没动,别慌——那不是没清掉。

11.5 清一遍#

原则是先看清楚再动手,别上来就一把梭。

docker system df -v

然后按需要、按类清,每一类各有一条:

docker container prune # 已停止的容器
docker image prune # 悬空镜像
docker image prune -a # 没被任何容器引用的镜像(更狠)
docker network prune # 没在用的网络
docker volume prune # 没被使用的卷
docker builder prune # 构建缓存

一把清:

docker system prune # 容器 / 网络 / 悬空镜像 / 构建缓存
docker system prune -a --volumes # 连没用的镜像和卷也清

易踩的坑:这些 prune 都不问你,确认都没有了才跑。-a 和 --volumes 尤其要看清——前者把没在用的镜像全删(下次构建得重新拉底),后者会删掉只是暂时没挂载的卷。

这一关的产出:知道磁盘被谁吃、给日志设了上限、也明白清理是扫帚不是根治。下一关反过来——不是空间出了问题,而是服务起不来、连不上,怎么在十分钟内定位到出错的那一层。

本关命令速查#

系统清理与日志,见 命令速查表 · 系统与清理。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
11进阶:日志与磁盘治理
https://hecloud.top/posts/tech/docker/11日志与磁盘治理/
作者
贺小云
发布于
2026-10-14
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
贺小云
热爱技术与折腾的博客 Dancing with uncertainty. 与不确定性共舞
公告
出于成本考虑,贺云已全面转型Serverless架构
分类
标签
碎碎念
站点统计
文章
91
分类
5
标签
44
总字数
103,192
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Cloudflare Pages
博客版本
Firefly v6.16.5
文章许可
CC BY-NC-SA 4.0