Як зв’язати послуги Docker через хости?


115

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

У Docker було декілька підходів до вирішення цієї проблеми, такі як CoreOSjumpers , сервіси локальних серверів, які по суті є проксі на іншій машині, і ціла купа проектів github для управління розгортаннями Docker, які, схоже, намагалися підтримати цей кейс використання. .

Зважаючи на темпи розвитку, важко прослідкувати, які є поточні найкращі практики. Тому моє питання по суті:

  1. Який (якщо такий є) сучасний переважаючий метод з'єднання між хостами в Docker та
  2. Чи є плани щодо підтримки цієї функціональності безпосередньо в системі Docker?

Відповіді:


58

Оновлення

Нещодавно компанія Docker оголосила про новий інструмент під назвою " Рой" для оркестрації Докера.

Рой дозволяє вам "приєднатися" до декількох демонів докера: Ви спочатку створюєте рій, запускаєте диспетчера рій на одній машині, а демони докера "приєднуються" до менеджера рою за допомогою ідентифікатора рою. Клієнт докера підключається до диспетчеру рій, ніби це звичайний сервер докера.

Коли контейнер запускається з Swarm, він автоматично присвоюється вільному вузлу, який відповідає будь-яким визначеним обмеженням. Наступний приклад взято з допису в блозі:

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

Одне з підтримуваних обмежень - "node"це можливість прив’язати контейнер до конкретного імені хоста. Рій також розв'язує зв'язки між вузлами.

Під час тестування у мене склалося враження, що Swarm ще не працює з томами у фіксованому місці (або, принаймні, процес їх зв’язування не дуже інтуїтивно зрозумілий), тому це потрібно пам’ятати.

Рой зараз знаходиться у бета-фазі.


До недавнього часу образець посла був єдиним докерським підходом до виявлення послуг віддаленого хоста. Цей візерунок все ще може бути використаний і не вимагає ніякої магії поза звичайним Docker, оскільки шаблон складається з одного або декількох додаткових контейнерів, які виконують функції проксі.

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

  • Підключення мостів мережі Docker на двох хостах, легкі та різноманітні рішення існують, але, як правило, з деякими застереженнями
  • Відкриття на основі DNS, наприклад, з skydock та SkyDNS
  • Інструменти для управління докером, такі як верфі та інструменти для оркестрування Докер. Дивіться це питання для широкого списку: Як масштабувати контейнери Docker у виробництві

2
Так що в основному все ще немає способу зв’язати контейнери перехрещувати хости, що не передбачає шаблон ambasador або обхід докера та спілкування з lxc безпосередньо?
user3012759

@ user3012759 Pattern Pattern - це єдиний створений рідний спосіб, але Swarm (в альфа) - це ще один рідний спосіб, який працює за допомогою заміни планувальника Docker. Вибачте за пізню відповідь.
ліскощінг

SkyDock не містить (ще: 03/2015) підтримки для багатьох хостів . Реєстратор (спрощений проект, який може працювати з SkyDNS), але конфігурація є більш ручною (служби повинні мати порти, відображені для розміщення портів).
turtlemonvh

6
Моє коротке дослідження рою говорить про те, що він зосереджений на управлінні кластерами, а не на взаємодії між хостами. Цей недолік чітко вказаний у власному демонстрації
Докера

1
@lyschoening Docker оголосив рідної мульти хост мережі ви можете оновити свою відповідь
Thomasleveil

15

ОНОВЛЕННЯ 3

Libswarm був перейменований як рій і зараз є окремим додатком.

Ось демонстраційна сторінка 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 подивитися демо тут

ОНОВЛЕННЯ

Існує приємна суть для того, щоб openvswitch хости спілкувалися в докер, використовуючи той самий підхід.

Щоб дозволити відкриття сервісу, існує цікавий підхід, заснований на DNS під назвою skydock .

Існує також екранна трансляція .


Це також приємна стаття з використанням тих самих частин головоломки, але додаючи також вланів зверху:

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

Виправлення не має нічого спільного з надійністю рішення. Docker насправді є лише свого роду DSL для Linux Containers, і обидва рішення в цих статтях просто обходять деякі автоматичні настройки Docker і повертаються безпосередньо до Linux Containers.

Таким чином, ви можете безпечно використовувати рішення та чекати, коли зможете це зробити простішим способом, як тільки Docker його реалізує.


2
Останнім часом не спостерігається великої активності в лібревій теплі. Цікаво, чи рухається команда докерів в іншому напрямку?
Раман

12

