如何在两个不同的Docker容器之间共享本地主机? [英] How to share localhost between two different Docker containers?

查看:293
本文介绍了如何在两个不同的Docker容器之间共享本地主机?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 版本: 2 

服务:

service_a:
container_name:service_a.dev
图片:service_a.dev
端口:
- 6473:6473
- 6474:6474
- 1812:1812
取决于:
-postgres
量:
-../ configs / service_a / var / conf:/ opt / services / service_a / var / conf

postgres:
container_name:postgres.dev
主机名:postgres.dev
图片:postgres:9.6
端口:
- 5432:5432
卷:
-../configs/postgres/scripts:/docker-entrypoint-initdb.d/

我可以从主机(Mac OS)成功卷曲每个图像,例如 curl -k https:// localhost:6473 / service_a / api / version 有效。我想做的是能够通过 service_a 容器引用 postgres 容器 localhost ,就好像这两个容器是一个容器,它们共享相同的 localhost 。我知道如果从 service_a 容器内部使用主机名 postgres.dev 是有可能的,但是我想才能使用 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

解决方案

正确的方法:不要使用localhost。而是使用docker内置的DNS网络,并按其服务名称引用容器。






不好的方法:如果不这样做,您甚至不应该设置容器名称。想要使用docker联网功能,则可以切换到主机联网,但这将关闭一个非常关键的功能,而其他docker功能(例如将容器在其自己的隔离网络中连接在一起的选项)将不再起作用。有了该免责声明,结果将类似于:

 版本: 2 

服务:

service_a:
容器名称:service_a.dev
映像:service_a.dev
network_mode:主机
取决于:
-postgres
卷:
-../configs/service_a/var/conf:/opt/services/service_a/var/conf

postgres:
container_name:postgres.dev
图片:postgres:9.6
network_mode:主机
卷:
-../configs/postgres/scripts:/docker-entrypoint-initdb.d/

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



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






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



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

 版本: 2 
服务:
postgres:
container_name:postgres.dev
图片:postgres:9.6
端口:
- 5432:5432
卷:
-../configs/postgres/scripts :/docker-entrypoint-initdb.d/

然后您可以在同一网络中进行第二项服务名称空间:

 版本: 2 
服务:
service_a:
容器名称:service_a .dev
图片:service_a.dev
network_mode:容器:postgres.dev
端口:
- 6473:6473
- 6474:6474
- 1812:1812
卷:
-../configs/service_a/var/conf:/opt/services/service_a/var/conf


I have two different Docker containers and each has a different image. Each app in the containers uses non-conflicting ports. See the 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/

I can cURL each image successfully from the host machine (Mac OS), e.g. curl -k https://localhost:6473/service_a/api/version works. What I'd like to do is to be able to refer to postgres container from the service_a container via localhost as if these two containers were one and they share the same localhost. I know that it's possible if I use the hostname postgres.dev from inside the service_a container, but I'd like to be able to use localhost. Is this possible? Please note that I am not very well versed in networking or Docker.

Mac version: 10.12.4

Docker version: Docker version 17.03.0-ce, build 60ccb22

I have done quite some prior research, but couldn't find a solution. Relevant: https://forums.docker.com/t/localhost-and-docker-compose-networking-issue/23100/2

解决方案

The right way: don't use localhost. Instead use docker's built in DNS networking and reference the containers by their service name. You shouldn't even be setting the container name since that breaks scaling.


The bad way: if you don't want to use the docker networking feature, then you can switch to host networking, but that turns off a very key feature and other docker capabilities like the option to connect containers together in their own isolated networks will no longer work. With that disclaimer, the result would look like:

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/

Note that I removed port publishing from the container to the host, since you're no longer in a container network. And I removed the hostname setting since you shouldn't change the hostname of the host itself from a docker container.

The linked forum posts you reference show how when this is a VM, the host cannot communicate with the containers as localhost. This is an expected limitation, but the containers themselves will be able to talk to each other as localhost. If you use a VirtualBox based install with docker-toolbox, you should be able to talk to the containers by the virtualbox IP.


The really wrong way: abuse the container network mode. The mode is available for debugging container networking issues and specialized use cases and really shouldn't be used to avoid reconfiguring an application to use DNS. And when you stop the database, you'll break your other container since it will lose its network namespace.

For this, you'll likely need to run two separate docker-compose.yml files because docker-compose will check for the existence of the network before taking any action. Start with the postgres container:

version: "2"
services:
  postgres:
    container_name: postgres.dev
    image: postgres:9.6
    ports:
      - "5432:5432"
    volumes:
      - ../configs/postgres/scripts:/docker-entrypoint-initdb.d/

Then you can make a second service in that same network namespace:

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

这篇关于如何在两个不同的Docker容器之间共享本地主机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