用 DaemonSet 在每个节点部署采集 Agent,把容器 stdout 日志送进炬鲸 OBSERVE,含 Helm 安装、K8s 元数据注入、Java 堆栈等多行日志合并,以及一份排错清单。
在 K8s 里采日志有两条路线:改应用让它主动推,或者在节点上统一收。前者要动每个服务的代码,后者加一个采集 Agent 就行。OBSERVE 推荐后者:每个节点跑一个 Agent,读容器运行时写到 /var/log/containers 的 stdout 日志,应用零改动。
好处很明显:新服务上线自动被采集,不用逐个配置;采集点是节点级,不会和应用抢资源;应用崩了日志照样在,因为 stdout 是容器运行时在管,不依赖应用进程本身。
helm repo add observe https://charts.ob.jjhub.cn
helm install observe-agent observe/agent \
--set endpoint="https://ob.jjhub.cn/ingest" \
--set token="替换成你的接入 token"
底层是一个 DaemonSet,把宿主机日志目录以只读方式挂进 Pod:
volumeMounts:
- name: varlog
mountPath: /var/log
readOnly: true
- name: containers
mountPath: /var/lib/docker/containers
readOnly: true
装完 kubectl -n observe get pods 应该看到每个节点一个 Agent,处于 Running。注意 containerd 运行时的日志路径和 Docker 不同(在 /var/log/pods 下),如果集群用的是 containerd,挂载目录要相应调整。
裸的容器日志只有内容和时间戳,没有“哪个命名空间、哪个 Pod、哪个容器”的信息。Agent 默认开启元数据注入,把 namespace、pod、container、node 作为标签打进去。之后在 OBSERVE 里就能按 namespace="prod" AND pod=~"order-*" 过滤,也能和 Prometheus 的 pod 维度对齐,做到日志和指标同口径。
Java 异常的堆栈打印成多行,如果每行当成一条独立日志,Traceback 会被拆散,检索时只看到半截异常。Agent 支持按正则识别多行:以时间戳或日志级别开头的行为新日志,其余行追加到上一条。
multiline:
firstline: '^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}'
配好之后,一条完整堆栈在 OBSERVE 里是一条日志,点开能看到全部调用帧。
kubectl -n observe logs 看 Agent 日志,八成是 token 过期或 endpoint 不通;