一步步用 OpenTelemetry Collector 以 DaemonSet 采集 K8s 容器日志与 cAdvisor 指标并上报 OBSERVE,附完整配置 YAML 与常见报错排查。
把 Kubernetes 的日志和指标接进可观测平台,是很多团队搭建可观测体系的第一步。这篇文章手把手带你用 OpenTelemetry Collector 完成接入:一个 DaemonSet、一份配置,跑通之后日志和指标都会带着 Pod 元数据进到平台里,可以直接按命名空间过滤、按 trace_id 关联。
用 OpenTelemetry Collector 以 DaemonSet 方式部署,每个节点跑一个实例,负责收集本节点所有容器的 stdout/stderr 日志与 cAdvisor 指标,再统一推送到炬鲸 OBSERVE 的 OTLP 端点。相比在每个 Pod 里塞 sidecar,DaemonSet 方案节点级共享、资源开销小,也更好升级,代价是牺牲了单 Pod 的定制能力——日志和指标采集通常用不到。之所以选 Collector 而不是自己写采集脚本,是因为它把解析、过滤、脱敏、重试这些脏活都标准化了,升级维护有社区兜底。
动手前确认三点:K8s 版本在 1.22 以上;Collector 所在节点能访问 OBSERVE 的 OTLP 端点(内网环境提前开好出网策略);已经拿到服务的接入 Token。混合架构集群(部分节点是 ARM)要给 Collector 配 nodeSelector,确保每个节点跑的是对应架构的镜像。
Collector 的关键组件:filelog receiver 读容器日志,k8s_cluster receiver 采集节点与 Pod 指标,k8sattributes processor 给日志补上 Pod 名、命名空间、标签等元数据,otlphttp exporter 推送到 OBSERVE。type: container 这个 operator 负责解析容器运行时的日志格式,让 message 和时间戳干净地出来,而不是包在一层 JSON 里。
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector
data:
config.yaml: |
receivers:
filelog:
include: [/var/log/containers/*.log]
operators:
- type: container
k8s_cluster:
auth_type: serviceAccount
processors:
k8sattributes:
extract:
metadata: [k8s.pod.name, k8s.namespace.name]
exporters:
otlphttp:
endpoint: https://ob.example.com/otlp
headers:
Authorization: Bearer ${OBSERVE_TOKEN}
service:
pipelines:
logs:
receivers: [filelog]
processors: [k8sattributes]
exporters: [otlphttp]
metrics:
receivers: [k8s_cluster]
processors: [k8sattributes]
exporters: [otlphttp]
还要给 Collector 配一个带 RBAC 权限的 ServiceAccount,让它能 list Pod 和命名空间;DaemonSet 上要设置资源 request/limit,防止被同节点的其他业务挤占。用 containerd 的集群,确认 include 路径 /var/log/containers/*.log 能正确解析到日志文件——多数发行版它是软链,但最好自己验证一下。应用如果会打印多行堆栈,加一个 multiline operator,否则一条异常会被拆成十几行不完整日志,排查时对不上号。
先在 OBSERVE 控制台创建服务,拿到接入 Token,再用 Secret 注入到 Collector 的环境变量里,别把 Token 明文写进 ConfigMap。Token 建议定期轮换,轮换后重启 Collector 即可生效。日志量大的集群,给 exporter 配 batch 和 retry,避免逐条推送压垮网络;日志里有敏感字段的话,加一个 redaction processor 在数据离开集群前先脱敏,这在金融、政务场景尤其重要。
部署后先看 Collector 自己的日志,确认 exporter 没有 401 或超时,再用类 SQL 查询确认日志进来:
SELECT * FROM logs WHERE k8s.namespace.name = 'production' AND ts > now() - 5m LIMIT 20
指标也顺手确认一下,能查到节点 CPU/内存就说明 k8s_cluster 这条链路通了。常见问题:Token 过期导致 401;filelog 读不到日志,多半是 include 路径和容器运行时日志目录对不上(containerd 与 Docker 路径不同);指标采不上,检查 k8s_cluster receiver 的 RBAC 权限是否配齐;日志重复,检查 Collector 和已有的日志 Agent 是否在同时采集同一批文件。
接入跑通只是第一步。接下来建议做两件事:一是给日志加上 trace_id 关联,把日志、链路、指标串成一条线;二是按环境设置日志保留策略,生产日志保留久一些,测试环境可以短一些,既控成本又不影响排查。