2017-09-05 142 views
0

我使用docker和microservices工作。想象一下,我们有3个服务:ReactPHP和docker:无法将主机从php解析到nginx容器

  user API 
     /
gateway API 
     \ 
      hotel API 

请求通过服务的网关。我有容器phpnginx,其中卷是相同的。接下来我给CONFIGS的名单:

server { 
    server_name gateway.api.loc; 

    root /var/www/der-ibe/ibe-gateway-api/web; 
    client_max_body_size 32m; 

    location/{ 
     try_files $uri @rewriteapp; 
    } 

    location @rewriteapp { 
     rewrite ^(.*)$ /app.php/$1 last; 
    } 

    location ~ ^/(app|app_dev|config)\.php(/|$) { 
     ... 
    } 
} 
server { 
    server_name hotel.api.loc; 
    root /var/www/der-ibe/ibe-hotel-api/web; 
    client_max_body_size 32m; 

    location/{ 
     try_files $uri @rewriteapp; 
    } 

    location @rewriteapp { 
     rewrite ^(.*)$ /app.php/$1 last; 
    } 

    location ~ ^/(app|app_dev|config)\.php(/|$) { 
     ... 
    } 
} 

...

泊坞窗,compose.yml

version: "3.1" 
services: 

    tphp: 
     build: docker/php 
     restart: always 
     container_name: my_tphp 
     extra_hosts: 
      - gateway.api.loc:172.14.10.10 
      - user.api.loc:172.14.10.10 
      - hotel.api.loc:172.14.10.10 
     networks: 
      - test 
     volumes: 
      - ../user-api:/var/www/user-api 
      - ../hotel-api:/var/www/hotel-api 
      - ./:/var/www/gateway-api 

    tnginx: 
     build: docker/nginx 
     restart: always 
     container_name: my_tnginx 
     ports: 
      - 80:80 
     networks: 
      test: 
       ipv4_address: 172.14.10.10 
     volumes: 
      - ../user-api:/var/www/user-api 
      - ../hotel-api:/var/www/hotel-api 
      - ./:/var/www/gateway-api 

networks: 
    ibe: 
     driver: bridge 
     ipam: 
     driver: default 
     config: 
      - subnet: 172.14.10.0/24 

如果我用简单的卷曲我可以达到酒店和用户API,以及我可以从他们那里得到回应,但如果我尝试用reactPHP来做到这一点 - 我不能!我的和平代码:

public function asyncGetRequest(Route $route, $params, $token) 
{ 
    $url = $this->buildURL($route, $params); 

    $loop = React\EventLoop\Factory::create(); 

    $dns = '172.14.10.10'; 
    $sender = Clue\React\Buzz\Io\Sender::createFromLoopDns($loop, $dns); 

    //$url = 'http://172.14.10.10:3000/api/quota/list'; 

    $client = new Clue\React\Buzz\Browser($loop, $sender); 
    //$client = new Clue\React\Buzz\Browser($loop); 

    $promise = $client->get($url, 
     [ 
      'Authorization' => $token, 
     ] 
    ); 

    /** @var Response $response */ 
    $response = new Response(); 

    try { 
     $response = Clue\React\Block\await($promise, $loop); 
    } catch (ResponseException $e) { 
     $this->logger->error($e->getMessage()); 
    } 

    dump($response->getBody()->getContents()); // I work on symfony 3.2 
    die; 
} 

线索库只是react的包装。所以我得到的错误是: DNS query for hotel.api.loc timed out和最后一个错误An error occurred in the underlying stream

所以我有一个问题:我做错了什么?为什么我通过curl访问nginx容器,但无法通过reactPHP访问?即使如果点DNS!

但是,如果我使用裸IP与端口,我可以达到它。我不支持dns,只是基本的知识。

UPDATE

我使用Linux的Debian(集装箱)。在Mac上工作。

有关逻辑:当请求URI是gateway.api.loc/api/hotel/list内部网关我们发送请求到hotel.api.loc到相同的URL(/api/hotel/list),接受回应并返回它。

我再说一遍,我有机会获得由卷曲域,但不能与reactPHP做到这一点,不明白为什么...

+0

