2017-04-21 134 views
0

我有两个不同的Docker容器,每个人都有不同的图像。容器中的每个应用程序都使用无冲突的端口。看到docker-compose.yml如何在两个不同Docker容器之间共享本地主机?

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.devservice_a容器内,但我希望能够使用localhost。这可能吗?请注意,我并不是很熟悉网络或Docker。

Mac版:10.12.4

泊坞版本:多克尔版本17.03.0策,建立60ccb22

我已经做了一些比较以前的研究,也没有找到一个解决方案。 相关:https://forums.docker.com/t/localhost-and-docker-compose-networking-issue/23100/2

+0

几个(不同程度的hackiness)这样做的方式,但你怎么想呢? – johnharris85

+0

我会重申,你为什么要这么做?用'localhost'搞乱只会造成混淆。在同一个容器中运行这两个进程可以达到同样的效果,而不会出现这种冒犯。 – Matt

+0

我的用例是这样的:为了某些安全目的,这两个服务必须部署在同一个主机上,所以现实世界中的'service_a'将被配置为只侦听'localhost/127.0.0.1'。理想情况下,我会创建一个Docker镜像来同时拥有postgres和service_a,但这似乎不可行,因此我的方法在这里。 – kolistivra

回答

1

正确方法:不要使用本地主机。相反,使用docker内置的DNS联网功能,并通过服务名称引用容器。你甚至不应该设置容器名称,因为这会打破缩放。


糟糕的方法:如果你不想使用泊坞窗网络功能,则可以切换到主机网络,但关闭一个很重要的特征和其他泊坞窗功能,如连接容器的选择一起在自己的孤立网络将不再工作。与声明,结果会是什么样子:

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/ 

注意,我删除端口出版从容器到主机,因为你在一个集装箱网络已不再。而且我删除了主机名设置,因为你不应该从一个码头工人容器主机本身的主机名更改。

您参考的链接的论坛帖子显示了当它是虚拟机时,主机无法与本地主机通信。这是一个预期的限制,但容器本身就可以互相交谈为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/ 

然后你就可以在同一网络中的命名空间进行第二次服务:

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 
+0

我认为这是正确的路要走;不幸的是Docker for Mac似乎与'主机'网络有关: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 – kolistivra

+0

论坛帖子指出了尝试从主机访问localhost的容器的问题。这个问题和这个答案覆盖了从容器到localhost的容器。但是我会重申一下,请不要这样做,如果它坏了,你会保留所有的东西。 – BMitch

相关问题