如何在两个不同的 Docker 容器之间共享本地主机?

kol*_*vra 10 docker

我有两个不同的 Docker 容器,每个容器都有不同的映像。容器中的每个应用程序都使用非冲突端口。见docker-compose.yml

version: "2"

services:

  service_a:
    container_name: service_a.dev
    image: service_a.dev
    ports:
      - "6473:6473"
      - "6474:6474"
      - "1812:1812"
    depends_on:
      - postgres
    volumes:
      - ../configs/service_a/var/conf:/opt/services/service_a/var/conf

  postgres:
    container_name: postgres.dev
    hostname: postgres.dev
    image: postgres:9.6
    ports:
      - "5432:5432"
    volumes:
      - ../configs/postgres/scripts:/docker-entrypoint-initdb.d/
Run Code Online (Sandbox Code Playgroud)

我可以从主机(Mac OS)成功卷曲每个图像,例如curl -k https://localhost:6473/service_a/api/version作品。我想要做的是能够postgresservice_a容器中引用容器localhost就好像这两个容器是一个并且它们共享相同的localhost. 我知道如果我使用容器postgres.dev内部的主机名是可能的service_a,但我希望能够使用localhost. 这可能吗?请注意,我不是很精通网络或 Docker。

Mac 版本:10.12.4

Docker 版本:Docker 版本 17.03.0-ce,构建 60ccb22

我之前做了很多研究,但找不到解决方案。相关:https : //forums.docker.com/t/localhost-and-docker-compose-networking-issue/23100/2

BMi*_*tch 9

正确的方法:不要使用本地主机。而是使用 docker 内置的 DNS 网络并通过其服务名称引用容器。您甚至不应该设置容器名称,因为这会破坏缩放。


糟糕的方法:如果您不想使用 docker 网络功能,那么您可以切换到主机网络,但这会关闭一个非常关键的功能,其他 docker 功能(例如在自己的隔离网络中将容器连接在一起的选项)将不再工作。有了该免责声明,结果将如下所示:

version: "2"

services:

  service_a:
    container_name: service_a.dev
    image: service_a.dev
    network_mode: "host"
    depends_on:
      - postgres
    volumes:
      - ../configs/service_a/var/conf:/opt/services/service_a/var/conf

  postgres:
    container_name: postgres.dev
    image: postgres:9.6
    network_mode: "host"
    volumes:
      - ../configs/postgres/scripts:/docker-entrypoint-initdb.d/
Run Code Online (Sandbox Code Playgroud)

请注意,我删除了从容器到主机的端口发布,因为您不再处于容器网络中。我删除了主机名设置,因为您不应该从 docker 容器更改主机本身的主机名。

您引用的链接论坛帖子显示了当这是一个 VM 时,主机如何作为 localhost 与容器进行通信。这是一个预期的限制,但容器本身将能够作为本地主机相互通信。如果您使用基于 VirtualBox 的安装和 docker-toolbox,您应该能够通过 virtualbox IP 与容器通信。


真正错误的方式:滥用容器网络模式。该模式可用于调试容器网络问题和特殊用例,实际上不应该用于避免重新配置应用程序以使用 DNS。当你停止数据库时,你会破坏你的另一个容器,因为它会失去它的网络命名空间。

为此,您可能需要运行两个单独的 docker-compose.yml 文件,因为 docker-compose 将在采取任何操作之前检查网络是否存在。从 postgres 容器开始:

version: "2"
services:
  postgres:
    container_name: postgres.dev
    image: postgres:9.6
    ports:
      - "5432:5432"
    volumes:
      - ../configs/postgres/scripts:/docker-entrypoint-initdb.d/
Run Code Online (Sandbox Code Playgroud)

然后你可以在同一个网络命名空间中创建第二个服务:

version: "2"
services:
  service_a:
    container_name: service_a.dev
    image: service_a.dev
    network_mode: "container:postgres.dev"
    ports:
      - "6473:6473"
      - "6474:6474"
      - "1812:1812"
    volumes:
      - ../configs/service_a/var/conf:/opt/services/service_a/var/conf
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是正确的方法;不幸的是,Mac 版 Docker 似乎对 `host` 网络有问题:https://forums.docker.com/t/should-docker-run-net-host-work/14215 和 https://forums.docker.com/ t/beta-9-and-localhost-connection-via-net-host/10471/15 (2认同)