docker_compose.yml 中的 links 和 depends_on 的区别

Posted

技术标签:

【中文标题】docker_compose.yml 中的 links 和 depends_on 的区别【英文标题】:Difference between links and depends_on in docker_compose.yml 【发布时间】:2016-06-20 07:34:52 【问题描述】:

根据 Docker Compose 的compose-file documentation:

depends_on - 表达服务之间的依赖关系。 links - 链接到另一个服务中的容器,并以与depends_on 相同的方式表达服务之间的依赖关系

我不明白链接到其他容器的目的,所以两个选项之间的区别对我来说似乎仍然相当困难。

如果有例子会容易得多,但我找不到任何例子。

我注意到,当我将容器 B 与容器 A 链接时,容器 B 将在容器 A 的外壳内“可ping”。

我在容器A的bash里面跑ping B得到了这样的结果(仅供参考,图片来自网络)

【问题讨论】:

--link 标志现在是 Docker 已弃用的遗留功能,文档建议“它最终可能会被删除”Docker: Legacy container links。建议不要使用Docker networks feature 或 docker compose 方法。我认为这对这里了解此功能的任何人都有帮助。 【参考方案1】:

此答案适用于 docker-compose version 2,它也适用于 version 3

您仍然可以在使用 depends_on 时访问数据。

如果您查看 docker docs Docker Compose and Django,您仍然可以像这样访问数据库:

version: '2'
services:
  db:
    image: postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

links和depends_on有什么区别?

链接:

为数据库创建容器时,例如:

docker run -d --name=test-mysql --env="MYSQL_ROOT_PASSWORD=mypassword" -P mysql

docker inspect d54cf8a0fb98 |grep HostPort

你可能会发现

"HostPort": "32777"

这意味着您可以从本地主机端口 32777(容器中的 3306)连接数据库,但每次重新启动或删除容器时,此端口都会更改。因此,您可以使用链接来确保始终连接到数据库,而不必知道它是哪个端口。

web:
  links:
   - db

取决于:

我发现 Giorgio Ferraris Docker-compose.yml: from V1 to V2 的一个不错的博客

当 docker-compose 执行 V2 文件时,它会自动在文件中定义的所有容器之间建立一个网络,每个容器都可以立即使用 docker-compose 中定义的名称来引用其他容器。 yml 文件。

所以我们不再需要链接了;链接用于启动我们的数据库容器和我们的网络服务器容器之间的网络通信,但这已经由 docker-compose 完成

更新

depends_on

表达服务之间的依赖关系,有两个作用:

docker-compose up 将按依赖顺序启动服务。在下面的例子中,db 和 redis 将在 web 之前启动。 docker-compose up SERVICE 将自动包含 SERVICE 的依赖项。在下面的例子中,docker-compose up web 也会创建并启动 db 和 redis。

简单示例:

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

注意:depends_on 在启动 web 之前不会等待 db 和 redis “准备好” - 仅在它们启动之前。如果您需要等待服务准备好,请参阅控制启动顺序以了解有关此问题的更多信息以及解决此问题的策略。

【讨论】:

我已经更新了我的答案,以澄清该答案是为撰写文件 v1 准备的。 这对版本 3 仍然有效吗? 是的,你可以看看https://docs.docker.com/compose/compose-file/compose-versioning/ “这意味着您可以从本地主机端口 32777(容器中的 3306)连接数据库但是每次重新启动或删除容器时此端口都会更改”如果您在 docker 中指定端口绑定,则不会-compose-file,它不会。而且由于这个问题是专门针对 docker-compose 的,所以我觉得这里的 docker run 示例完全无关紧要,无论如何容器都不是这样运行的。我错过了什么? 是的,如果您指定端口,您是对的。我的docker run example 想指出为什么我们需要使用depends_on 或链接而不是硬编码端口号。只是因为如果你不指定它,它每次都会改变。我认为这会让人们更多地了解depends_on或links。【参考方案2】:

links 选项被弃用后,帖子需要更新。

基本上,links 不再需要,因为它的主要目的是通过添加环境变量使另一个容器可以访问,隐含在 network 中。当容器放置在同一个网络中时,它们可以使用容器名称和其他别名作为主机相互访问。

对于docker run--link 也已弃用,应替换为自定义网络。

docker network create mynet
docker run -d --net mynet --name container1 my_image
docker run -it --net mynet --name container1 another_image

depends_on表示启动顺序(隐含拉图顺序),这是links的一个很好的副作用。

