Docker-Compose配置YARP网关转发微服务时出现503及地址分配错误
Docker + YARP 部署HTTP 503错误解决
本人是Docker与YARP新手,可能犯了基础错误。用ASP.NET Core搭建了YARP网关和一个微服务,单独运行两个容器时可正常工作,但使用docker-compose部署时出现HTTP 503错误(无法分配请求地址)。
网关appsettings.json配置
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ReverseProxy": { "Routes": { "route1": { "ClusterId": "cluster1", "Match": { "Path": "{**catch-all}" }, "Transforms": [ { "PathPattern": "{**catch-all}" } ] } //"route2": { // "ClusterId": "cluster2", // "Match": { // "Path": "/2/{**catch-all}" // }, // "Transforms": [ // { "PathPattern": "{**catch-all}" } // ] //} }, "Clusters": { "cluster1": { "LoadBalancingPolicy": "RoundRobin", "Destinations": { "destination1": { "Address": "http://host.docker.internal:5100/weatherforecast" } } } //"cluster2": { // "LoadBalancingPolicy": "RoundRobin", // "Destinations": { // "destination2": { // "Address": "https://172.35.0.2:5101/PageCall" // } // } //} } } }
docker-compose.yml配置
version: '3.4' services: gateway: image: ${DOCKER_REGISTRY-}gateway build: context: . dockerfile: Gateway/Dockerfile #ports: #- "5000:5000" #- "5001:5001" networks: proxybackend: posting-service: image: ${DOCKER_REGISTRY-}postingservice build: context: . dockerfile: Posting-service/Dockerfile #ports: #- "5100:5100" #- "5101:5101" networks: proxybackend: networks: proxybackend: name: proxybackend driver: bridge
docker-compose.override.yml配置
version: '3.4' services: gateway: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 ports: - "5000:80" - "5001:443" volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro posting-service: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 ports: - "5100:80" - "5101:443" volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
错误日志
System.Net.Http.HttpRequestException: Cannot assign requested address (localhost:5101) 2024-03-12 10:06:02 ---> System.Net.Sockets.SocketException (99): Cannot assign requested address 2024-03-12 10:06:02 at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) 2024-03-12 10:06:02 at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) 2024-03-12 10:06:02 at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|277_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) 2024-03-12 10:06:02 at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) 2024-03-12 10:06:02 --- End of inner exception stack trace --- 2024-03-12 10:06:02 at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) 2024-03-12 10:06:02 at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) 2024-03-12 10:06:02 at System.Net.Http.HttpConnectionPool.AddHttp2ConnectionAsync(HttpRequestMessage request) 2024-03-12 10:06:02 at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken) 2024-03-12 10:06:02 at System.Net.Http.HttpConnectionPool.GetHttp2ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) 2024-03-12 10:06:02 at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) 2024-03-12 10:06:02 at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) 2024-03-12 10:06:02 at Yarp.ReverseProxy.Forwarder.HttpForwarder.SendAsync(HttpContext context, String destinationPrefix, HttpMessageInvoker httpClient, ForwarderRequestConfig requestConfig, HttpTransformer transformer, CancellationToken cancellationToken)
问题根源
- 容器间通信地址错误:docker-compose创建的内部网络中,容器不能通过
host.docker.internal或宿主机端口访问其他容器,必须使用服务名(posting-service)+容器内部监听端口。 - YARP地址配置冗余:Destination的Address不应包含具体路径(
/weatherforecast),路径转发应由路由规则处理。
修复步骤
1. 修改网关appsettings.json配置
更新ReverseProxy的Cluster地址,替换为服务名+容器内部端口,去掉路径部分:
"Clusters": { "cluster1": { "LoadBalancingPolicy": "RoundRobin", "Destinations": { "destination1": { "Address": "http://posting-service:80" } } } }
当前路由的{**catch-all}规则会将网关收到的所有路径原样转发到微服务,确保微服务的接口路径(如/weatherforecast)能正常响应即可。
2. 验证容器网络连通性
进入网关容器执行命令,测试与微服务的连通性:
docker exec -it <gateway-container-id> curl http://posting-service:80/weatherforecast
如果能收到微服务的响应,说明网络连通正常。
3. 重新部署容器
修改配置后,重新构建并启动容器:
docker-compose down docker-compose up --build
4. 测试转发效果
访问网关地址http://localhost:5000/weatherforecast,此时YARP应能正确转发请求到微服务,返回预期结果。
内容的提问来源于stack exchange,提问作者coen donk
相关产品推荐
相关产品推荐

