把服务网格流量接进 OpenTelemetry:2026 年东西向指标参考

2026-06-29 31 预计阅读时间: 1 分钟
来源: cncf.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

如果你已经在跑 OpenTelemetry pipeline,应用内部发生了什么通常不再是黑盒:请求耗时、错误、trace、runtime 指标都能进同一套观测系统。但很多团队仍然缺一块:服务之间的东西向流量。服务网格或 sidecar/proxy 能看到应用代码看不到的连接、重试、TLS、上游/下游关系,把这些 mesh-derived metrics 接进 OTel,能让服务拓扑从“代码视角”补齐到“网络视角”。

应用指标看不到的那一层

应用埋点通常回答这些问题:某个 handler 慢不慢、数据库调用失败多少、业务错误在哪里抛出。它的盲区也很明确:

  • 请求在进入应用前是否已经被代理重试过。
  • 服务 A 到服务 B 的连接是否因为 mTLS、负载均衡或目标实例异常而失败。
  • 同一个调用链里,网络层看到的延迟和应用层看到的延迟是否一致。
  • 哪些服务实际在通信,而不是架构图里“应该”通信。

mesh-derived metrics 的价值就在这里。它不替代应用内 OTel instrumentation,而是从数据平面补充观测信号。对 SRE 来说,这类指标尤其适合排查“代码没变但调用突然抖动”的问题:比如代理配置、服务发现、证书、连接池、重试策略或某个实例的网络路径。

接入思路:让网格指标走同一条 OTel 管道

一个实用目标是:不要为服务网格再建一套孤立的指标系统。既然已经有 OpenTelemetry Collector、导出器、后端存储和告警规则,就应该尽量把 mesh 指标规范化后送进同一条 pipeline。

可以这样拆分职责:

  • 数据平面或网格组件暴露指标,常见形态是 Prometheus scrape endpoint。
  • OpenTelemetry Collector 负责抓取、过滤、补充资源属性、重命名或降噪。
  • 后端继续使用现有的 OTLP、Prometheus remote write、Grafana/Tempo/Mimir/其他 APM 组合。
  • Dashboard 和告警同时使用应用指标与 mesh 指标,避免只看单边信号。

这里的关键不是“多收几个指标”,而是把服务身份对齐。应用指标里可能叫 service.name=checkout,网格指标里可能带的是 workload、namespace、pod、destination_service。进入 OTel pipeline 后,要尽量把这些维度整理成可 join、可聚合、可告警的标签。

可以这样实践:用 OpenTelemetry Collector 抓取网格 Prometheus 指标

下面示例假设你的服务网格或代理已经暴露 Prometheus 格式指标,例如 http://mesh-proxy-metrics:15090/stats/prometheus。不同网格的端口和指标名会不一样,运行前需要替换 targets 和保留的指标正则。

# otel-collector-mesh-metrics.yaml
receivers:
  prometheus:
    config:
      scrape_configs:
        - job_name: mesh-derived-metrics
          scrape_interval: 15s
          static_configs:
            - targets:
                - mesh-proxy-metrics:15090
          metrics_path: /stats/prometheus

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
  batch:
    timeout: 5s
  resource:
    attributes:
      - key: telemetry.source
        value: service-mesh
        action: upsert
  filter/mesh_noise:
    metrics:
      include:
        match_type: regexp
        metric_names:
          - ".*requests.*"
          - ".*request_duration.*"
          - ".*tcp.*"
          - ".*upstream.*"

exporters:
  otlphttp:
    endpoint: http://otel-backend:4318

service:
  pipelines:
    metrics:
      receivers: [prometheus]
      processors: [memory_limiter, resource, filter/mesh_noise, batch]
      exporters: [otlphttp]

本地验证配置可以用 Collector 容器跑一遍。把 mesh-proxy-metrics:15090otel-backend:4318 改成你的环境地址:

