容器日志必须统一采集至中心系统,禁用json-file驱动,强制输出到stdout/stderr,用Fluentd/Promtail开启JSON解析与元数据注入,Loki+Promtail组合以标签索引实现低成本高效率日志管理。

容器日志必须统一采集到中心系统,否则故障排查会退化成“登录每台节点翻文件”的体力活——这不是运维,是考古。
为什么不能直接读 /var/log/containers/*.log
看似最省事的方式,实则埋下三大隐患:Kubernetes Pod 重启后日志路径变更、多容器共享一个 Pod 时日志混杂、宿主机磁盘被打满却无告警。更关键的是,json-file 驱动默认不压缩、不轮转,单个容器日志可暴涨至 GB 级,且无法关联命名空间、标签等上下文。
- 务必禁用
docker run --log-driver=json-file生产部署(除非配合max-size/max-file严格限制) - 所有容器应输出日志到
stdout/stderr,交由采集器统一处理 - 若使用
fluentd或promtail,需确认其配置中启用了merge_json_log true(Fluentd)或auto_kubernetes_labels = true(Promtail),否则 JSON 日志会被当纯文本切碎
DaemonSet 模式采集的三个硬性配置项
在每个节点部署日志代理是最主流方案,但漏配任意一项都会导致日志丢失或元数据失效:
-
hostPath必须挂载/var/log和/run/containerd(或/var/run/docker.sock),否则无法读取容器运行时日志 - 采集配置中需启用 Kubernetes 元数据注入,例如 Promtail 的
pipeline_stages.kubernetes,否则查到错误日志却不知道来自哪个 Deployment - 必须设置
scrapeConfig.relabelConfigs过滤掉系统组件日志(如kube-proxy、coredns),否则日志量被噪音淹没
典型错误现象:logs show "level=info" but no pod_name or namespace label——说明元数据注入失败。
Loki + Promtail 是当前性价比最高的组合
不是因为“新”,而是它把云原生日志的三个矛盾点同时解开了:动态标签多、存储贵、查询慢。Loki 不索引日志内容,只索引 namespace、pod、container 这类低基数标签,因此写入快、存储省、扩展平滑。
- 对比 Elasticsearch:相同日志量下,Loki 存储成本通常低于 1/10,且无需调优分片和副本数
- Promtail 内存占用稳定在
15–20MB,而 Filebeat 常超100MB,在资源紧张的边缘节点更可靠 - 查询语法极简:
{namespace="prod", container="api"} |~ "timeout",不用学 Lucene 语法也能定位问题
注意:Loki 不支持全文模糊匹配(如 *error*),必须用正则 |~ "error|fail",这是设计取舍,不是 bug。
真正难的不是选工具,而是让所有服务都输出结构化日志并带上 traceID;一旦漏掉一个 Java 微服务没配 logback-spring.xml 的 JSON encoder,整条调用链的日志就断成碎片。










