Как связать службы Docker через хосты?

Docker позволяет серверам из нескольких контейнеров соединяться друг с другом через ссылки и обнаружение служб. Однако из того, что я вижу, это обнаружение службы является локальным для хоста. Я хотел бы реализовать службу, которая использует другие службы, размещенные на другой машине.

Было несколько подходов к решению этой проблемы в Docker, таких как CoreOS jumpers, локальные службы хоста, которые по сути являются прокси-сервером для другой машины, и целый ряд проектов github для управления развертываниями Docker, которые появляются пытался поддержать этот вариант использования.

Принимая во внимание темпы развития, трудно понять, каковы нынешние лучшие практики. Поэтому мой вопрос по сути:

  1. Какой (если есть) текущий преобладающий метод для связи между хостами в Docker, и
  2. Есть ли планы по поддержке этой функциональности непосредственно в системе Docker?

Ответ 1

Обновить

Docker недавно анонсировал новый инструмент под названием Swarm для оркестровки Docker.

Swarm позволяет вам "присоединяться" к нескольким демонам-докерам: вы сначала создаете рой, запускаете менеджер роя на одной машине и получаете, чтобы демоны-докеры "присоединялись" к рору-менеджеру, используя идентификатор роя. Докер-клиент подключается к администратору роя, как если бы это был обычный докер-сервер.

Когда контейнер запускается с Swarm, он автоматически присваивается свободному узлу, который соответствует всем определенным ограничениям. Следующий пример взят из сообщения в блоге:

$ docker run -d -P -e constraint:storage=ssd mysql

Одним из поддерживаемых ограничений является "node" который позволяет вам прикрепить контейнер к определенному имени хоста. Рой также разрешает связи между узлами.

В моем тестировании у меня сложилось впечатление, что Swarm еще не очень хорошо работает с томами в фиксированном месте (или, по крайней мере, процесс их соединения не очень интуитивен), так что об этом следует помнить.

Рой сейчас в бета-фазе.


До недавнего времени шаблон Ambassador был единственным подходом Docker к обнаружению службы удаленного хоста. Этот шаблон все еще может использоваться и не требует никакой магии, кроме простого Docker, так как шаблон состоит из одного или нескольких дополнительных контейнеров, которые действуют как прокси.

Кроме того, существует несколько сторонних расширений для поддержки кластера Docker. Сторонние решения включают в себя:

  • При подключении сетевых мостов Docker к двум хостам существуют легковесные и различные решения, но обычно с некоторыми оговорками
  • Обнаружение на основе DNS, например, с помощью skydock и SkyDNS
  • Инструменты управления докером, такие как Верфь, и инструменты оркестровки Docker. Смотрите этот вопрос для обширного списка: Как масштабировать контейнеры Docker в производстве

Ответ 2

ОБНОВЛЕНИЕ 3

Libswarm был переименован в swarm и теперь является отдельным приложением.

Вот демонграмма github для использования в качестве отправной точки:

# create a cluster
$ swarm create
6856663cdefdec325839a4b7e1de38e8

# on each of your nodes, start the swarm agent
#  <node_ip> doesn't have to be public (eg. 192.168.0.X),
#  as long as the other nodes can reach it, it is fine.
$ swarm join --token=6856663cdefdec325839a4b7e1de38e8 --addr=<node_ip:2375>

# start the manager on any machine or your laptop
$ swarm manage --token=6856663cdefdec325839a4b7e1de38e8 --addr=<swarm_ip:swarm_port>

# use the regular docker cli
$ docker -H <swarm_ip:swarm_port> info
$ docker -H <swarm_ip:swarm_port> run ... 
$ docker -H <swarm_ip:swarm_port> ps 
$ docker -H <swarm_ip:swarm_port> logs ...
...

# list nodes in your cluster
$ swarm list --token=6856663cdefdec325839a4b7e1de38e8
http://<node_ip:2375>

ОБНОВЛЕНИЕ 2

Официальным подходом теперь является использование libswarm демонстрации здесь

UPDATE

для хостов openvswitch в докере используется тот же подход.

Чтобы разрешить обнаружение служб, существует интересный подход, основанный на DNS, называемый skydock.

Существует также screencast.


Это также хорошая статья, использующая одни и те же фрагменты головоломки, но добавление также vlans сверху:

