遇到 Unable to export traces to OpenTelemetry Collector on Kubernetes,并且配置了 OTEL_EXPORTER_OTLP_ENDPOINT=http://0.0.0.0:4318 时,先修正地址:Collector 与应用不在同一个 Pod,就改为 <collector-service>.<namespace>.svc.cluster.local:4318;使用 OTLP/gRPC 时改为 4317。只有 Collector 以 Sidecar 形式与应用同 Pod,才适合使用 127.0.0.1。
排查这类问题时,通常应先确认应用是否把数据发到了自己所在 Pod,而不是只看 Collector 是否已经启动。0.0.0.0 常用于 Collector 监听所有网卡;作为客户端目标地址时,在常见的 Linux Pod 网络中,它指向当前 Pod 所在的网络环境,并不会自动指向集群里的 Collector。
先修正 OTLP 目标地址
Collector 常见的 OTLP 接收配置同时开放 gRPC 和 HTTP:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"
这里的 4317 对应 OTLP/gRPC,4318 对应 OTLP/HTTP。应用使用的协议、Collector 的 receiver 和 Kubernetes Service 暴露的端口必须一致。即使 DNS 解析正确,把 HTTP 客户端连到 gRPC 端口,仍然无法导出。
如果 Collector 独立部署,应按实际 Service 和 namespace 修改 traces 专用变量:
# OTLP/HTTP
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=<collector-service>.<namespace>.svc.cluster.local:4318
# OTLP/gRPC
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=<collector-service>.<namespace>.svc.cluster.local:4317
如果 Collector 是应用 Pod 内的 Sidecar,回环地址才成立,例如:
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=127.0.0.1:4318
随后检查 Service 端口、Pod 状态和 Collector 日志,并依据实际输出判断问题:
kubectl get svc -n <namespace>
kubectl get pods -n <namespace>
kubectl logs -n <namespace> <collector-pod> --since=10m
Service DNS 只解决“发给哪个 Collector”,不能修复协议不匹配、Service 没有可用后端、Collector receiver 未启用或 exporter 连接失败。也不要把 Pod IP 写死,因为 Kubernetes Pod 重建后 IP 可能变化。
按数据路径选择部署模式
Collector 的部署方式应结合数据路径选择,而不是先确定一个“标准副本数”。不同工作负载对弹性、节点覆盖、稳定主机名和应用级配置的要求不同。
| 部署模式 | 适合场景 | 主要约束 |
|---|---|---|
| Deployment | 弹性通用网关,统一接收多个应用的遥测数据 | 多个副本可能落在同一节点,不能只看副本数判断节点故障容错 |
| DaemonSet | 每个节点统一采集或预处理数据 | 节点异常时,该节点的 Collector 也不可用 |
| StatefulSet | 副本数和主机名需要固定的场景 | 弹性伸缩能力不如 Deployment,适合依赖稳定主机名的处理器 |
| Sidecar | 应用需要定制 Collector 配置,或希望在本 Pod 内转交遥测数据 | 每个应用 Pod 都要承担一份 Collector 的资源和运维成本 |
Deployment 与 Sidecar 也可以组合:通用 Collector 负责集群级入口,Sidecar 承载应用特有处理。DaemonSet 更适合节点级统一处理,StatefulSet 则适合依赖稳定主机名列表的处理器。
多集群环境还要处理节点故障、内存峰值和配置漂移。Deployment 副本如果全部调度到同一节点,节点故障仍会同时带走全部 Collector;DaemonSet 覆盖了所有节点,也不等于节点故障时本地数据不会中断。 配置则适合采用版本化模板管理,把集群标识、后端地址等环境差异限制在少量字段中,再比较各集群最终渲染出的配置,避免人工复制 YAML 后逐渐分叉。
掘金热榜中的 Skyscanner 24 集群案例与 Mastodon 小团队方案,可以作为两个方向相反的治理参考:前者更值得强调配置一致性和故障隔离,后者更值得强调最少组件和最低维护成本。热点材料没有提供足够的配置细节,不能据此推导一套适用于所有团队的拓扑。
Collector 配置可以通过 ConfigMap 挂载,再以以下参数启动:
--config=/conf/collector.yaml
这只是配置起点。Collector 官方示例的定位是指南,而不是可以直接用于生产的方案,镜像版本和资源配置仍需按当前版本、节点规模及实际流量验证。
先限内存再批量发送
每个 Collector pipeline 都应先执行 memory_limiter,再执行 batch。前者负责在内存压力下保护 Collector,后者负责批量发送;如果先堆积大量数据再检查内存,限流通常已经来不及。
下面的数值只用于说明参数关系:
processors:
memory_limiter:
limit_mib: 1800
spike_limit_mib: 400
batch:
send_batch_size: 10000
在这个例子中,软限制是 1800 - 400 = 1400 MiB。内存超过软限制后,Collector 会开始拒绝新数据;超过 limit_mib 后会触发 GC,并继续拒绝数据。代价是出现遥测缺口,因此不能为了“保住节点”把限制设成与实际流量完全脱节的值。
limit_mib 是 Collector heap 的硬目标,不应直接等同于容器 memory limit。容器还要给非 heap 内存、连接缓冲和运行时开销留出空间;否则限流器还没来得及拒绝数据,Pod 就可能先被 OOMKill。send_batch_size 同样不是越大越好,批量过大可能拉高单次发送时间和内存峰值。
尾采样由 tailsamplingprocessor 完成,适合放在 Collector 的 trace pipeline 中,在导出之前处理候选链路。它需要保留相关 Span 进行决策,会增加内存压力,必须用接近生产的流量验证采样结果和 Collector 资源消耗,不宜直接套用一个通用采样比例。
让应用自动发出遥测
OpenTelemetry Operator 通过 OpenTelemetryCollector 描述 Collector,通过 Instrumentation 定义自动注入规则;OpenTelemetryTargetAllocator 用于水平扩展场景,例如动态分配接收目标。
Java 工作负载常见的注入注解如下:
spec:
template:
metadata:
annotations:
instrumentation.opentelemetry.io/inject-java: "true"
这个注解必须放在实际接收注入的 Pod 模板上。当前 Operator 版本是否支持对应语言、工作负载注解应放在哪里,以及 Agent 应采用哪种配置方式,都应按所用版本的 CRD 和文档核对,不能仅凭旧示例判断。
给多集群数据统一身份
多集群首先要统一数据身份,不必先统一所有组件。资源属性可以识别容器、主机和服务,多集群还应增加可验证的集群标识。具体属性名需要结合所用 OpenTelemetry 语义约定及后端支持情况确认,不能假定某个固定字段在所有版本里都有效。
Kubernetes 标签和 Pod UID 等字段可能带来高基数问题。不要把所有原始标签直接塞进每条遥测数据,而应保留定位故障真正需要的稳定维度。
指标、日志和链路可以保留各自的采集路径:指标继续由 Prometheus 抓取,多集群查询再评估 Thanos 或 Cortex;容器日志由运行时从 stdout、stderr 捕获并按 CRI 格式保存,应用日志若要走 OpenTelemetry 路径,则由应用发送 OTLP logs,Collector 再导出到 Loki;链路则沿 OTLP 进入 Collector。
日志和链路要真正关联,日志中需要保留 trace_id,资源属性也要与链路保持一致。否则即使两个信号都进了同一后端,也无法从一个错误日志稳定跳到对应 Trace。
沿同一条 Trace 完成验收
验收按数据路径逐段检查:应用先发出测试 Trace,Kubernetes Service 将请求送到 Collector,Collector 接收并处理,再由 exporter 发往后端,最后在查询界面按 Trace ID 查找。Collector 日志里“看到数据”不等于后端已经成功保存,还要继续检查 exporter 到后端的连接。
Operator 的注入和升级行为可以使用 kind 与 Chainsaw 做端到端验证;Collector 链路则可以参考多 Collector 测试方案,重点覆盖副本切换、配置更新和后端不可达时的行为。
排查时从应用日志或调试信息取得 Trace ID,再依次检查 Service、Collector 日志和后端查询结果。只有后端能够查到同一 trace ID,才说明整条采集链路已经打通。












暂无评论内容