Docker compose服务名与外网冲突

Ath*_*lan 7 docker docker-compose docker-network

我正在尝试使用外部网络连接在 docker-compose 上运行的两个本地开发的项目。

从一方面来看,我有第一个要公开的应用程序。Compose 包含主机:apprabbit

version: '3.4'

services:
  app:
    # ...
  rabbit:
    # ...

networks:
  default:
    driver: bridge
Run Code Online (Sandbox Code Playgroud)

从另一边来看,我有第二个应用程序预计会看到第一个应用程序:

version: '3.4'

services:
  app:
    # ...
    networks:
      - paymentservice_default
      - default

networks:
  paymentservice_default:
    external: true
Run Code Online (Sandbox Code Playgroud)

rabbit.paymentservice_default可以到达主机。

然而,服务(第一)与(第二)app冲突:app

root@6db86687229c:/app# ping app.paymentservice_default
PING app.paymentservice_default (192.168.80.6) 56(84) bytes of data.

root@6db86687229c:/app# ping app
PING app (192.168.80.6) 56(84) bytes of data.
Run Code Online (Sandbox Code Playgroud)

一般来说,从第二个角度来看,主机appapp.paymentservice_default共享相同的 IP 使得app.paymentservice_default无法被发现。

这里的问题是,我是否有正确的配置并且可以在不更改服务名称的情况下避免app冲突?为什么有这个限制?考虑到每个 docker-compose 配置都是跨项目共享的,并且可以在微服务世界中开发。

$ docker-compose --version
docker-compose version 1.17.1, build unknown
$ docker --version
Docker version 19.03.4, build 9013bf583a
Run Code Online (Sandbox Code Playgroud)

谢谢。

mai*_*mic 2

我在Docker Playground上使用以下配置

paymentservice.docker-compose.yml

version: '3.4'

services:
  app:
    image: busybox
    # keep container running
    command: tail -f /dev/null
  rabbit:
    image: rabbitmq

networks:
  default:
    driver: bridge
Run Code Online (Sandbox Code Playgroud)

other.docker-compose.yml

version: '3.4'

services:
  app:
    image: busybox
    # keep container running
    command: tail -f /dev/null
    networks:
      - paymentservice_default
      - default

networks:
  paymentservice_default:
    external: true
Run Code Online (Sandbox Code Playgroud)

运行两个项目

$ COMPOSE_PROJECT_NAME=paymentservice docker-compose -f paymentservice.docker-compose.yml up -d
$ COMPOSE_PROJECT_NAME=other docker-compose -f other.docker-compose.yml up -d
Run Code Online (Sandbox Code Playgroud)

显示 Docker IP

$ docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }} {{range .NetworkSettings.Networks}} {{.IPAddress}}{{end}}' | sed 's#^/##';
Run Code Online (Sandbox Code Playgroud)

我有

other_app_1  172.20.0.2 172.19.0.4
paymentservice_app_1  172.19.0.3
paymentservice_rabbit_1  172.19.0.2
Run Code Online (Sandbox Code Playgroud)

我通过使用ping paymentservice_app_1(172.19.0.3)other_app_1app.paymentservice_default

$ docker exec -it other_app_1 ping -c 1 app.paymentservice_default
PING app.paymentservice_default (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.258 ms

--- app.paymentservice_default ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.258/0.258/0.258 ms
Run Code Online (Sandbox Code Playgroud)

我通过使用ping other_app_1(172.20.0.2)other_app_1app

$ docker exec -it other_app_1 ping -c 1 app
PING app (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.054 ms

--- app ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.054/0.054/0.054 ms
Run Code Online (Sandbox Code Playgroud)

如您所见,我可以paymentservice.docker-compose.yml从第二个应用程序(的)访问第一个应用程序(的other.docker-compose.yml)。

另一个方向也是如此。我通过使用ping other_app_1(172.19.0.4)paymentservice_app_1app.paymentservice_default

$ docker exec -it paymentservice_app_1 ping -c 1 app.paymentservice_default
PING app.paymentservice_default (172.19.0.4): 56 data bytes
64 bytes from 172.19.0.4: seq=0 ttl=64 time=0.198 ms

--- app.paymentservice_default ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.198/0.198/0.198 ms
Run Code Online (Sandbox Code Playgroud)

我通过使用ping paymentservice_app_1(172.19.0.3)paymentservice_app_1app

$ docker exec -it paymentservice_app_1 ping -c 1 app
PING app (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.057 ms

--- app ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.057/0.057/0.057 ms
Run Code Online (Sandbox Code Playgroud)

如您所见,我可以访问app这两个项目的服务。如果我想访问同一个项目的服务,我就使用项目的默认网络。如果我想访问另一个项目的服务,我会使用两个项目之间共享的外部网络。

注意:我建议通过使用命令行在项目外部创建共享网络来使这一点更加明确

docker network create shared-between-paymentservice-and-other
Run Code Online (Sandbox Code Playgroud)

并在两个项目中将其声明为外部。

注意:仍然存在这样的限制:如果您app在同一(外部)网络(某种名称空间)中有 3 个具有相同服务名称(例如 )的项目,服务发现可能无法工作。在这种情况下,重命名服务、使用多个外部网络、定义别名或使用完全不同的方法来发现/识别 Docker 容器可能是更好的主意。


后记

有这样的要求吗?我试图重现你的问题,但我不确定我是否做了和你一样的事情。例如,我不确定你在哪里跑步ping。Docker主机还是root@6db86687229cDocker容器?哪个容器?app我认为它是服务的Docker 容器other.docker-compose.yml。如果我遗漏了某些内容或误解了您的问题,请发表评论,我会更新我的答案。然后我可能会更详细地解释或提出另一个建议如何在多个 Docker Compose 项目之间进行服务发现。


附录

清理

$ COMPOSE_PROJECT_NAME=other docker-compose -f other.docker-compose.yml down
$ COMPOSE_PROJECT_NAME=paymentservice docker-compose -f paymentservice.docker-compose.yml down
Run Code Online (Sandbox Code Playgroud)

版本

$ docker --version
Docker version 20.10.0, build 7287ab3
$ docker-compose --version
docker-compose version 1.26.0, build unknown
Run Code Online (Sandbox Code Playgroud)