Docker Compose 循环容器链接

15

我正试图使用Docker将我们的开发环境容器化。这包括一些Google Appengine项目和一些最终托管在容器化VM中的Google Compute Engine服务。

我们目前的开发环境引导脚本在boot2docker中启动elasticsearch和nginx,其他应用程序在dev_appserver appengine沙盒中运行于localhost:{product port}。这个过程很难管理和维护,因为需要深入了解我们的应用程序如何通信。

我在docker-compose中遇到了一个错误,检测到容器之间存在循环依赖。

cs、vbc、aa和sr之间存在循环导入。

由于此配置仅用于开发环境(mac osx),是否有人对将所有产品套件的依赖关系链接在一起采取不同方法的建议或想法。

docker-compose.yml的部分内容:

elasticsearch:
  build: ./compute/containers/elasticsearch/elasticsearch
  ports:
    - "9200:9200"
  environment:
    - PROJECT_ID=localhost
nginx:
  build: ./compute/containers/elasticsearch/nginx
  links:
    - elasticsearch:localhost
  ports:
    - "9201:9201"
cs:
  build: ./CS
  command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8080 --admin_port=9080 --storage_path=/data/
  ports:
    - "8080:8080"
    - "9080:9080" 
  volumes:
   - /Users/source/CS/src:/src
   - /Users/source/CS/data:/data 
aa:
  build: ./AA
  command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8081 --admin_port=9081 --storage_path=/data/
  links:
    - vbc:vbc-local
    - st:st-local
    - elasticsearch:localhost    
  ports:
    - "8081:8081"
    - "9081:9081" 
  volumes:
   - /Users/source/AA/src:/src
   - /Users/source/AA/data:/data 
vbc:
  image: google/cloud-sdk
  command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8082 --admin_port=9082 --storage_path=/data/
  links:
    - cs:cs-local
    - sr:sr-local
    - sm:sm-local
    - ms:ms-local
    - st:st-local    
    - cis:cis-local
    - elasticsearch:localhost
  ports:
    - "8082:8082"
    - "9082:9082" 
  volumes:
   - /Users/source/VBC/src:/src
   - /Users/source/VBC/data:/data    
sr:
  build: ./SR
  command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8083 --admin_port=9083 --storage_path=/data/
  links:
    - cs:cs-local  
    - aa:aa-local      
  ports:
    - "8083:8083"
    - "9083:9083" 
  volumes:
   - /Users/source/SR/src:/src
   - /Users/source/SR/data:/data 

2
你可以考虑使用像consul这样的服务注册表 https://github.com/progrium/docker-consul 和一个自动注册器,例如https://registry.hub.docker.com/u/progrium/registrator/。使用这些组件,您可以在consul中注册您的容器,并且每个容器都必须从consul读取所需的信息,从而消除循环依赖关系。但是这会增加更多的复杂性。 - christian
4个回答

10

很快您将能够使用以下解决方案。

循环链接问题将在PR#1676中得到修复。

这里是他们处理此问题的方式。简单来说,他们将使容器能够无需链接即可相互通信。我已将更新添加到下面的Docker Compose文档中:

Compose中的网络

默认情况下,Compose为您的应用程序设置单个默认网络。每个服务的容器都加入默认网络,并且可以通过DNS在服务名称下被发现。

注意: 您的应用程序网络名称与“项目名称”相同,后者基于其所在目录的名称。请参阅CLI文档以了解如何覆盖它。

例如,假设您的应用程序位于名为myapp的目录中,而docker-compose.yml如下所示:

web:
  build: .
  ports:
    - "8000:8000"
db:
  image: postgres
当你运行docker-compose up时,会发生以下事情:
  1. 创建一个名为myapp的网络。
  2. 使用web的配置创建一个容器。它以web的名称加入到myapp网络中。
  3. 使用db的配置创建一个容器。它以db的名称加入到myapp网络中。
每个容器现在都可以查找主机名webdb,并获取相应容器的IP地址。例如,web的应用程序代码可以连接到URL postgres://db:5432 并开始使用Postgres数据库。
由于web显式映射了端口,因此也可以通过Docker主机的网络接口上的8000端口从外部访问它。
有关实验性Docker网络API的更多阅读材料: https://github.com/docker/docker/blob/master/experimental/networking_api.md

2
太棒了,期待尝试一下! - Jesse

2
现在使用v2 docker-compose文件定义,所有服务之间都可以直接访问,不需要链接部分。您可以直接从任何人向任何人(包括自己)的服务名称发出请求。因此,如果您想从cs向vbc发出请求,只需curl vbc。还可以通过在docker-compose文件的服务部分声明hostname键来定义具有自定义域名的服务。如果您想了解更多信息,网络API现在不再是实验性的:https://github.com/docker/compose/blob/master/docs/networking.md。这是您的v2 docker-compose文件,没有不必要的链接:
version: '2'

services:
  elasticsearch:
    build: ./compute/containers/elasticsearch/elasticsearch
    ports:
      - "9200:9200"
    environment:
      - PROJECT_ID=localhost
  nginx:
    build: ./compute/containers/elasticsearch/nginx
    ports:
      - "9201:9201"
  cs:
    build: ./CS
    command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8080 --admin_port=9080 --storage_path=/data/
    ports:
      - "8080:8080"
      - "9080:9080" 
    volumes:
     - /Users/source/CS/src:/src
     - /Users/source/CS/data:/data 
  aa:
    build: ./AA
    command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8081 --admin_port=9081 --storage_path=/data/
    ports:
      - "8081:8081"
      - "9081:9081" 
    volumes:
     - /Users/source/AA/src:/src
     - /Users/source/AA/data:/data 
  vbc:
    image: google/cloud-sdk
    command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8082 --admin_port=9082 --storage_path=/data/
    ports:
      - "8082:8082"
      - "9082:9082" 
    volumes:
     - /Users/source/VBC/src:/src
     - /Users/source/VBC/data:/data    
  sr:
    build: ./SR
    command: dev_appserver.py /src/ --host=0.0.0.0 --admin_host=0.0.0.0 --port=8083 --admin_port=9083 --storage_path=/data/
    ports:
      - "8083:8083"
      - "9083:9083" 
    volumes:
     - /Users/source/SR/src:/src
     - /Users/source/SR/data:/data 

0

这取决于你的链接:

sr requires aa
aa requires vbc
vbc requires sr
sr requires aa

sr requires cs
sr requires vbc
vbc requires sr
vbc requires cs

你可以看到这是循环的。


是的,我知道这个问题是由于链接引起的。然而,在我的单个docker-compose文件中,“统治它们所有”以进行开发环境引导,这是一个期望的问题。问题的目的是找出如何实现这一点。 - Jesse
你为什么想要将它们链接在一起?是为了通信吗?如果是的话,那么你有几个选择:1. 大使容器 2. 中间代理(我个人更喜欢这个)3. 还有其他几个试图链接远程容器的项目。 - Michael

0

你想要做的就是不要将两个容器链接在一起,否则会出现循环错误,我已经解决了。

示例:

mongo: # container image name
 image: mongo:latest
 ... 
 ...
springboot-app:
 image: anythink
 ...
 ...
 links:
 - mongo #this image mongo container image name
angular-app:
 image: anythink
 ...
 ...
 links:
 - springboot-app

你的回答目前写得不够清晰,请 [编辑] 添加更多细节以帮助其他人理解它是如何回答问题的。你可以在帮助中心找到更多有关撰写良好答案的信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接