3. Jaeger 部署与配置:使用 Docker Compose 与 Kubernetes 部署 Jaeger 全栈

在生产级可观测性体系中,Jaeger 的部署方式直接影响链路数据的采集效率与运维成本。本章围绕两种主流编排方案——Docker Compose(适用于开发/测试环境)与 Kubernetes(适用于生产环境),详细拆解 Jaeger 全栈组件的部署流程、配置要点及验证方法。

3.1 Jaeger 全栈组件架构概览

在部署前,需明确 Jaeger 各核心组件的职责与数据流向。下表梳理了关键组件及其功能定位:

组件 角色 关键配置项
jaeger-agent 边车代理,接收应用端 Span 并批量上报 --reporter.grpc.host-port
jaeger-collector 接收 Agent 或直连 Span,校验并写入存储后端 --collector.zipkin.host-port, --es.server-urls
jaeger-query 提供 API 与 UI 查询已存储的 Trace 数据 --query.storage.type, --query.port
jaeger-ingester 从 Kafka 消费 Span 并批量写入存储(可选) --kafka.consumer.topic, --ingester.deadlockInterval
存储后端 持久化 Span 数据(Elasticsearch / Cassandra / Badger) 索引分片数、副本数、TTL
架构要点: 生产环境推荐使用 Kafka 作为 Collector 与 Ingester 之间的缓冲层,以应对突发流量并解耦写入压力。Agent 应部署为 DaemonSet 或 Sidecar,确保每个 Pod 都有本地上报端点。

3.2 使用 Docker Compose 部署 Jaeger 全栈

Docker Compose 适用于本地开发、快速原型验证及 CI/CD 集成测试。以下部署方案包含 Agent、Collector、Query 及 Elasticsearch 存储。

3.2.1 编写 docker-compose.yml

version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.10
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ports:
      - "9200:9200"
      - "9300:9300"

  jaeger-collector:
    image: jaegertracing/jaeger-collector:1.52
    ports:
      - "14269:14269"   # 健康检查
      - "14268:14268"   # 直连 HTTP
      - "14250:14250"   # gRPC
      - "9411:9411"     # Zipkin 兼容
    environment:
      - SPAN_STORAGE_TYPE=elasticsearch
      - ES_SERVER_URLS=http://elasticsearch:9200
      - COLLECTOR_QUEUE_SIZE=2000
    depends_on:
      - elasticsearch

  jaeger-query:
    image: jaegertracing/jaeger-query:1.52
    ports:
      - "16686:16686"   # UI
      - "16687:16687"   # 健康检查
    environment:
      - SPAN_STORAGE_TYPE=elasticsearch
      - ES_SERVER_URLS=http://elasticsearch:9200
    depends_on:
      - elasticsearch

  jaeger-agent:
    image: jaegertracing/jaeger-agent:1.52
    ports:
      - "5775:5775/udp" # Zipkin thrift
      - "6831:6831/udp" # Jaeger thrift compact
      - "6832:6832/udp" # Jaeger thrift binary
      - "5778:5778"     # 配置端口
    command: ["--reporter.grpc.host-port=jaeger-collector:14250"]
    depends_on:
      - jaeger-collector

3.2.2 启动与验证

  1. 启动服务:docker-compose up -d
  2. 检查健康状态:访问 http://localhost:14269/ 返回 {"status":"Server available"}
  3. 访问 UI:浏览器打开 http://localhost:16686,确认服务列表为空(尚未接入应用)
  4. 查看日志:docker-compose logs -f jaeger-collector 确认无连接错误
避坑提示: Elasticsearch 首次启动较慢,需等待 30-60 秒。若 Collector 报错 no Elasticsearch node available,请检查 ES_SERVER_URLS 是否使用服务名而非 localhost。

3.3 使用 Kubernetes 部署 Jaeger 全栈

Kubernetes 部署采用 Jaeger Operator 或 Helm Chart 两种主流方式。本节以 Helm Chart 为例,展示生产级配置。

3.3.1 部署架构图

Jaeger on Kubernetes 部署架构 Jaeger on Kubernetes 部署架构 Kubernetes 集群 应用 Pod 业务容器 jaeger-agent (Sidecar) gRPC jaeger-collector Deployment HPA 自动扩缩 Kafka Kafka 缓冲层 jaeger-ingester 批量写入 Elasticsearch StatefulSet jaeger-query Deployment Service + Ingress

3.3.2 使用 Helm Chart 部署

Jaeger 官方 Helm Chart 位于 jaegertracing/jaeger,支持一键部署全栈组件。以下为生产级 values.yaml 关键配置:

# values-prod.yaml
provisionDataStore:
  cassandra: false
  elasticsearch: true

