如何通过发布端口与Docker Service通信?Windows环境问题排查
Docker Swarm服务访问404问题:多实例负载均衡实现方案
问题场景
你在单节点Windows Docker环境中,尝试运行同一ASP.NET Core API镜像的多个实例,期望通过Swarm实现负载均衡:
- 使用
docker run启动容器时,外部机器通过80端口能正常请求http://node_ip/api/node并获取唯一Guid响应; - 但用
docker service create创建5个副本服务后,同样的请求返回404错误。 - 你已经了解到
host模式端口发布的局限性,并且发现当前Windows环境下Docker路由网格未生效,想知道路由网格何时支持Windows。
你的测试环境:Windows 10 1703 Build 15063.0,Docker CE 17.12.0-ce-win46 (15048)
相关代码与命令
控制器代码
using Microsoft.AspNetCore.Mvc; using System; namespace MinimalDockerTest.Controllers { [Route("api/[controller]")] public class NodeController : Controller { [HttpGet] public IActionResult Get() { return Ok(NodeId); } private static Guid NodeId { get; } = Guid.NewGuid(); } }
Dockerfile
#Context is binary output folder, i.e. bin/publishoutput FROM microsoft/aspnetcore:2.0-nanoserver-sac2016 EXPOSE 80 WORKDIR /app Copy . . ENTRYPOINT ["dotnet", "MinimalDockerTest.dll"]
构建与运行命令
- 构建镜像:
docker build -t minimaltest . - 单容器运行(正常访问):
docker run -p 80:80 --name minimaltest minimaltest - Swarm服务创建(返回404):
docker service create -p 80:80 --replicas 5 --name minimaltest minimaltest
问题根源
你遇到的核心问题是早期Windows Docker版本对Swarm路由网格(Ingress Network)的支持不完善:
- 在Docker CE 17.12版本中,Windows容器的Swarm模式默认不支持ingress网络(路由网格依赖的核心组件),当你用
docker service create发布端口时,请求无法正确转发到后端的服务副本,因此返回404。 - 而
docker run是直接将容器端口映射到主机网络栈,绕过了Swarm的路由机制,所以能正常访问,但无法实现多实例的自动负载均衡。
解决方案
方案1:用反向代理实现负载均衡(适用于当前环境)
在主机上部署一个反向代理容器(比如Nginx),统一监听主机80端口,手动配置它将请求转发到所有API实例:
- 创建自定义Docker网络(确保容器间能互相访问):
docker network create --driver bridge minimal-net - 启动5个API容器,连接到上述网络,不映射主机端口:
docker run -d --name minimaltest-1 --network minimal-net minimaltest docker run -d --name minimaltest-2 --network minimal-net minimaltest docker run -d --name minimaltest-3 --network minimal-net minimaltest docker run -d --name minimaltest-4 --network minimal-net minimaltest docker run -d --name minimaltest-5 --network minimal-net minimaltest - 准备Nginx配置文件(
nginx.conf):http { upstream api_pool { server minimaltest-1:80; server minimaltest-2:80; server minimaltest-3:80; server minimaltest-4:80; server minimaltest-5:80; } server { listen 80; location / { proxy_pass http://api_pool; proxy_set_header Host $host; } } } events {} - 启动Nginx容器,映射主机80端口并挂载配置文件:
现在访问docker run -d -p 80:80 --name nginx-proxy --network minimal-net -v C:/path/to/nginx.conf:/etc/nginx/nginx.conf nginx:windowsservercorehttp://node_ip/api/node就能看到请求被均衡到不同的API实例。
方案2:升级环境启用路由网格(长期最优解)
Docker在后续版本中完善了Windows容器的路由网格支持:
- 支持版本要求:Windows 10 1809+(或Windows Server 2019+) + Docker CE 18.09及以上版本。
- 升级后,直接使用你原本的
docker service create命令即可:
此时Swarm路由网格会自动处理请求的负载均衡,无需额外配置。docker service create -p 80:80 --replicas 5 --name minimaltest minimaltest
关于Windows路由网格的支持时间
Docker首次在Docker CE 18.09版本中正式支持Windows容器的Swarm路由网格,对应的Windows系统需要是Windows 10 1809(October 2018 Update)或Windows Server 2019及以上版本。如果你能升级系统和Docker版本,就能直接享受路由网格带来的便捷负载均衡能力。
内容的提问来源于stack exchange,提问作者JSteward
相关产品推荐
相关产品推荐