Weave - це нова технологія віртуальної мережі Docker, яка виконує функцію віртуального перемикання Ethernet через TCP / UDP - все, що вам потрібно, це контейнер Docker, який працює Weave на вашому хості.

Що тут цікавого

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

Це призводить до таких цікавих сценаріїв, як

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

Наприклад, є приклад керівництва про те, як створити багатовузловий кластер Cassandra на своєму ноутбуці та кілька хмарних (EC2) хостів з двома командами на хост. Я запустив кластер CoreOS з AWS CloudFormation, встановив переплетення на кожному в / home / core, а також мій докер VM для ноутбука і отримав кластер менш ніж за годину. Мій ноутбук зафіксований, але Weave, здається, не в порядку з цим, він просто підключається до своїх партнерів EC2.


З того, що я розумію, переплетення - це мережеве накладання, яке працює всередині контейнерів для підключення до сервісу, в той час як рій - це технологія кластеризації, яка розширює докерний CLI для організації інфраструктури. Підключення до інфраструктури потрібно здійснювати за межами рою (наприклад, за допомогою звичайних комутаторів) та службового оркестрування за межами переплетення (використовуючи, наприклад, Mesos / Kubernetes). Чи відповідає це вашому уявленню про те, як це працює?
Генрік

Ось як я б це поглянув: docker compose - це зв'язування контейнерів та оркестрація, докер ройк - це проведення докера через безліч хокер-докерів, socketplane (тепер належить docker) та переплетення - це обидва мережі накладення. Socketplane базується на openvswitch, який зазвичай використовується для накладень у ВМ (наприклад, opentack); Плетіння з іншого боку - лише докер. З усіх перерахованих, Mesos / Kubernetes / Решітка є заміною для докерного рою з дещо іншим досвідом користувачів та рівнями масштабованості, ніж докер CLI.
Стюарт Чарлтон

7

Оновлення

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


З випуском Docker 1.9 ви отримаєте вбудовану мережу з кількома хостами . Вони також надають приклад сценарію щоб легко забезпечити робочий кластер.

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

Потім ви створюєте нову мережу накладання на зразок цього:

$ docker network create --driver overlay my-network

Тепер контейнери можна запускати з мережевим іменем як параметр run:

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

Вони також можуть бути підключені до мережі, коли вони вже запущені:

$ docker network connect my-network my-container

Більш детальна інформація доступна в документації .


6

У наступній статті добре описано, як підключити контейнери докера на декількох хостах: http://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/


1
Це дійсно дуже приємне рішення; Я також натрапив на це. Мене турбує те, що стаття була опублікована лише вчора, і вона закликає докерівського патча. (З огляду на те, як недавно це було опубліковано, я зачекав би трохи, щоб побачити, чи зливають вони цей патч у Докер).
лишчогінг

Докер знаходиться на ранній стадії розробки, можливо, ще не всі вимоги зрозумілі, а визначені вимоги не всі виконані. Отже, необхідна латка.
paweloque

2
Це невідповідь. Скопіюйте відповідь із пов’язаної статті. Це стандарт SO.
Бруно Броноський

6

Можна з'єднати кілька підмереж Docker разом, використовуючи Open vSwitch або Tinc. Я підготував Gists, щоб показати, як це зробити:

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

Примітка. Я знаю, що є ще одна відповідь, яка вказує на мій перший істот, але у мене недостатньо карми, щоб редагувати або коментувати цю відповідь.


Як би ви зробили службу виявлення? Скажіть, якщо у мене є Redis на одній машині, а клієнтська програма на іншій машині, як би клієнтська програма отримала IP-адресу служби Redis?
lyschoening

Таким же чином ви зробите це на одному хості: надайте собі IP / порт для нещодавно запущених служб, або використовуйте сховище ключа / значення (наприклад, etcd) або використовуйте DNS, до якого служби можуть запитувати. Мені подобається використовувати DNS, тому що багато існуючих сервісів можуть використовувати його без змін.
відмічено

1

Як згадувалося вище, Weave - це, безумовно, життєздатне рішення для з'єднання Docker-контейнерів між хостами. Виходячи з власного досвіду роботи з ним, це досить просто. Тепер він також має службу DNS, за якою ви можете адресувати контейнер за його іменами DNS.

З іншого боку, є фланель CoreOS і Juniper's Opencontrail для підключення контейнерів до хостів.


1

Схоже, рій докера 1.14дозволяє:

  • присвоєння імені хоста контейнеру, використовуючи --hostnameтег, але я не зміг змусити його працювати, контейнери не в змозі пінг один одного за присвоєними іменами хостів.

  • присвоєння послуг машинному використанню --constraint 'node.hostname == <host>'

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.