Docker Compose部署时OpenTelemetry exporter端点无法正常工作
故障原因
- 硬编码固定IP不可靠:代码中写死Collector地址为
172.23.10.4,虽然compose中给otel服务指定了固定IP,但容器重建、网络配置变更时都可能出现IP分配异常,且同compose网络内的服务默认可以通过服务名做DNS解析,不需要手动指定固定IP。 - Collector监听地址配置错误:这是最高发的原因。你挂载到容器的
otel-collector-config.yml中,如果OTLP HTTP接收器的监听地址写的是127.0.0.1:4318,Collector只会监听容器自身的回环网卡,同网络下的web容器根本无法访问。非Docker环境下本地运行时,服务和Collector都在宿主机上,127.0.0.1可以正常访问,但容器间网络是隔离的,必须监听0.0.0.0才能接收其他容器的请求。 - OTLP端点路径配置错误:如果你使用的.NET OpenTelemetry OTLP导出器版本低于1.4.0,使用HttpProtobuf协议时不会自动拼接OTLP标准接口路径,只配置到
http://ip:4318根路径的话,请求会直接发到根路径返回404,Collector的OTLP HTTP接口默认路径为/v1/traces(链路)、/v1/metrics(指标)、/v1/logs(日志)。
修复方案
- 先修改Collector配置文件
./OpenTelemetry/otel-collector-config.yml,将OTLP HTTP接收器的监听地址改为0.0.0.0:4318,核心配置参考:
receivers: otlp: protocols: http: endpoint: 0.0.0.0:4318 # 禁止写127.0.0.1 processors: batch: {} exporters: # 替换为你实际使用的导出后端,比如debug、otlp、prometheus等 debug: verbosity: detailed service: pipelines: traces: receivers: [otlp] processors: [batch] exporters: [debug] # 替换为实际的exporter配置
- 优化遥测配置方式,不要在代码里硬编码Collector地址,优先使用OpenTelemetry官方标准环境变量配置,适配不同部署环境不需要改代码:
- 修改
docker-compose.yml,升级compose版本到兼容新Docker的3.8,去掉没必要的固定IP配置,增加启动依赖避免web先于Collector启动,给web服务增加OTel标准环境变量,修改后配置参考:
version: "3.8" services: web: build: context: .. dockerfile: ./MyWebServer/Dockerfile container_name: web networks: - test_net ports: - "8080:80" depends_on: - otel environment: - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel:4318 - OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf - OTEL_SERVICE_NAME=MyWebServer - OTEL_SERVICE_VERSION=1.0.0 otel: image: "otel/opentelemetry-collector:latest" container_name: otel command: ["--config=/etc/otel-collector-config.yml"] volumes: - ./OpenTelemetry/otel-collector-config.yml:/etc/otel-collector-config.yml networks: - test_net ports: - "4318:4318" networks: test_net: ipam: config: - subnet: 172.23.0.0/16- 简化
Program.cs里的OTel配置,不需要手动指定Endpoint和Protocol,SDK会自动读取环境变量,资源配置也可以通过环境变量自动注入:
如果你不想用环境变量,也可以直接在代码里把端点改为服务名访问+全路径,兼容所有版本的导出器:builder.Services.AddOpenTelemetryTracing(tracerProviderBuilder => { tracerProviderBuilder .AddOtlpExporter() .AddSource(serviceName) .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation() .AddSqlClientInstrumentation(); });.AddOtlpExporter(opt => { opt.Endpoint = new Uri("http://otel:4318/v1/traces"); opt.Protocol = OtlpExportProtocol.HttpProtobuf; }) - 修改
- 配置完成后重新构建启动容器,可以进入web容器执行
curl http://otel:4318/v1/traces验证连通性,如果返回405 Method Not Allowed说明网络和端口已经正常连通,遥测数据可以正常上报。
内容的提问来源于stack exchange,提问作者Ellisein
相关产品推荐
相关产品推荐

