跳到主要内容

K8s 分布式追踪:Jaeger + OpenTelemetry 实战

场景与目标

  • 在 Kubernetes 中快速落地 Jaeger + OpenTelemetry Collector。
  • 将业务服务或 Istio 网格的追踪数据发送到 Jaeger。
  • 验证 Trace 是否采集成功,并提供常见故障排查。

环境准备

  • Kubernetes >= 1.24。
  • 已准备 kubectl 与集群管理员权限。
  • 如使用 Istio,请确保命名空间已打 istio-injection=enabled

部署 Jaeger 与 OTel Collector

  1. 创建命名空间:
kubectl create namespace observability
  1. 部署 Jaeger All-in-One(简化版,适合演示和小规模):
kubectl -n observability apply -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/deploy/examples/simple-prod.yaml

该示例会创建 jaeger-query Service,默认暴露 16686 端口供 UI 访问。

  1. 部署 OpenTelemetry Collector(接收 OTLP,转发到 Jaeger):
# otel-collector.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
namespace: observability
data:
otel-collector-config: |
receivers:
otlp:
protocols:
http:
grpc:
processors:
batch: {}
exporters:
jaeger:
endpoint: jaeger-collector.observability.svc.cluster.local:14250
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [jaeger]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: otel-collector
namespace: observability
spec:
replicas: 1
selector:
matchLabels:
app: otel-collector
template:
metadata:
labels:
app: otel-collector
spec:
containers:
- name: otel-collector
image: otel/opentelemetry-collector:0.102.1
args: ["--config=/etc/otel-collector-config.yaml"]
volumeMounts:
- name: config
mountPath: /etc/otel-collector-config.yaml
subPath: otel-collector-config
ports:
- containerPort: 4317 # gRPC
- containerPort: 4318 # HTTP
volumes:
- name: config
configMap:
name: otel-collector-config
---
apiVersion: v1
kind: Service
metadata:
name: otlp
namespace: observability
spec:
selector:
app: otel-collector
ports:
- name: grpc
port: 4317
targetPort: 4317
- name: http
port: 4318
targetPort: 4318

应用:

kubectl apply -f otel-collector.yaml
kubectl -n observability get po

接入应用或 Istio 网格

直接接入应用(无 Service Mesh)

在应用中设置 OTLP 端点即可(以 Java 示例):

export OTEL_EXPORTER_OTLP_ENDPOINT=http://otlp.observability.svc:4318
export OTEL_SERVICE_NAME=demo-web
java -javaagent:/path/opentelemetry-javaagent.jar -jar app.jar

Istio 集成(将 Envoy Trace 发送到 OTel Collector)

meshConfig.defaultConfig.tracing 中配置 Envoy 到 OTLP:

tracing:
sampling: 100.0
zipkin:
address: otlp.observability.svc.cluster.local:4317

应用配置后滚动更新 Sidecar 即可。

验证与排障

  1. 端口转发查看 Jaeger UI:
kubectl -n observability port-forward svc/jaeger-query 16686:16686
# 浏览器访问 http://localhost:16686
  1. 触发请求并查看 Trace:在 Jaeger UI 选择 demo-web 或服务名称,确认 Trace 树和 Span 存在。
  2. 常见问题:
  • 无 Trace:检查应用环境变量是否指向 otlp.observability.svc,或 Istio tracing 配置是否生效。
  • 连接失败:排查 otlp Service ENDPOINTS 是否为空,Collector Pod 日志是否有 “failed to connect” 信息。
  • 取样率过低:调整 sampling 比例,或在应用中设置 OTEL_TRACES_SAMPLER=always_on 进行验证。
  • 时区/延迟异常:确保节点时间同步(NTP),排查网络 MTU/丢包。

生产落地要点

  • 使用 Jaeger Operator 或 Helm chart 配置存储后端(Elasticsearch/ClickHouse)以持久化 Trace。
  • 根据访问量水平扩展 Collector 副本,并开启 batch/queue 限流防止 OOM。
  • 统一定义 service.name、环境标签(env, version),便于查询和告警。
  • 将配置纳入 GitOps,发布前执行 kubectl apply --server-dry-run 校验。
  • 结合告警:对 500/延迟升高时触发的 Trace 数量设置阈值,快速定位问题。

总结

通过部署 Jaeger + OpenTelemetry Collector,并将应用或 Istio 网格流量指向 OTLP 端点,可以在 Kubernetes 中快速获得可观测的调用链。按照上述安装、接入、验证与排障步骤,你可以在生产环境逐步扩容并叠加存储、告警和标准化标签,构建稳定的分布式追踪体系。