你在使用什么操作系统?请更新您的问题 –

+0

我找到了解决方案,而不使用任何dns,只是直接请求。我请求'http:// 172.14.10.10/api/doc',头文件'Host'=>'user.api.loc'',它可以工作。 但是如果你告诉我为什么我不能直接在'gateway'里面申请'user.api.loc/api/doc'我会非常感谢 –

+0

很好,谢谢分享 –

回答

1

您的问题是,有对gateway.api.lochotel.api.loc没有DNS解析,它们在您的Nginx配置中被定义为路由,但在其他任何地方都没有DNS解析。您需要将您撰写改为下面这样他们也得到搬运工DNS解析

version: "3.1" 
services: 

    tphp: 
     build: docker/php 
     restart: always 
     container_name: my_tphp 
     extra_hosts: 
      - gateway.api.ibe.lazy-ants.loc:172.14.10.10 
      - user.api.ibe.lazy-ants.loc:172.14.10.10 
      - hotel.api.ibe.lazy-ants.loc:172.14.10.10 
     networks: 
      - test 
     volumes: 
      - ../user-api:/var/www/user-api 
      - ../hotel-api:/var/www/hotel-api 
      - ./:/var/www/gateway-api 

    tnginx: 
     build: docker/nginx 
     restart: always 
     container_name: my_tnginx 
     ports: 
      - 80:80 
     networks: 
      test: 
       ipv4_address: 172.14.10.10 
       aliases: 
        - hotel.api.loc 
        - gateway.api.loc 
     volumes: 
      - ../user-api:/var/www/user-api 
      - ../hotel-api:/var/www/hotel-api 
      - ./:/var/www/gateway-api 

networks: 
    ibe: 
     driver: bridge 
     ipam: 
     driver: default 
     config: 
      - subnet: 172.14.10.0/24 

该DNS解析外面解决,只会撰写的内部工作,而不是。所以,如果你室外使用,那么你将不得不作出主机条目

编辑-1

看来你的问题可能只是代码。您尝试使用网关IP作为DNS时,它不是DNS服务器。

变化

$loop = React\EventLoop\Factory::create(); 

$dns = '172.14.10.10'; 
$sender = Clue\React\Buzz\Io\Sender::createFromLoopDns($loop, $dns); 

//$url = 'http://172.14.10.10:3000/api/quota/list'; 

$client = new Clue\React\Buzz\Browser($loop, $sender); 

$loop = React\EventLoop\Factory::create(); 

$dns = '172.14.10.10'; 
//$sender = Clue\React\Buzz\Io\Sender::createFromLoopDns($loop, $dns); 
//$url = 'http://172.14.10.10:3000/api/quota/list'; 

$client = new Clue\React\Buzz\Browser($loop); 

,看看它是否有助于

+0

不好的消息:不要为我工作,我想不仅仅是为了我。别名只是容器名称的别名,不适用于主机名。 –

+0

别名用于使用DNS而非主机名的IP解析。请让我明白为什么它不起作用?你从哪里运行PHP代码?你得到了什么确切的错误? –

+0

就像我在示例中展示的那样。这个方法在控制上,来自服务的方法,并从它调用。 错误是:'[1/4] TimeoutException:5秒后超时+', '[2/4] TimeoutException:user.api.ibe.lazy-ants.net的DNS查询超时' '[3/4] RuntimeException:user.api.ibe.lazy-ants.net的DNS查询失败:太多重试' '[4/4] RuntimeException:在基础流中发生错误' (I ** edit docker -compose.yml **,请你修复它;谢谢) –

0

你看到的问题是ReactPHP的不完整的DNS实现。它不尊重/etc/resolv.conf,最近只增加了对/etc/hosts的支持。如果你不使用react/dns v0.4.11 or later那么这可能是问题,你应该尝试升级。

我不知道Docker如何解析DNS这些天的链接容器。几年前,它与一个提供主机名和相应IP的挂钩/etc/hosts一起工作。但是我认为现在Docker使用的是内部DNS服务器。由于ReactPHP不会自动选择它,所以在创建DNS解析器时必须明确地设置它。

尝试将127.0.0.11设置为名称服务器,它是Docker的内部DNS。