凌晨值班时,100GB 系统盘从 35% 很快涨到 98%:容器每分钟输出数万行 JSON,重启后日志目录却多出几十 GB,镜像拉取随即失败。手工删日志只能拖延,因为 stdout采集链路仍在写入。真正要查的是日志从哪里来、被谁写,以及轮转和清理为何失效。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:richproxies(海外服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
一、日志膨胀发生在链路哪一段
典型路径是:进程把 stdout、stderr 交给容器运行时,日志驱动落到节点目录,再经过日志轮转机制、压缩和保留清理。应用产生日志,却不等于直接占满磁盘。采集代理重试、重复写入、轮转后未重开文件或压缩失败,都会让目录持续增长。多节点叠加副本数、调试级别和保留天数,十几 MB 的单应用也可能堆出数十 GB。

还要区分“文件消失”和“空间释放”。日志已删除但进程仍持有句柄时,目录里看不到文件,df 却显示容量不降;这是句柄泄漏。大量小文件还可能先耗尽 inode,导致镜像解压和配置写入失败。用随身服务器巡检小环境时,也要分开核算宿主机与容器日志,避免把系统日志误判为应用输出。
二、用四组证据定位写入源头
判断时做四组交叉检查:用 du 找占空间目录,用 df -h、df -i 区分容量与 inode 压力,用 lsof +L1 查已删除但仍打开的文件,再按分钟观察谁还在增长。若 du 很低而 df 很高,优先查开放句柄;若 inode 已满,查轮转残留;若单文件持续长高,查轮转信号、代理重试和写入目标。

然后验证JSON日志解析与轮转是否同链路工作。抽取最近文件逐行解析,统计失败行、时间跨度和字段长度;解析器若反复保存原始内容,增长可能快于业务输出。轮转要确认新文件是否生成、信号是否送达、代理是否重开句柄;压缩要检查退出码;保留则确认日志保留周期确实执行,而非只配置“最大文件数”。
常见坑包括:轮转与复制同时读取造成空间峰值,删除后不查开放句柄,压缩失败却仍被当作清理成功,以及只看总目录不看 inode。闭环验证要记录写入速率、轮转成功率、压缩失败数、保留积压量和磁盘水位告警触发时间,才能判断增长来自业务、采集异常还是清理失效。
轮转之后,为什么日志仍会增长
容器日志“删了却还在涨”,往往不是轮转失效,而是生成、缓存、落盘叠加。应用若既写容器内文件又输出 stdout,节点只采集标准输出,文件仍占盘;若只写文件,风险只是转移到业务卷。
轮转参数随运行方式变化。Docker 的 json-file 驱动可用 max-size、max-file 控制;Kubernetes 通常由 kubelet 依据 containerLogMaxSize、containerLogMaxFiles 管理。修改前必须确认运行时与驱动,不能把 Docker 参数套到 containerd 或 CRI-O。
常见坑是重复采集:节点代理与应用内 sidecar 同时转发同一份日志;轮转后旧 inode 仍被读取,新文件却未打开。copytruncate 还可能让采集器读到半行,应采用“改名后新建”并验证 reopen 行为。
JSON 日志解析要求一行一个完整对象。美化后的多行 JSON、混入堆栈或 ANSI 控制字符,都会使解析失败;若代理无限重试,本地缓存便会膨胀。应设置有界队列和丢弃策略,并暴露失败数、重试数。

从保留策略到磁盘水位治理
排查 stdout 链路要逐段核对:应用是否因管道背压阻塞,节点代理是否落缓存,中心端是否限流,索引与对象存储是否积压。日志可见只能证明 stdout 正常;应关联写入速率、缓存占用、发送队列和入库延迟。
日志保留周期不能只看磁盘容量。审计日志按合规期限保存,调试日志可缩短;删除要覆盖节点缓存、中心索引和对象存储。只设置 max-file 不等于按天删除,残留副本仍会占用空间。
磁盘告警应同时使用百分比水位与绝对剩余空间,并按写入速率预测耗尽时间。为 warn、critical 配置分级阈值和值班动作,追踪日志盘配额;先定位增长源,再限速非关键日志并记录丢弃量。
可执行检查清单:①确认运行时、驱动及实际生效参数;②在所有节点核对容器日志目录、代理缓存目录和可写层,找出重复文件与增长 Top;③抽样验证每行均为合法 JSON,检查多行堆栈、ANSI 字符、解析失败和重试队列;④沿“应用→stdout→节点代理→网络→中心平台”测速并确认背压;⑤按日志类型制定保留周期,演练过期删除;⑥配置日志盘百分比、剩余空间、预计耗尽时间三类告警,并验证通知、处置和回滚。


喜欢
顶
难过
囧
围观
无聊





