在docker_compose.yml中链接和depends_on之间的差异

its*_*jef 248 docker dockerfile docker-compose

根据Docker Compose的撰写文件文档:

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

我不明白链接到其他容器的目的,所以两个选项之间的差异对我来说似乎仍然很难.

如果有一个例子会更容易,但我找不到任何例子.

我注意到,当我将容器B与容器A链接时,容器B将在容器A的shell内"ping".

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

在此输入图像描述

Win*_*oon 181

这个答案适用于docker-compose 版本2,它也适用于版本3

使用depends_on时仍可以访问数据.

如果你看看docker docs Docker Compose和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
Run Code Online (Sandbox Code Playgroud)

链接和depends_on有什么区别?

链接:

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

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

docker inspect d54cf8a0fb98 |grep HostPort
Run Code Online (Sandbox Code Playgroud)

你可能会发现

"HostPort": "32777"
Run Code Online (Sandbox Code Playgroud)

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

web:
  links:
   - db
Run Code Online (Sandbox Code Playgroud)

依赖于取决于:

我从Giorgio Ferraris Docker-compose.yml找到了一个不错的博客:从V1到V2

当docker-compose执行V2文件时,它将自动在文件中定义的所有容器之间构建一个网络,并且每个容器将立即使用docker-compose.yml文件中定义的名称立即引用其他容器.

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

更新

依赖于取决于

服务之间的快速依赖,有两个影响:

  • 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
Run Code Online (Sandbox Code Playgroud)

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


Siy*_*iyu 72

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
Run Code Online (Sandbox Code Playgroud)

depends_on表达开始顺序(和隐式图像拉动顺序),这是一个很好的副作用links.

  • 常见的StackOverflow,为什么我必须向下滚动147和43点以下的答案才能找到实际上最好的1分答案. (9认同)
  • 如何在 docker-compose 中做同样的事情?我认为使用 docker compose,所有服务都已经在同一个网络中,无需添加任何内容。如果其中一个容器尝试连接到未处于就绪状态的容器,则容器之间的链接仍然不起作用。 (2认同)

Xio*_*Jin 45

[2016年9月更新]:此答案适用于docker撰写文件v1(如下面的示例撰写文件所示).对于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
Run Code Online (Sandbox Code Playgroud)

links,码内web将能够使用来访问数据库db:5432,假设端口5432中被暴露db的图像.如果depends_on使用,这是不可能的,但容器的启动顺序是正确的.

  • name:port在使用expose时甚至没有链接: (9认同)
  • "如果使用了depends_on,这是不可能的,但容器的启动顺序是正确的." 这是不正确的.如果你只是使用depends_on它会工作.您仍然可以使用数据库主机名访问`web`中的`db`. (6认同)

Tim*_*euw 7

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

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

在此长格式中,您可以指定要等待服务启动、正常运行或成功完成。

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

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

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

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

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

Run Code Online (Sandbox Code Playgroud)