docker容器A可以使用什么URL来访问另一个docker容器B(同一台开发机,不同的项目)

时间:2019-03-23 07:06:57

标签: docker-compose docker-networking

假设仅在开发的某些阶段(烟熏测试一些api调用)很少需要这样做,最简单的方法是让Project Bar中的dockerized Web服务访问Project Foo中的dockerized web服务?

在开发Mac上,Docker Engine:18.09.2,Compose:1.23.2,我们有Project Foo和Project Bar,它们各自具有自己的docker-compose文件,每个文件都具有Web服务和数据库服务。

通常它们是独立运行的,并且是独立开发的。

但是Project Foo的网络服务托管的API仅偶尔需要我们从Project Bar的网络容器中访问

它们被分配给不同的主机端口,docker ps显示Project Foo使用端口0.0.0.0:3000-> 3000 / tcp(例如,我们使用localhost:3000从Mac的浏览器访问Web服务。 Bar使用端口0.0.0.0:3010-> 3010 / tcp

docker inspect对于Foo表示其IP地址为“ 172.18.0.3”(网关“ 172.18.0.1”),对于Bar表示其IP地址为“ 172.22.0.4”(网关“ 172.22.0.1”)< / p>

docker network ls显示它们都使用相同的“桥”驱动程序。

两个项目都在Mac上运行,总共有4个容器(Foo上的web + db和Bar上的web + db)

如果在Bar上运行的程序(Ruby)需要访问Foo上的REST URL,那么Foo上“ / api_test”的URL是什么?

在Bar Web容器中,我尝试了http://localhost:3000/api_testhttp://127.0.0.1:3000/api_test(这是我们在网络浏览器中使用的功能,因此并不真正希望它可以在容器到容器中使用) ),而我尝试了http://172.18.0.3:3000/api_testhttp://172.18.0.3/api_test都不起作用。

我看到了有关建立链接或Docker网络的在线参考,但是所有示例都是针对使用docker run而不是docker-compose的。我希望,如果您知道每个容器的Web服务器的IP和端口,那么应该使用正确的URL而无需任何额外的网络设置吗?

任何帮助将不胜感激。

首选手动分配的静态IP解决方案 ......在Docker之前,我们使用Vagrant,这很简单,在每个项目的Vagrantfile中,我们只需在同一私有子网192.168上手动为其分配IP .50.50和192.168.50.51,它们彼此“交谈”就很好了,我们可以简单地将这些IP“编码”到我们的开发代码中。 Docker似乎又增加了一层抽象,这让我感到困惑。

3 个答案:

答案 0 :(得分:0)

我终于找到了针对较新版本的Docker提及的SO线程,例如我正在使用主机名host.docker.internal访问主机,所以我的问题的一个答案是-因为我已经为Foo分配了不同的端口和Bar-Bar容器可以使用网址http://host.docker.internal:3000/api_test

但是仍然能够为每个容器分配静态IP仍然是首选,因此我将这个问题留待解决。

答案 1 :(得分:0)

您可以使用docker网络将容器A接入B。https://docs.docker.com/network/

使用docker网络-帮助。

  1. 创建网络

    • docker network create mynetwork
  2. 将容器ContainerA和containerB都放入此网络中,在本例中为mynetwork。

    • docker network connect mynetwork containerA

    • docker network connect mynetwork containerB

  3. 您现在可以将一个容器访问到另一个具有容器名称的容器。

您也可以使用ping对其进行测试。进行A或B容器打击并使用;

  1. apt-get update

  2. apt-get install iputils-ping

  3. 像在容器A中使用ping containerB一样进行测试。

例如1:

如果要在带有端口的apache虚拟主机设置中使用它;

  • ProxyPass "/" "http://containerB:3000"

例如2:

我有两个容器;分别命名为basemyphp。我正在端口3000上的基本容器中运行nodejs应用。而且我正在第二个容器myphp上运行apache和php。

基本上,我的nodejs应用程序为我提供了“ Hello Word”输出。它正在容器base上工作,下面是代码:

'use strict';

const express = require('express');

// Constants
const PORT = 3000;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello world\n');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`); 

基本上,我的php应用程序为我提供了所有源代码的连接地址。它正在容器myphp上工作。这是代码:

<?php
    $domain = 'http://base:3000';
    $handle = fopen($domain, 'r');
    $content = stream_get_contents($handle);
    fclose($handle);

    echo "<textarea rows='20' cols='80'>$content</textarea>";
?>

然后,我将这两个容器放在同一个网络中。当我运行index.php,这是myphp容器应用程序。它给我“你好词”;

因此,如果将容器放置在同一网络中,则可以使用"http://containerB:3000"之类的名称彼此访问,或者如果路由器正在监听“ / api_test” "http://containerB:3000/api_test"

最后,这就是我正在做的通信容器。我希望它也对您有用。

答案 2 :(得分:0)

TLDR :使用http://host.docker.internal

https://docs.docker.com/docker-for-mac/networking/

  

主机的IP地址正在更改(如果没有网络访问权限,则没有IP地址)。从18.03开始,我们的建议是连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。这是出于开发目的,不适用于Docker Desktop for Mac以外的生产环境。

我尝试过,这也适用于Windows。

例如,如果您在端口5000上的容器中运行python应用程序/微服务,则可以使用它来连接到它:

requests.get('http://host.docker.internal:5000')