【讨论】:

如何在 docker-compose 中做同样的事情?我认为使用 docker compose 所有服务都已经在同一个网络中,不需要添加任何东西。如果其中一个容器尝试连接到未处于就绪状态的容器,则容器之间的链接仍然不起作用。 我在 docker-compose 版本 3 文档中看不到有关已弃用链接的信息:docs.docker.com/compose/compose-file/#links。我认为该选项不太有用,因为我们有共享网络和depends_on,但如果我正确阅读文档(他们只提到docker容器上的--link标志),它不会被弃用。 注意:同一网络中的容器(实际上是服务)可以通过服务名称访问,而不是容器名称。官方文档:docs.docker.com/compose/networking/#links【参考方案3】:

[2016 年 9 月更新]:此答案适用于 docker compose file v1(如下面的示例 compose 文件所示)。对于 v2,请参阅 @Windsooon 的另一个答案。

[原答案]:

在文档中很清楚。 depends_on决定依赖和容器创建的顺序,links不仅做这些,还做

链接服务的容器可以通过与别名相同的主机名访问,或者如果没有指定别名,则使用服务名。

例如,假设以下docker-compose.yml文件:

web:
  image: example/my_web_app:latest
  links:
    - db
    - cache

db:
  image: postgres:latest

cache:
  image: redis:latest

使用linksweb 中的代码将能够使用db:5432 访问数据库,假设端口 5432 在db 图像中公开。如果使用depends_on,这是不可能的,但是容器的启动顺序是正确的。

【讨论】:

你能举个例子吗?因为那部分是我仍然不清楚的。也许还有其他 compose-file 选项可以使它更具体。请给予更详细资讯。谢谢! 非常感谢!我得到了它。最后一个问题,请。所以,在我的特殊情况下,我正在部署我的 rails 应用程序,我应该使用 links 还是 depends_on 或者其中任何一个都可以?我目前的docker-compose.yml 使用depends_on,而且一切似乎都很好。 :) 如果不需要通过name:port直接访问其他容器,那么depends_on就可以了。 name:port 在您使用时即使没有链接也可以使用expose: “如果使用了depends_on,这是不可能的,但是容器的启动顺序是正确的。”。这是不正确的。如果您只使用depends_on,它会起作用。您仍然可以使用数据库主机名在web 中访问您的db【参考方案4】:

我认为这个问题的答案需要根据 v1.27.0 中首次引入的新 Docker compose 规范进行更新,该规范现在允许depends_on 的长格式:

https://github.com/compose-spec/compose-spec/blob/master/spec.md#long-syntax-1

在这种长格式中,您可以指定要等待服务启动、运行良好或成功完成。

如果您在该服务上生成health_check,Docker compose 就会知道该服务是健康的:

https://github.com/compose-spec/compose-spec/blob/master/spec.md#healthcheck

我建议阅读文档中的示例以了解更多详细信息,请参阅上面的链接!

举个简单的例子,这是我在 compose 文件中用于集成测试的内容:

services:
  cloud-broker:
    image: my.docker.registry/activemq-artemis:latest
    healthcheck:
      test: ["CMD-SHELL", "wget http://localhost:8161/ --delete-after --tries=3 2> /dev/null"]
      interval: 10s
      timeout: 5s
      retries: 5

  postgresql:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      POSTGRES_PASSWORD: "<my-secret>"
      POSTGRES_USER: "postgres"
      POSTGRES_DB: "postgres"
  
  # This service calls a script to create an empty database and the service-user
  postgresql-setup:
    image: postgres
    depends_on:
      postgresql:
        condition: service_healthy
    restart: "no"
    volumes:
      - "./scripts:/scripts"
    environment:
      PGPASSWORD: "<my-secret>"
    entrypoint: "psql -U postgres -d postgres -h postgresql -f /scripts/create-db.sql"

  my-business-service:
    image: my.docker.registry/my-business-service:latest
    depends_on:
      cloud-broker:
        condition: service_healthy
      postgresql-setup:
        condition: service_completed_successfully

【讨论】:

以上是关于docker_compose.yml 中的 links 和 depends_on 的区别的主要内容,如果未能解决你的问题,请参考以下文章

从汇总函数中提取参数系数

LIN(Local Interconnect Network)总线

Vector - CAPL - 等待并获取LIN数据

LIN通讯

汽车Lin总线特点

G016-OS-LIN-CENT-01 CentOS 7.8.2003 安装