http://fbevmware.blogspot.it/2013/12/coupling-docker-and-open-vswitch.html

Паттинг не имеет ничего общего с надежностью решения. Docker на самом деле является лишь своего рода DSL на Linux Containers, и оба решения в этих статьях просто обходят некоторые автоматические настройки Docker и возвращаются непосредственно в контейнеры Linux.

Таким образом, вы можете безопасно использовать решения и ждать, когда сможете сделать это проще, как только Docker его реализует.

Ответ 3

Weave - новая технология виртуальной сети Docker, которая действует как виртуальный коммутатор Ethernet через TCP/UDP. Все, что вам нужно, - это контейнер Docker, на котором работает Weave на вашем хоста.

Что интересно здесь

  • Вместо ссылок используйте статические IP-адреса/имена хостов в вашей виртуальной сети.
  • Хосты не нуждаются в полной подключенности, сетка формируется на основе того, что доступны одноранговые узлы, и пакеты будут маршрутизироваться с несколькими переходами туда, где им нужно идти.

Это приводит к интересным сценариям, таким как

  • Создайте виртуальную сеть через WAN, ни один из контейнеров Docker не узнает или не заботится о том, в какой реальной сети они находятся в
  • Переместите ваши контейнеры на разные физические докеры-хосты, Weave определит равноправное соединение

Например, существует примерное руководство о том, как создать кластер Cassandra multi- node на вашем ноутбуке и несколько узлов облака (EC2) с двумя командами на хост. Я запустил кластер CoreOS с AWS CloudFormation, установил переплетение на каждом из них в /home/core, плюс мой ноутбук-брандмауэр-докер VM, и получил кластер в течение часа. Мой ноутбук брандмауэром, но Weave, похоже, все в порядке, он просто подключается к своим сверстникам из EC2.

Ответ 4

Обновление

Докер 1.12 содержит так называемый режим роя, а также добавляет абстракцию service. Они, вероятно, недостаточно зрелы для каждого случая использования, но я предлагаю вам держать их под наблюдением. Режим роя, по крайней мере, помогает в настройке с несколькими хостами, что не обязательно упрощает привязку. Внутренний DNS-сервер Docker (с 1.11) должен помочь вам получить доступ к именам контейнеров, если они хорошо известны - это означает, что сгенерированные имена в контексте Swarm не будут так легко адресоваться.


С выпуском Docker 1.9 вы создадите в много хост-сети. Они также предоставляют пример script, чтобы легко обеспечить рабочий кластер.

Вам понадобится магазин K/V (например, Consul), который позволяет обмениваться данными между различными двигателями Docker на каждом хосте. Каждый движок Docker должен быть настроен с этим хранилищем K/V, и затем вы можете использовать Swarm для подключения ваших хостов.

Затем вы создаете новую оверлейную сеть следующим образом:

$ docker network create --driver overlay my-network

Теперь контейнеры могут запускаться с именем сети в качестве параметра запуска:

$ docker run -itd --net=my-network busybox

Они также могут быть подключены к сети, когда они уже запущены:

$ docker network connect my-network my-container

Более подробная информация доступна в документации.

Ответ 6

Можно объединить несколько подсетей Docker вместе, используя Open vSwitch или Tinc. Я подготовил Гистов, чтобы показать, как это сделать:

Преимущество, которое я вижу в использовании этого решения вместо опции --link и шаблона посла, заключается в том, что я считаю его более прозрачным: нет необходимости иметь дополнительные контейнеры и, что более важно, не нужно выставлять порты на хосте. На самом деле я думаю, что опция --link будет временным взломом, прежде чем Docker получит более приятную историю о настройках нескольких хостов (или нескольких демонах).

Примечание. Я знаю, что есть еще один ответ, указывающий на мой первый Gist, но мне не хватает кармы, чтобы отредактировать или прокомментировать этот ответ.

Ответ 7

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

С другой стороны, есть CoreOS Flannel и Juniper Opencontrail для подключения контейнеров через хосты.

Ответ 8

Кажется, что докерный рой 1.14 позволяет вам:

  • определить имя хоста для контейнера, используя тег --hostname, но я не смог заставить его работать, контейнеры не могут пинговать друг друга назначенными именами хостов.

  • назначение служб машине с помощью --constraint 'node.hostname == <host>'