Docker Swarm集群中如何从sv_web服务连接到sv_api服务?
我来帮你排查这个Docker Swarm服务间通信的问题——你遇到的情况很典型,主要是服务命名冲突、网络未共享这两个核心问题导致的,咱们一步步来解决:
1. 先修正服务部署的命名问题
你现在的两个部署命令都用了同一个栈名sv,而且两个docker-compose文件里的服务都叫web——这会直接导致第二个部署覆盖第一个的服务,根本不会存在两个独立的sv_web和sv_api服务!这是最关键的错误。
修改sv_web的部署文件(docker-compose-web.yml):
version: "3" services: sv_web: # 把服务名改成明确的sv_web,替换原来的web image: XXX/sv_web:latest ports: - "80:80" networks: - webnet networks: webnet: driver: overlay # Swarm环境下必须用overlay网络,显式指定更稳妥
然后用新的栈名部署:
docker stack deploy -c ~/docker-compose-web.yml web_stack
修改sv_api的部署文件(docker-compose-api.yml):
version: "3" services: sv_api: # 服务名改成sv_api,替换原来的web image: XXX/sv_api:latest ports: - "81:81" networks: - webnet networks: webnet: external: true # 指定复用已创建的webnet网络,避免每个栈单独建同名网络
用独立的栈名部署:
docker stack deploy -c ~/docker-compose-api.yml api_stack
2. 确保两个服务共享同一个Overlay网络
Docker Swarm里,服务间要通信必须在同一个Overlay网络里。如果两个栈各自创建webnet,它们会被自动加上栈名前缀,变成两个完全独立的网络,服务自然看不到彼此。
上面的配置已经通过external: true让sv_api复用sv_web创建的webnet网络。如果你想更稳妥,也可以先手动创建共享网络:
docker network create --driver overlay webnet
然后两个部署文件里的networks部分都设置external: true即可。
3. 使用正确的服务名访问
当两个服务在同一个Overlay网络后,就可以直接用服务名+容器内部端口访问了。你只需要在sv_web里把配置改成:
api_server = "sv_api:81"
这里的sv_api就是你在docker-compose里定义的服务名,Swarm的DNS服务会自动解析到对应的服务节点。
4. 验证连通性(如果还是有问题)
如果配置后还是无法连接,可以进入sv_web的容器里测试:
# 找到sv_web的容器ID docker ps | grep sv_web # 进入容器 docker exec -it <容器ID> sh # 用curl测试连通性 curl sv_api:81
还可以检查网络是否正确关联了服务:
# 查看webnet网络的详细信息,确认两个服务都在里面 docker network inspect webnet
核心要点回顾
- 不要用相同的栈名部署不同服务,否则会覆盖已有服务
- 服务间通信必须共享同一个Overlay网络
- 访问时要用docker-compose里定义的服务名,而不是栈名或者自定义的名称
- 确保容器内部端口和服务监听的端口一致(你的情况是81,没问题)
内容的提问来源于stack exchange,提问作者v v
相关产品推荐
相关产品推荐

