如何在Mac的同一网络上连接容器?

时间:2018-10-24 19:46:34

标签: macos docker scrapy docker-compose

我在尝试将我们的Scrapy Scheduler Spiderkeeper连接到我本地Mac环境上的scrapyd时遇到了困难。

这两种服务都位于同一网络的不同容器中。

Spiderkeeper使用SERVERS变量连接到我们的scrapyd服务器,但连接被拒绝。

在SSH进入Spiderkeeper并运行curl -v scrapyd:6800时,容器拒绝连接。

真正奇怪的是,当我通过SSH进入scrapyd容器并运行curl -v spiderkeeper:5000时,我得到了一个响应,并且当我们将相同的设置部署到kubernetes时,这些容器可以正常通信,但是对于本地目的,这是一场噩梦。

这里是docker-compose.yaml

version: '3'

services:
  scrapyd:
    build: .
    ports:
      - "6800:6800"
    depends_on:
      - spiderkeeper

  spiderkeeper:
    image: <our_spiderkeeper_image>
    ports:
      - "5000:5000"
    environment:
      SERVERS: "scrapyd:6800"

我在当地想念什么?

4 个答案:

答案 0 :(得分:1)

容器之间进行通信的要求是将容器置于同一docker网络上,您的应用程序侦听所有接口,并且客户端使用容器名称或服务别名和容器端口进行通信(而不是主机发布的端口)。 / p>

对于共享网络,默认情况下,docker compose yaml v2和更高版本会为您提供此功能(您只需手动定义网络即可覆盖此行为)。这里没事做。

对于客户端连接,您尝试与服务别名和容器端口进行通信,因此该部分也是正确的。


我们看不到该应用程序正在所有接口上正确侦听。解决故障的首选方法是运行调试容器:

docker run -it --rm --net container:${container_id} nicolaka/netshoot netstat -lnt

上面的${container_id}是您抓取的容器ID或名称。您应该看到一行:

0.0.0.0:6800
:::6800

如果相反,您看到一行:

127.0.0.1:6800
::1:6800

然后,您的应用程序正在侦听不支持的环回接口。您需要在应用程序配置中将其重新配置为0.0.0.0

如果您什么都看不到,则说明您的应用程序根本没有在网络上侦听,现在是时候开始调试应用程序,挖掘日志等了。


要调整的最后一件事是删除docker-compose文件中服务之间的依赖关系。这种依赖关系无法解决您要解决的所有问题,并且如果您迁移到群体模式,则根本无法使用。相反,最佳实践是将客户端应用程序配置为轮询远程服务是否可用,如果在适当的超时时间内未发生故障,则正常地失败。出现竞争状况很容易,其中docker在第一个服务完成启动并正在侦听端口之前启动第二个服务,从而导致连接被拒绝。 (我怀疑这是问题,因为您描述了手动登录,大概是在应用程序有足够的时间启动之后。)

请参阅此note in the docker documentation on depends_on,以了解为什么我反对这样做:

  

使用Depends_on时需要注意以下几点:

     
      
  • depends_on在启动Web之前不会等待db和redis处于“就绪”状态-仅在它们启动之前。如果您需要等待   要准备好服务,请参阅控制启动顺序以获取更多信息。   这个问题及其解决策略。

  •   
  • 版本3不再支持depends_on的条件形式。

  •   
  • 以群集模式(版本3的Compose文件)部署集群时,将忽略depends_on选项。

  •   

答案 1 :(得分:0)

如果我没记错的话,我必须为此行为执行以下操作。

  1. 创建本地桥接的docker网络

docker network create my_local_net --subnet 192.168.130.0/24 --attachable --gateway 192.168.130.1

  1. 最后添加到docker-compose文件。

    networks: default: external: name: my_local_net

答案 2 :(得分:0)

尝试一下:

version: '3'

services:
  scrapyd:
    build: .
    ports:
      - "6800:6800"
    depends_on:
      - spiderkeeper

    networks:
      mynetwork:
        aliases:
          - scrapyd
    hostname: scrapyd

  spiderkeeper:
    image: <our_spiderkeeper_image>
    ports:
      - "5000:5000"
    environment:
      SERVERS: "scrapyd:6800"
    networks:
      mynetwork:
        aliases:
          - spiderkeeper
    hostname: spiderkeeper

networks:
  mynetwork:
    driver: bridge

答案 3 :(得分:-1)

您尝试使用localhost:6800而不是scrapyd:6800吗?