docker run --rm \
  -v "$PWD/otel-collector-mesh-metrics.yaml:/etc/otelcol/config.yaml" \
  -p 4318:4318 \
  otel/opentelemetry-collector-contrib:latest \
  --config /etc/otelcol/config.yaml

如果你在 Kubernetes 里部署,可以把同样的配置放进 ConfigMap,再由 Collector Deployment 挂载。下面是可改造的最小片段:

apiVersion: v1
kind: ConfigMap
metadata:
  name: otel-collector-mesh-config
  namespace: observability
data:
  config.yaml: |
    receivers:
      prometheus:
        config:
          scrape_configs:
            - job_name: mesh-derived-metrics
              kubernetes_sd_configs:
                - role: pod
              relabel_configs:
                - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
                  action: keep
                  regex: "true"
                - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
                  action: replace
                  target_label: __metrics_path__
                  regex: "(.+)"
                - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
                  action: replace
                  regex: "([^:]+)(?::\\d+)?;(\\d+)"
                  replacement: "$1:$2"
                  target_label: __address__
    processors:
      batch: {}
      resource:
        attributes:
          - key: telemetry.source
            value: service-mesh
            action: upsert
    exporters:
      otlphttp:
        endpoint: http://otel-backend.observability:4318
    service:
      pipelines:
        metrics:
          receivers: [prometheus]
          processors: [resource, batch]
          exporters: [otlphttp]

这个例子有意保持保守:它没有假设某个具体网格,也没有把所有指标无脑送走。真实生产环境里,你还需要按后端成本、查询习惯和告警需求收紧维度。

看哪些指标,怎么避免噪声

mesh 指标最容易踩的坑是基数爆炸。按 source_poddestination_podpathresponse_codemethod 全量展开,几天内就能把指标后端打到很贵。更稳的做法是从服务级别问题开始:

  • 请求量:按 source service、destination service、namespace 聚合。
  • 错误率:区分 5xx、连接失败、上游重置、超时。
  • 延迟:看代理观测到的 p50/p95/p99,与应用 handler 延迟对比。
  • TCP 连接:关注连接建立失败、连接重置、活跃连接数。
  • mTLS 或策略:关注认证失败、授权拒绝、证书相关错误。

告警也要克制。mesh 指标适合做“网络路径正在伤害用户请求”的告警,而不是每个代理内部计数器都报警。一个常见模式是:应用错误率升高时,用 mesh 指标解释原因;mesh 连接失败或上游重置升高时,再关联 trace 和日志定位具体服务。

可以这样写一个 PromQL 风格的查询思路,具体指标名按你的网格替换:

sum by (source_service, destination_service) (
  rate(mesh_requests_total{response_code=~"5.."}[5m])
)
/
sum by (source_service, destination_service) (
  rate(mesh_requests_total[5m])
)

这类查询回答的是“哪条服务到服务的边正在变坏”,比只看单个服务的总体 5xx 更接近东西向流量问题。

落地清单:先补视角,再扩指标面

采用 mesh-derived metrics 时,不建议一次把所有代理指标灌进 OTel。更稳的路径是:

  1. 选一条关键业务链路,例如 frontend -> checkout -> payment
  2. 对齐 service.name、namespace、workload、destination service 等核心维度。
  3. 只收请求量、错误率、延迟、连接失败这几类指标。
  4. 在 dashboard 上同时展示应用 OTel 指标和 mesh 指标,观察两者差异。
  5. 根据排障场景逐步增加 TCP、mTLS、策略、重试等维度。
  6. 给高基数字段设置过滤、聚合或采样策略。

OpenTelemetry pipeline 已经解决了“信号怎么进来、怎么处理、怎么导出”的大框架。mesh-derived metrics 要解决的是另一件事:让服务之间真实发生的通信被看见。它的边界也要说清楚:网格指标不能解释业务语义,也不能替代代码级 trace;但当问题出在代理、连接、服务发现或策略层,它往往是最短路径。


相关推荐