先看现象。Ubuntu 22.04 上跑 docker 24.0,一个 golang 服务把日志打到 stdout,容器日志一夜涨到 48G,根分区写满,应用开始报 no space left on device,docker info 里 logging driver 是 json-file。
真正麻烦的地方在于,几个原因的现象几乎一样。json-file 驱动默认不轮转,日志文件只追加不切分。另一种情况是compose 文件里没写 logging.options 的 max-size 和 max-file。
还有一种情况,daemon.json 只配了 log-driver 没配 log-opts,对已有容器不起作用。
另外,应用把整段请求体打进 stdout,单条日志就有几十 K。
上来先找出占空间最大的容器日志
du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail -5
随后清空当前日志把空间先放出来
truncate -s 0 /var/lib/docker/containers/*/*-json.log
再往下在 daemon.json 里加全局轮转
printf '%s
' '{"log-driver":"json-file","log-opts":{"max-size":"100m","max-file":"3"}}' > /etc/docker/daemon.json
剩下的就是重启 daemon 并核对新容器配置
systemctl restart docker && docker inspect --format '{{.HostConfig.LogConfig}}' app
报错是间歇性的,我蹲守了半小时才抓到一次完整现场。
恢复的判定其实很直接。df -h / 的占用回落到六成,新容器日志到 100M 就切,历史文件最多保留三份。
补一句。轮转配置只对新建容器生效,老容器必须重建;应用侧同样要限流,单条几十 K 的日志再多轮转也顶不住。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
