Docker中.NET 6 API与Prometheus通信连接被拒绝求助
.NET 6 API容器无法向Prometheus暴露指标(目标状态Down)
问题现象
- 访问
http://localhost:9090/targets显示myapi目标状态为Down,错误信息:Get "http://myapi:50505/metrics": dial tcp 192.168.65.2:50505: connect: connection refused - 进入API容器执行
netstat --tcp --listen --numeric-ports,仅5005端口处于监听状态,50505端口未被监听 - 已尝试但无效的操作:
- 在docker-compose的myapi端口配置中添加
"50505:50505" - 使用KestrelMetricServer指定1234端口并修改prometheus.yml
- 在prometheus.yml中改用
localhost:50505作为目标地址 - 在API Dockerfile中添加
EXPOSE 50505/tcp
- 在docker-compose的myapi端口配置中添加
- API与Prometheus日志均无报错信息
相关配置文件
prometheus.yml
global: scrape_interval: 15s scrape_configs: - job_name: "myapi" scrape_interval: 5s static_configs: - targets: ["myapi:50505"]
docker-compose.yml
version: '3.3' services: myapi: image: myapi container_name: myapi ports: - "7109:5005" networks: - mynet prometheus: image: prometheus ports: - "9090:9090" depends_on: - myapi networks: - mynet networks: mynet: driver: bridge
Prometheus Dockerfile
FROM prom/prometheus ADD ./prometheus.yml /etc/prometheus/
API Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build ARG BUILDCONFIG=RELEASE ARG VERSION=1.0.0 COPY ["myapi.csproj", "./src/myapi/"] WORKDIR ./src/myapi/ RUN dotnet publish -c $BUILDCONFIG -o out /p:Version=$VERSION FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY --from=build /src/myapi/out ./ EXPOSE 5005/tcp EXPOSE 50505/tcp ENTRYPOINT ["dotnet", "myapi.dll", "--urls", "http://+:5005"]
Program.cs 相关代码
... app.UseMetricServer(50505, "/prometheus"); app.UseRouting(); app.UseHttpMetrics(); app.Run();
端点方法代码
Counter _eventCounter = Metrics.CreateCounter("API_Events", "Entry Attempts", new string[] { "result" }); _eventCounter.WithLabels("test").Inc();
环境信息
- 主机系统:Mac M2 Ventura 13.2.1
- Docker版本:20.10.22,build 3a2c30b
解决方案
核心问题分析
UseMetricServer默认使用独立HttpListener监听指定端口,但在Docker容器环境中,该端口可能仅绑定到容器的127.0.0.1回环地址,导致容器外部(包括同网络的Prometheus)无法访问;同时.NET 6的默认配置可能限制了独立端口的监听权限。
修复步骤
修改Program.cs,将指标端点合并到Kestrel主端口
放弃独立端口,将Prometheus指标挂载到API的主服务端口(5005)上,避免额外端口监听问题:... // 移除端口参数,直接指定指标路径 app.UseMetricServer("/metrics"); app.UseRouting(); app.UseHttpMetrics(); app.Run();更新prometheus.yml的目标配置
调整目标地址为API容器的主端口,并指定指标路径:global: scrape_interval: 15s scrape_configs: - job_name: "myapi" scrape_interval: 5s static_configs: - targets: ["myapi:5005"] metrics_path: "/metrics"清理冗余配置
- 在API Dockerfile中移除
EXPOSE 50505/tcp(无需再暴露该端口) - docker-compose.yml中无需添加50505端口映射(同Docker网络内可直接通过容器名访问主端口)
- 在API Dockerfile中移除
重新构建启动容器
docker-compose down docker-compose build docker-compose up -d
验证
- 进入API容器执行
netstat --tcp --listen --numeric-ports,确认5005端口正常监听 - 访问
http://localhost:9090/targets,检查myapi目标状态是否变为Up - 主机访问
http://localhost:7109/metrics,验证指标是否正常返回
内容的提问来源于stack exchange,提问作者danielc
相关产品推荐
相关产品推荐

