已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
背景
12 节点集群(16C64G,Kubernetes 1.28.9,containerd 1.7.13,内核 5.15),日志链路是:业务容器 stdout 走 containerd 的 json-file 驱动(--log-opt max-size=10m --log-opt max-file=3),容器内应用文件日志由 otel-collector(filelog receiver)tail 采集,最终落 Loki。我们没跑 filebeat,纯 otel 采集。
现象
一次支付超时故障复盘时,后端(Loki)能查到故障前后各约 1 分钟的日志,但中间 40 秒是断的。而同一时段 kubectl logs、crictl logs、节点上 cat 原始 json 文件都能完整看到那 40 秒的日志——说明日志确实写出来了,是采集侧丢了,不是应用没打。
已尝试的排查
kubectl describe pod 无 OOMKill,otel 副本资源充足,无重启记录。max-size 触发点,节点 docker/ctr 日志目录能看到 xxx.json 被 rename 成 xxx.json.1、同时生成新的 xxx.json。cat /proc/sys/fs/inotify/max_user_watches 是默认 8192,节点容器多,怀疑逼近上限,但没拿到"watch 耗尽"的坐实证据。卡点 我基本判断是 rotate 产生新 inode,而 otel 的 file tail 没对新文件重新建立 watch,导致新写入的日志漏采。但 otel filelog 和 filebeat 的 reopen 机制不一样(filebeat 有明确的 registry + inotify 重挂),我没吃透 otel 这边的实现,也没法定位到具体是哪一环没跟上。
期望得到的答案形态
poll_interval / 相关配置项是多少、默认值是什么?max-size/max-file、改 otel 的 start_at/flush 配置,还是干脆换 node agent(filebeat)?各自的取舍?想听听大家生产里踩过的坑,以及你们最终是靠 otel 配置兜住,还是回到了 filebeat。