在Docker Compose中部署Jaeger(不使用all-in-one镜像)
错误信息
traces export: context deadline exceeded: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 172.18.0.10:4317: connect: connection refused"
我的Docker Compose配置
version: '3' services: service-a: build: context: . dockerfile: service-a/Dockerfile networks: - service-jaeger ports: - "8081:8081" environment: - OUTBOUND_HOST_PORT=service-b:8082 - OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger-collector:4317 - OTEL_EXPORTER_OTLP_INSECURE=true service-b: build: context: . dockerfile: service-b/Dockerfile networks: - service-jaeger environment: - OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger-collector:4317 - OTEL_EXPORTER_OTLP_INSECURE=true # ElasticSearch 作为追踪和日志存储 elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.11.3 networks: - service-jaeger environment: - "ES_JAVA_OPTS=-Xms2g -Xmx2g" - "bootstrap.memory_lock=true" - "discovery.type=single-node" - "xpack.security.enabled=false" - "xpack.security.enrollment.enabled=false" ports: - "127.0.0.1:9200:9200" restart: on-failure volumes: - esdata:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 # Apache Kafka 作为临时存储和追踪数据流处理系统 kafka: image: confluentinc/cp-kafka:5.2.1 networks: - service-jaeger ports: - "9092:9092" environment: KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181" KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092" KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_BROKER_ID: 1 restart: on-failure # Apache Zookeeper 用于协调Kafka服务 zookeeper: image: confluentinc/cp-zookeeper:5.2.1 networks: - service-jaeger ports: - "2181:2181" environment: ZOOKEEPER_CLIENT_PORT: "2181" # Jaeger Collector 接收Agent的追踪数据并发送到Kafka jaeger-collector: image: jaegertracing/jaeger-collector:1.11.0 hostname: jaeger-collector ports: - "14269:14269" - "14268:14268" - "14267:14267" - "9411:9411" networks: - service-jaeger restart: on-failure environment: LOG_LEVEL: "info" SPAN_STORAGE_TYPE: "kafka" KAFKA_BROKERS: "kafka:9092" METRICS_BACKEND: "prometheus" depends_on: - elasticsearch # Jaeger Ingester 从Kafka接收追踪数据并写入ElasticSearch jaeger-ingester: image: jaegertracing/jaeger-ingester:1.11.0 networks: - service-jaeger ports: - "14270:14270" - "14271:14271" restart: on-failure environment: LOG_LEVEL: "info" INGESTER_PARALLELISM: "1" INGESTER_DEADLOCKINTERVAL: "0ms" SPAN_STORAGE_TYPE: "elasticsearch" ES_SERVER_URLS: "http://elasticsearch:9200" KAFKA_BROKERS: "kafka:9092" METRICS_BACKEND: "prometheus" depends_on: - kafka # Jaeger Agent 本地接收客户端追踪数据并转发到Collector jaeger-agent: image: jaegertracing/jaeger-agent:1.11.0 hostname: jaeger-agent command: ["--collector.host-port=jaeger-collector:14267"] ports: - "5775:5775/udp" - "6831:6831/udp" - "6832:6832/udp" - "5778:5778" networks: - service-jaeger restart: on-failure environment: SPAN_STORAGE_TYPE: "elasticsearch" METRICS_BACKEND: "prometheus" depends_on: - jaeger-collector # Jaeger Query 用于查询追踪数据的UI服务 jaeger-query: image: jaegertracing/jaeger-query:1.11.0 environment: SPAN_STORAGE_TYPE: "elasticsearch" no_proxy: "localhost" METRICS_BACKEND: "prometheus" ports: - "16686:16686" - "16687:16687" networks: - service-jaeger restart: on-failure command: [ "--es.server-urls=http://elasticsearch:9200", "--span-storage.type=elasticsearch", "--log-level=debug", "--query.ui-config=/usr/share/jaeger-query/jaeger-query-config.json" ] volumes: - ./jaeger-query-config.json:/usr/share/jaeger-query/jaeger-query-config.json:ro depends_on: - jaeger-agent volumes: esdata: networks: service-jaeger: driver: bridge
核心问题
你使用的Jaeger Collector版本为1.11.0,该版本过于老旧,不支持OpenTelemetry标准的OTLP协议4317端口(Jaeger从1.20+版本才开始默认启用OTLP的gRPC端口4317)。你的服务配置了通过该端口发送追踪数据,但Collector未监听此端口,因此出现连接拒绝错误。
修复步骤
1. 升级Jaeger组件版本(推荐方案)
将所有Jaeger相关服务(collector、ingester、agent、query)的镜像版本从1.11.0升级到**1.40+**的稳定版本(例如1.50.0)。新版本默认支持OTLP的gRPC端口4317和HTTP端口4318,无需额外配置即可兼容你的服务的OTLP exporter设置。
修改后的Jaeger Collector配置示例:
jaeger-collector: image: jaegertracing/jaeger-collector:1.50.0 hostname: jaeger-collector ports: - "14269:14269" - "14268:14268" - "14267:14267" - "9411:9411" - "4317:4317" # 显式映射OTLP gRPC端口,新版本默认已开启 - "4318:4318" # 可选:OTLP HTTP端口 networks: - service-jaeger restart: on-failure environment: LOG_LEVEL: "info" SPAN_STORAGE_TYPE: "kafka" KAFKA_BROKERS: "kafka:9092" METRICS_BACKEND: "prometheus" depends_on: - kafka # 修正依赖:Collector使用Kafka存储,应依赖Kafka而非ElasticSearch
2. 不升级版本的替代方案
若暂时无法升级,需修改服务的OTLP配置,改为使用Jaeger 1.11.0支持的协议端口:
- 将服务的
OTEL_EXPORTER_OTLP_ENDPOINT改为http://jaeger-collector:14268(Jaeger Thrift HTTP端口) - 添加协议配置
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf(适配OpenTelemetry SDK的协议转换)
修改后的service-a环境变量示例:
environment: - OUTBOUND_HOST_PORT=service-b:8082 - OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger-collector:14268 - OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf - OTEL_EXPORTER_OTLP_INSECURE=true
3. 修正依赖关系错误
当前jaeger-collector的depends_on设置为elasticsearch,但Collector配置的存储类型是Kafka,这会导致Collector启动时Kafka可能未就绪,需改为依赖kafka。
内容的提问来源于stack exchange,提问作者bdparrish

