OpenTelemetry 企业链路追踪与可靠转发

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。
本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
API Application Programming Interface 应用程序编程接口
CA Certificate Authority 证书颁发机构
DB Database 数据库
gRPC gRPC Remote Procedure Calls 基于 HTTP/2 的远程过程调用框架
OTLP OpenTelemetry Protocol OpenTelemetry 遥测传输协议
PDB Pod Disruption Budget Pod 中断预算,约束自愿驱逐
PKI Public Key Infrastructure 公钥基础设施
PVC Persistent Volume Claim 持久卷申领
SAN Subject Alternative Name 证书主题备用名称,用于声明域名或 IP
SDK Software Development Kit 软件开发工具包
TLS Transport Layer Security 传输层安全协议
UID Unique Identifier 唯一标识符;Linux 权限语境中为 User ID(用户标识)
W3C World Wide Web Consortium 万维网联盟

场景:订单 API→队列→worker→数据库形成可关联 trace,经 Collector gateway TLS 转发到已有企业 Tempo/OTLP 后端。前置:基线、业务 SDK instrumentation、可用 tracing backend;仅安装 Collector 不会自动产生业务 span。

设计先确定#

API 使用 W3C tracecontext/baggage;异步队列采用明确 parent/link 语义,传播头不包含个人信息。所有服务统一 service.name、环境和版本,采样率按吞吐/费用确定。Collector 有两类角色:Agent 收节点数据,Gateway 收集/处理/导出;本篇只部署 traces gateway,日志由日志篇负责,避免重复采集。

head sampling 由 SDK 决定,已丢弃的 trace 不能由下游恢复。tail sampling 需要同一 trace 的 spans 路由到同一实例,不能把普通多副本 Service 当成完整尾采样架构。Collector 韧性

Hands-on:TLS、持久队列与背压#

先准备 observability/otel-server-tls 的服务端 tls.crt/tls.key、otel-backend-tls 的客户端 tls.crt/tls.key/ca.crt;证书 SAN 包含实际 Service 名。密钥由 cert-manager/企业 PKI 管理,两个证书用途分开。

helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm search repo open-telemetry/opentelemetry-collector --versions
export OTEL_CHART_VERSION='REPLACE_CHART_VERSION'
helm show values open-telemetry/opentelemetry-collector --version "$OTEL_CHART_VERSION" > otel-defaults.yaml

保存 otel-values.yaml。使用 StatefulSet 让每副本有自己的持久队列,不给多个实例共用同一 file_storage 目录;所选 chart 必须支持 volumeClaimTemplates:

mode: statefulset
replicaCount: 3
image:
  repository: otel/opentelemetry-collector-contrib
podSecurityContext:
  fsGroup: 10001
securityContext:
  runAsNonRoot: true
  runAsUser: 10001
  runAsGroup: 10001
  allowPrivilegeEscalation: false
  capabilities: {drop: [ALL]}
ports:
  otlp-http: {enabled: false}
  jaeger-compact: {enabled: false}
  jaeger-thrift: {enabled: false}
  jaeger-grpc: {enabled: false}
  zipkin: {enabled: false}
resources:
  requests: {cpu: 250m, memory: 512Mi}
  limits: {cpu: "2", memory: 1Gi}
extraVolumes:
  - name: server-tls
    secret: {secretName: otel-server-tls}
  - name: backend-tls
    secret: {secretName: otel-backend-tls}
extraVolumeMounts:
  - {name: queue, mountPath: /var/lib/otel}
  - {name: server-tls, mountPath: /tls/server, readOnly: true}
  - {name: backend-tls, mountPath: /tls/backend, readOnly: true}
statefulset:
  volumeClaimTemplates:
    - metadata: {name: queue}
      spec:
        accessModes: [ReadWriteOnce]
        storageClassName: REPLACE_STORAGE_CLASS
        resources: {requests: {storage: 20Gi}}
config:
  receivers:
    jaeger: null
    zipkin: null
    prometheus: null
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317
          tls:
            cert_file: /tls/server/tls.crt
            key_file: /tls/server/tls.key
        http: null
  extensions:
    health_check:
      endpoint: 0.0.0.0:13133
    file_storage:
      directory: /var/lib/otel
  processors:
    memory_limiter:
      check_interval: 1s
      limit_mib: 768
      spike_limit_mib: 128
    batch:
      timeout: 5s
      send_batch_size: 1024
    attributes/redact:
      actions:
        - {key: http.request.header.authorization, action: delete}
        - {key: enduser.id, action: delete}
  exporters:
    debug: null
    otlp/backend:
      endpoint: REPLACE_OTLP_BACKEND_HOST:4317
      tls:
        ca_file: /tls/backend/ca.crt
        cert_file: /tls/backend/tls.crt
        key_file: /tls/backend/tls.key
      sending_queue:
        enabled: true
        storage: file_storage
        queue_size: 10000
      retry_on_failure:
        enabled: true
        max_elapsed_time: 0s
  service:
    extensions: [health_check, file_storage]
    pipelines:
      logs: null
      metrics: null
      traces:
        receivers: [otlp]
        processors: [memory_limiter, attributes/redact, batch]
        exporters: [otlp/backend]

确保 fsGroup/UID 可写队列 PVC,补跨区放置/PDB、允许业务到 4317 的 NetworkPolicy,其他默认接收端口关闭。chart 的默认 image tag/command 与 contrib 必须匹配所选 Chart,渲染后固定 digest。Collector Chart

helm upgrade --install otel-gateway open-telemetry/opentelemetry-collector --version "$OTEL_CHART_VERSION" -n observability --create-namespace -f otel-values.yaml --wait --timeout 15m
kubectl -n observability get statefulset,pods,pvc,service

业务 SDK 配置实际 Service 的 TLS endpoint、gRPC 协议及 CA,设置 OTEL_SERVICE_NAME=orders-api、OTEL_TRACES_SAMPLER=parentbased_traceidratio 和已测算采样率。worker 使用自己的 service.name 并传播消息上下文。不要设置 insecure 跳过 TLS。

企业验收与恢复#

从真实订单响应/日志提取 trace_id,在后端看到 API、生产消息、worker、DB spans;确认服务/环境正确、敏感属性已移除。精确业务字段在应用 SDK 入口脱敏,Collector 的两条示例删除规则不可能覆盖所有秘密。

阻断后端出口:观察 exporter queue、失败重试和磁盘;重建一个 Collector Pod 后队列从对应 PVC 恢复,恢复出口后消退。满队列/磁盘故障仍可能丢数据,按实际峰值测可容忍中断时间;追踪不承担账务审计保证。

升级前核对 Collector 配置 schema、组件弃用和持久队列兼容;先试点一个独立 gateway,再切 SDK endpoint。恢复旧 Collector 不能盲目读新格式存储;保留队列副本与证据。后端、CA、PVC 和 SDK 配置的恢复要协同。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