elasticsearch:
  host: "elasticsearch-master.elastic-system.svc.cluster.local"
  port: 9200
  user: "elastic"
  password: "changeme"

collector:
  replicas: 3
  resources:
    requests:
      memory: "512Mi"
      cpu: "500m"
    limits:
      memory: "1Gi"
      cpu: "1"
  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 10
    targetCPUUtilizationPercentage: 70

query:
  replicas: 2
  ingress:
    enabled: true
    hosts:
      - jaeger.example.com

agent:
  enabled: true
  strategy: DaemonSet
  resources:
    requests:
      memory: "128Mi"
      cpu: "100m"

storage:
  type: elasticsearch
  es:
    index-cleaner:
      enabled: true
      numberOfDays: 7
    span-storage-type: elasticsearch

部署命令:

helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
helm repo update
helm install jaeger jaegertracing/jaeger -f values-prod.yaml -n observability --create-namespace

3.3.3 验证部署

验证项 命令/操作 预期结果
Pod 状态 kubectl get pods -n observability 所有 Pod 处于 Running 状态
Service 暴露 kubectl get svc -n observability jaeger-query 有 ClusterIP 或 LoadBalancer
UI 可访问 端口转发 kubectl port-forward svc/jaeger-query 16686:16686 -n observability 浏览器打开 localhost:16686 显示 Jaeger UI
Agent 上报 查看 Agent 日志 kubectl logs daemonset/jaeger-agent -n observability 无连接拒绝错误
存储写入 ES 索引检查 curl elasticsearch:9200/_cat/indices 存在 jaeger-span-* 索引

3.4 配置要点与生产优化

3.4.1 存储选型对比

存储类型 适用场景 优势 劣势
Elasticsearch 生产环境,大规模链路 全文检索、聚合分析、成熟生态 资源消耗高、运维复杂
Cassandra 超大规模写入,高可用 水平扩展、无单点 查询能力弱、学习曲线陡
Badger 单机开发/测试 零依赖、启动快 不支持集群、数据易丢失
Kafka + ES 高吞吐生产环境 削峰填谷、解耦写入 增加链路延迟、运维组件多

3.4.2 关键配置参数

  • Collector 队列:COLLECTOR_QUEUE_SIZE 默认 2000,高并发场景建议提升至 5000-10000,同时增加 COLLECTOR_NUM_WORKERS 匹配 CPU 核数。
  • 采样策略:生产环境使用 概率采样(如 0.1)或 速率限制采样(如 100 spans/sec),避免存储爆炸。
  • 索引生命周期:ES 索引 TTL 建议 7 天,配合 ILM 策略自动删除过期索引,释放磁盘空间。
  • Agent 上报:gRPC 端口 14250 比 UDP 端口 6831 更可靠,生产环境优先使用 gRPC。
生产警告: 切勿在生产集群中直接使用 allInOne 镜像部署 Jaeger。该模式将所有组件合并为单进程,不具备高可用与扩展能力,仅适用于本地快速体验。

3.5 部署后快速验证:发送测试 Trace

部署完成后,可通过 Jaeger 自带的 HotROD 示例应用快速验证全链路功能:

# Docker Compose 环境
docker run --rm -it \
  --network jaeger_default \
  -e JAEGER_AGENT_HOST=jaeger-agent \
  -p 8080:8080 \
  jaegertracing/example-hotrod:1.52 all

# Kubernetes 环境
kubectl run hotrod --image=jaegertracing/example-hotrod:1.52 \
  --env="JAEGER_AGENT_HOST=jaeger-agent.observability.svc.cluster.local" \
  --port=8080
kubectl expose pod hotrod --port=8080 --type=NodePort

访问 HotROD 页面(http://localhost:8080 或 NodePort),点击按钮触发请求,随后在 Jaeger UI 中搜索 hotrod 服务,应能看到完整的 Trace 链路。

Jaeger 部署方式决策流程 Jaeger 部署方式决策流程 选择部署环境 开发 / 测试环境 Docker Compose + Badger/ES 生产环境 Kubernetes + ES + Kafka 快速验证 / 本地调试 高可用 / 自动扩缩 / 持久化
最佳实践总结:
  • 开发环境:Docker Compose + Elasticsearch(单节点)+ Agent Sidecar,快速迭代。
  • 预发/生产环境:Kubernetes + Helm Chart + Elasticsearch 集群 + Kafka 缓冲 + HPA 自动扩缩。
  • 存储选型:优先 Elasticsearch,日均 Span 量超过 10 亿时考虑 Cassandra。
  • 采样策略:生产环境必须配置采样率,避免存储成本失控。