Разница между ссылками и depen_on в docker_compose.yml

292

Согласно документации файла Docker Compose :

  • depends_on - Выразить зависимость между сервисами.
  • links- Связывать с контейнерами в другом сервисе, а также выражать зависимость между сервисами таким же образом, как depen_on .

Я не понимаю цели связывания с другими контейнерами, поэтому разница между двумя вариантами все еще кажется мне довольно сложной.

Было бы намного проще, если бы был пример, но я не могу его найти.

Я заметил, что когда я связываю контейнер B с контейнером A, тогда контейнер B будет «пингуемым» внутри оболочки контейнера A.

Я побежал ping Bв контейнер А bashи получил такой результат (просто для справки, изображение из Интернета)

введите описание изображения здесь

itsjef
источник
6
Этот --linkфлаг теперь является устаревшей функцией Docker, и в документации предлагается «Он может быть в конечном итоге удален» Docker: ссылки на устаревшие контейнеры . Рекомендуется не использовать функцию сетей Docker или метод создания Docker . Я подумал, что это будет полезно всем, кто узнает об этой функции.
Звезда

Ответы:

122

Сообщение нуждается в обновлении после того, как linksопция устарела.

По сути, linksбольше не требуется, потому что его основное назначение - сделать контейнер доступным для другого путем добавления переменной окружения, неявно включено в network. Когда контейнеры размещаются в одной и той же сети, они доступны друг другу, используя имя контейнера и другой псевдоним в качестве хоста.

For 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.

Siyu
источник
13
Обычный StackOverflow, почему мне нужно прокрутить вниз ответы ниже 147 и 43 балла, чтобы найти 1 балл ответа, который на самом деле лучший.
19
3
@ u8it Это природа времени и интернета.
Майкл Коул
Как сделать то же самое в docker-compose? Я думаю, что с помощью docker compose все сервисы уже находятся в одной сети, и нет необходимости что-либо добавлять. Однако связь между контейнерами не работает, если один из контейнеров пытается подключиться к контейнеру, который не находится в состоянии Готов.
Маккаси
Я не вижу информации об устаревших ссылках в документах docker-compose версии 3: docs.docker.com/compose/compose-file/#links . Я не считаю эту опцию слишком полезной, поскольку у нас есть общие сети и зависимость_, но это не рекомендуется, если я правильно прочитал документы (они упоминают только флаг --link на контейнере докера).
rideronthestorm
Примечание: контейнеры (фактически сервисы) в одной сети доступны по имени сервиса, а не по имени контейнера. Официальная документация: docs.docker.com/compose/networking/#links
GarryOne
194

Этот ответ предназначен для docker-compose версии 2, а также для версии 3

Вы по-прежнему можете получить доступ к данным, когда вы используете зависимость_.

Если вы посмотрите на документы Docker 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

В чем разница между ссылками и зависимости_?

ссылки по теме:

Когда вы создаете контейнер для базы данных, например:

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

зависит от:

Я нашел хороший блог от Джорджио Феррари Docker-compose.yml: от V1 до V2

Когда docker-compose выполняет файлы V2, он автоматически создает сеть между всеми контейнерами, определенными в файле, и каждый контейнер сразу же может ссылаться на другие, просто используя имена, определенные в файле docker-compose.yml.

И

Поэтому нам больше не нужны ссылки; ссылки использовались для запуска сетевого взаимодействия между нашим контейнером db и нашим контейнером веб-сервера, но это уже сделано 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

Примечание: depen_on не будет ждать, пока db и redis будут «готовы» перед запуском web - только до тех пор, пока они не будут запущены. Если вам нужно дождаться готовности службы, см. «Управление порядком запуска» для получения дополнительной информации об этой проблеме и стратегиях ее решения.

Windsooon
источник
Я обновил свой ответ, чтобы уточнить, что ответ был предназначен для создания файла v1.
Сюнбин Цзинь
1
Это все еще действует для версии 3?
Фабиомая
Да, вы можете взглянуть наhttps://docs.docker.com/compose/compose-file/compose-versioning/
Windsooon
«Это означает, что вы можете подключить базу данных через локальный порт 32777 (3306 в контейнере). Но этот порт будет меняться каждый раз, когда вы перезапускаете или удаляете контейнер», - если вы не укажете привязку порта в файле docker-compose-file, он не будет , И поскольку этот вопрос конкретно касается docker-compose, я считаю, что приведенный docker runздесь пример совершенно не имеет значения, так или иначе контейнер будет работать не так. Чего мне не хватает?
Андрей Савиных
Да, вы правы, если указали порт. В моем docker run примере я хочу указать, почему нам нужно использовать номер_связи или ссылки вместо жесткого кода номера порта. Просто потому, что если вы не укажете его, он будет меняться каждый раз. Я думаю, что это позволит людям понять больше о зависящих от них ссылках.
Windsooon
50

[Обновление сентября 2016 года]: Этот ответ был предназначен для файла компоновки 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

С помощью linksкода внутри webможно будет получить доступ к базе данных, используя db:5432порт 5432 в dbобразе. Если бы depends_onони использовались, это было бы невозможно, но порядок запуска контейнеров был бы правильным.

Сюнбин Джин
источник
Можете привести пример? Потому что эта часть - то, о чем мне до сих пор неясно. Возможно, есть другие параметры составного файла, которые могут сделать его более конкретным. Пожалуйста, предоставьте дополнительную информацию. Спасибо!
itsjef
Большое спасибо! Я понял. Последний вопрос, пожалуйста. Так что, в моем конкретном случае, я развертываю свое приложение rails, я должен использовать, linksили depends_onили любой из них в порядке? Мое текущее docker-compose.ymlиспользование depends_onи вещи, кажется, работают нормально. :)
itsjef
Если вам не нужен прямой доступ к другому контейнеру через, name:portтогда depends_onвсе в порядке.
Xiongbing Jin
9
имя: порт работает даже без ссылки, когда вы используете Expose:
Amit Goldstein
7
Msgstr "Если используются зависимости_, ​​это было бы невозможно, но порядок запуска контейнеров был бы правильным." Это не правильно. Это будет работать, если вы просто используете зависимость_ Вы все еще можете получить доступ к вашему имени dbв webбазе данных, используя имя хоста
prog.Dusan