不同docker-compose.yaml跨Docker网络curl可行吗?求解决方案
首先,你现在请求失败的原因很明确:在app-a容器里执行curl http://localhost:8012时,这里的localhost指向的是app-a容器自己的内部网络,而不是宿主机或者app-b容器。因为两个容器分别在独立的自定义Docker网络中,默认情况下这些网络是互相隔离的,所以app-a根本无法直接访问到app-b所在的网络空间。
不过这种跨网络的请求是完全可行的,给你几个实用的解决方案:
方案一:将两个容器加入同一个自定义网络(推荐)
这是Docker容器间通信的标准做法,既保留容器的隔离性,又能让它们通过DNS互相发现。
- 先创建一个共享的自定义网络:
docker network create shared-app-network
修改两个docker-compose文件,指定使用这个外部共享网络:
- 对于
docker-compose-app-a.yaml,修改networks部分:
version: "3" services: app: # 其他配置保持不变 networks: - shared-app-network networks: shared-app-network: external: true # 标记这个网络是已存在的外部网络- 同样修改
docker-compose-app-b.yaml的networks部分,和上面一致。
- 对于
重启两个服务:
docker-compose -f docker-compose-app-a.yaml down && docker-compose -f docker-compose-app-a.yaml up -d docker-compose -f docker-compose-app-b.yaml down && docker-compose -f docker-compose-app-b.yaml up -d
- 现在就可以在app-a里通过容器名访问app-b了:
docker exec -it app-a curl http://app-b:8012/user/1
Docker的自定义网络自带DNS解析功能,会自动把容器名app-b解析到它的容器IP,不需要手动指定IP。
方案二:通过宿主机IP访问(无需修改网络配置)
如果你不想调整网络,也可以利用端口映射的特性,通过宿主机的IP来访问app-b。
先找到宿主机的IP地址:
- Linux/macOS可以用
ifconfig或ip addr查看,Windows用ipconfig,通常是类似192.168.x.x或者10.x.x.x的私有IP。
- Linux/macOS可以用
在app-a容器里用宿主机IP代替localhost:
docker exec -it app-a curl http://你的宿主机IP:8012/user/1
这种方式依赖宿主机的端口映射(你已经在app-b的配置里做了8012:8012的映射),但缺点是如果宿主机IP变化,请求地址也要跟着改,灵活性不如方案一。
方案三:使用主机网络模式(不推荐)
这种方式会让容器直接使用宿主机的网络栈,失去容器的网络隔离性,除非特殊场景不建议使用。
修改任意一个docker-compose的service配置,添加network_mode: host:
services: app: # 其他配置保持不变 network_mode: host # 注意:如果用host模式,ports映射可以删掉,因为容器直接用宿主机端口
修改后重启服务,此时app-a里的localhost就指向宿主机,直接用curl http://localhost:8012/user/1就能访问了。
内容的提问来源于stack exchange,提问作者ALTELMA

