如何在两个不同的Docker容器之间共享localhost?

时间:2017-04-21 16:32:08

标签: 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/

我可以从主机(Mac OS)成功地获取每个图像,例如curl -k https://localhost:6473/service_a/api/version有效。我想做的是能够从postgres容器通过service_a 引用localhost容器,就像这两个容器是一个并且它们一样分享相同的localhost。我知道如果我使用postgres.dev容器内的主机名service_a,我可以使用localhost。这可能吗?请注意,我不太熟悉网络或Docker。

Mac版:10.12.4

Docker版本:Docker版本17.03.0-ce,build 60ccb22

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

2 个答案:

答案 0 :(得分:3)

正确的方法:不要使用localhost。而是使用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/

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

链接的论坛帖子你引用显示当这是一个VM时,主机无法与容器作为localhost进行通信。这是一个预期的限制,但容器本身将能够作为localhost相互通信。如果您使用基于VirtualBox的安装与docker-toolbox,您应该能够通过虚拟机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/

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

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

答案 1 :(得分:1)

特别是对于Mac和本地测试,我设法使用docker.for.mac.localhost方法使多个容器工作。我记录了它http://nileshgule.blogspot.sg/2017/12/docker-tip-workaround-for-accessing.html