0%

Docker 容器日志把磁盘写满时怎么找、怎么截断

磁盘告警先确认是不是容器日志。默认的 json-file 驱动会把标准输出写到 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log,这个文件会一直长,直到把分区写满。

先看 Docker 用的日志驱动,再看磁盘:

1
2
3
docker info --format '{{.LoggingDriver}}'
df -h / /var/lib/docker
docker system df

LoggingDriver 是 json-file 时,日志在上面那个目录里。是 journald 时,日志在 journal 里,用 journalctl 按容器查,下面的截断步骤不适用。

docker system df 里的 Containers 一行如果很大,多半就是这些 json 日志。镜像和卷另算,不要一上来 docker system prune -a,那会删掉没在跑的镜像。

找出最大的日志

1
sudo find /var/lib/docker/containers -name '*-json.log' -printf '%s %p\n' | sort -n | tail

左边是字节数。目录名是完整容器 ID。对照名字:

1
docker ps -a --no-trunc --format '{{.ID}} {{.Names}}'

或者直接问这个容器的日志路径:

1
docker inspect --format '{{.Name}} {{.LogPath}}' 容器名

截断正在写的日志

容器还在跑时,不要 rm 这个文件。进程拿着已删除的 inode,空间不会还回来,新日志也写不进原路径。把文件截成 0,文件还在,句柄也还在:

1
sudo truncate -s 0 /var/lib/docker/containers/容器ID/容器ID-json.log

截断会丢掉这份日志。需要留档就先 cp 到别的盘。

限制以后的大小

/etc/docker/daemon.json 已有内容时,只补日志相关的键,不要整文件覆盖:

1
2
3
4
5
6
7
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}

然后:

1
sudo systemctl restart docker

重启 Docker 会让没有重启策略的容器停住。而且这个配置只对新建的容器生效。已经在跑的容器要重建之后才会按 max-size 滚动,截断解决的是这一次的磁盘。