一个 DaemonSet 部署 OpenTelemetry Collector,统一采集 K8s 集群的容器日志、主机指标和分布式追踪,配置 OTLP exporter 上报到炬鲸 OBSERVE,附完整 YAML 与排错清单。
一个 K8s 集群几十个服务,如果每个应用自己配上报,Token、采集地址、采样率散落在十几个仓库里,改起来要命。OpenTelemetry Collector 的价值在于把「接收、处理、转发」集中到一处:应用只把数据发给本机 Collector,Collector 统一做过滤、脱敏、批量后转发给后端。
炬鲸 OBSERVE 原生支持 OTLP 协议,Collector 配一个 OTLP exporter 就能把日志、指标、追踪三路数据一起送进来。本文从 DaemonSet 清单讲到验证,完整走一遍。
Collector 以 DaemonSet 跑在每个节点上,负责采集该节点所有容器的 stdout 日志和主机指标:
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
data:
config.yaml: |
receivers:
filelog:
include: [/var/log/pods/*/*/*.log]
operators:
- type: json_parser
hostmetrics:
scrapers: [cpu, memory, disk, network]
exporters:
otlphttp:
endpoint: https://ob.example.com/otlp
headers:
Authorization: Bearer <你的Token>
service:
pipelines:
logs: {receivers: [filelog], exporters: [otlphttp]}
metrics: {receivers: [hostmetrics], exporters: [otlphttp]}
用 kubectl apply -f 部署 DaemonSet,把宿主机 /var/log/pods 和 /var/log/containers 挂进容器即可。filelog 接收器 tail 这些路径,json_parser 算子把每一行解析成结构化字段,后续才能在平台上按字段过滤。
Java/Go/Python 应用引入对应 SDK 后,把 OTEL_EXPORTER_OTLP_ENDPOINT 指向本机 Collector(localhost:4318),由 Collector 统一加上集群元数据(node、namespace、pod)再转发。应用代码零改动,元数据却更完整。
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_SERVICE_NAME=order-service
每个 pod 只和本节点的 Collector 通信,没有跨节点流量,应用里的 exporter 也完全不需要知道 Observe 的地址和 Token。以后轮换 Token,只需改 Collector 一处,不用重新部署所有服务。
Collector 的 processor 在数据进后端之前做加工。比如把 access log 里的手机号、身份证号脱敏:
processors:
redaction:
allow_all_keys: true
blocked_values: [password, token]
再配合 filter 丢掉 debug 级日志、batch 合并小批量降低网络开销。追踪是三种信号里最「吵」的,用采样处理器只保留全部错误 span 和一小部分健康流量:
processors:
probabilistic_sampler:
sampling_percentage: 10
这些处理放在采集端,后端存储成本能省 30% 以上,敏感字段也根本不会离开集群,合规审查时也好交代。
部署后先在控制台「日志检索」里查一条日志,确认能看到 k8s.namespace、k8s.pod 等字段;指标页确认 hostmetrics 已上报。常见问题按顺序排查:/var/log/pods 没挂载导致 filelog 收不到;OTLP endpoint 写错协议(4317 是 gRPC、4318 是 HTTP,别混);Token 放错 header 名。给 DaemonSet 设一个宽松但有上限的内存限制——Collector 在内存里缓冲数据,洪峰下内存太紧会丢 span,而不是把整条管道拖垮。逐项排查,管道几分钟内就能跑通。