K8s 分布式追踪:Jaeger + OpenTelemetry 实战
场景与目标
- 在 Kubernetes 中快速落地 Jaeger + OpenTelemetry Collector。
- 将业务服务或 Istio 网格的追踪数据发送到 Jaeger。
- 验证 Trace 是否采集成功,并提供常见故障排查。
环境准备
- Kubernetes >= 1.24。
- 已准备
kubectl与集群管理员权限。 - 如使用 Istio,请确保命名空间已打
istio-injection=enabled。
部署 Jaeger 与 OTel Collector
- 创建命名空间:
kubectl create namespace observability
- 部署 Jaeger All-in-One(简化版,适合演示和小规模):
kubectl -n observability apply -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/deploy/examples/simple-prod.yaml
该示例会创建
jaeger-queryService,默认暴露 16686 端口供 UI 访问。
- 部署 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 即可。
验证与排障
- 端口转发查看 Jaeger UI:
kubectl -n observability port-forward svc/jaeger-query 16686:16686
# 浏览器访问 http://localhost:16686
- 触发请求并查看 Trace:在 Jaeger UI 选择
demo-web或服务名称,确认 Trace 树和 Span 存在。 - 常见问题:
- 无 Trace:检查应用环境变量是否指向
otlp.observability.svc,或 Istio tracing 配置是否生效。 - 连接失败:排查
otlpServiceENDPOINTS是否为空,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 中快速获得可观测的调用链。按照上述安装、接入、验证与排障步骤,你可以在生产环境逐步扩容并叠加存储、告警和标准化标签,构建稳定的分布式追踪体系。