bigywater.tech
Docker · 71

json-file 日志:没有轮转时磁盘怎么被写满

容器的日志存在哪里、什么格式、会不会无限增长?Docker Desktop 的默认日志驱动和常见文档里的 json-file 不一样。这篇逐项实测 local 和 json-file 的文件、格式、拆分与轮转。

local 不是 json-file
Docker Desktop 的 daemon.json 把默认日志驱动设成了 local,日志文件是二进制
16384 字节
json-file 单条记录的字节上限:40000 个字符被拆成 16384 + 16384 + 7233
209 / 1000 行
max-size=10k max-file=3 轮转后 docker logs 剩下的行数,对比不设上限的 1000 行

默认是 local

实测 · 本机执行输出
  docker info 的 Logging Driver = local
  虚拟机里 daemon.json 的日志配置:"log-driver":"local","log-format":"json",
  HostConfig.LogConfig = {"Type":"local","Config":{}};LogPath = ''(local 驱动没有 LogPath)
  容器目录下的日志相关文件:local-logs/container.log
  local 日志文件的前 48 个字节(十六进制):00 00 00 1c 0a 06 73 74 64 6f 75 74 10 b9 a8 ef bb 92 cf cb ee 18 1a 08 6c 69 6e 65 2d 6f 6e 65 00 00 00 1c 00 00 00 1c 0a 06 73 74 64 65 72 72(不是 JSON 文本)
  docker logs 仍然能读:line-one ⏎ err-line

很多文章说默认的日志文件是 <容器ID>-json.log,但在 Docker Desktop 里默认驱动是 local,日志在 local-logs/container.log,是二进制格式,docker logs 能正常读取。Linux 宿主机 Docker 的默认驱动是 json-file,这是我的了解,没有在 Linux 上验证。

json-file 的格式

实测 · 本机执行输出
  LogPath = /var/lib/docker/containers/<容器ID>/<容器ID>-json.log
    {"log":"line-one\n","stream":"stdout","time":"2026-10-10T13:35:27.306116551Z"}
    {"log":"err-line\n","stream":"stderr","time":"2026-10-10T13:35:27.306182301Z"}
  docker logs 的输出:line-one ⏎ err-line

显式 --log-driver json-file 后,日志是每行一条 JSON:log(内容,带换行)、stream(stdout 或 stderr)、time。

长行

实测 · 本机执行输出
  输出 1 行 40000 个字符:日志文件里有 3 条记录;每条 log 字段的长度 [16384, 16384, 7233]
  docker logs 读出来是 1 行

一行 40000 个字符被拆成 3 条记录(16384、16384、7233),docker logs 读出来再拼成一行。

轮转

实测 · 本机执行输出
  max-size=10k max-file=3,日志目录里的文件:6477 <ID>-json.log ; 10033 <ID>-json.log.1 ; 10033 <ID>-json.log.2 ; 3086 config.v2.json ; 1512 hostconfig.json
  脚本一共输出 1000 行;docker logs 能读到 209 行,第一行是「line 791 pad」,最后一行是「line 999 pad」
  对比:json-file 不设 --log-opt(默认没有上限)日志文件:126890 <ID>-json.log ; 3086 config.v2.json ; 1481 hostconfig.json;docker logs 读到 1000 行

json-file 默认不限制大小,一个只输出 1000 行的小脚本就有 126890 字节;设置 max-size 与 max-file 后轮转成 .1、.2 文件,docker logs 只能读到保留下来的部分(209 行)。local 驱动的默认轮转限制我没有测。

删除

实测 · 本机执行输出
  docker rm -f 之后容器目录还在吗?已删除

容器一删,日志目录就没了,要保留日志得用日志驱动转发到别处(见下一篇)。

分步演示

容器日志文件
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。日志文件取自虚拟机里 /var/lib/docker/containers/<容器ID>/(特权容器加 nsenter 只读读取,方法见 c19);local 驱动只看了文件头的十六进制;轮转实验输出 1000 行(每行约 60 字节);每种情形运行一次;实验后已删除容器
    • 没有验证:local 驱动的默认轮转(max-size / max-file / compress)、日志文件里部分行(partial)的标记、无换行输出在进程退出后是否写出、日志文件被外部截断的行为、Linux 宿主机默认值
    京ICP备2026067502号-1京公网安备11010502063487号