Jak połączyć usługi Dockera między hostami?

115

Docker umożliwia serwerom z wielu kontenerów łączenie się ze sobą za pośrednictwem łączy i odnajdywania usług . Jednak z tego, co widzę, to wykrywanie usług odbywa się lokalnie. Chciałbym wdrożyć usługę, która korzysta z innych usług hostowanych na innym komputerze.

Było kilka podejść do rozwiązania tego problemu w Dockerzejumpers , takich jak CoreOS , lokalne usługi hosta, które zasadniczo proxy dla innej maszyny oraz cała masa projektów github do zarządzania wdrożeniami Dockera, które wydają się próbować wspierać ten przypadek użycia .

Biorąc pod uwagę tempo rozwoju, trudno jest śledzić aktualne najlepsze praktyki. Dlatego moje pytanie brzmi zasadniczo:

  1. Jaka (jeśli istnieje) jest obecnie dominująca metoda łączenia między hostami w Dockerze i
  2. Czy są jakieś plany dotyczące obsługi tej funkcjonalności bezpośrednio w systemie Docker?
lizoening
źródło

Odpowiedzi:

58

Aktualizacja

Docker niedawno ogłosił nowe narzędzie o nazwie Swarm for Docker orkiestration.

Swarm pozwala na „dołączenie” do wielu demonów docker: Najpierw tworzysz rój, uruchamiasz menedżera roju na jednej maszynie, a demony dockera „dołączają” do menedżera roju przy użyciu identyfikatora roju. Klient docker łączy się z menedżerem roju tak, jakby był zwykłym serwerem docker.

Gdy kontener został uruchomiony z Swarm, jest automatycznie przypisywany do wolnego węzła, który spełnia wszelkie zdefiniowane ograniczenia. Poniższy przykład pochodzi z posta na blogu:

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

Jednym z obsługiwanych ograniczeń jest "node"możliwość przypięcia kontenera do określonej nazwy hosta. Rój rozwiązuje również połączenia między węzłami.

Podczas moich testów odniosłem wrażenie, że Swarm nie działa jeszcze zbyt dobrze z woluminami w ustalonej lokalizacji (a przynajmniej proces ich łączenia nie jest zbyt intuicyjny), więc warto o tym pamiętać.

Swarm jest teraz w fazie beta.


Do niedawna wzorzec Ambassador był jedynym rodzimym podejściem Dockera do wykrywania usług hosta zdalnego. Ten wzorzec może być nadal używany i nie wymaga żadnej magii poza zwykłym Dockerem, ponieważ wzór składa się z co najmniej jednego dodatkowego kontenera, który działa jako proxy.

Ponadto istnieje kilka rozszerzeń innych firm, które umożliwiają obsługę klastra platformy Docker. Rozwiązania innych firm obejmują:

  • Łączenie mostów sieciowych Dockera na dwóch hostach, istnieją lekkie i różne rozwiązania, ale generalnie z pewnymi zastrzeżeniami
  • Wykrywanie oparte na DNS, np. Za pomocą Skydock i SkyDNS
  • Narzędzia do zarządzania Docker, takie jak Shipyard i Docker orchestration tools. Zobacz to pytanie, aby zapoznać się z obszerną listą: Jak skalować kontenery platformy Docker w środowisku produkcyjnym
lizoening
źródło
2
Więc zasadniczo nadal nie ma sposobu na połączenie kontenerów między hostami, który nie wymaga wzorca ambasadora lub pominięcia dockera i bezpośredniego komunikowania się z lxc?
user3012759
@ user3012759 Wzorzec ambasadora to jedyny znany sposób natywny, ale Swarm (w wersji alfa) to inny natywny sposób, który działa poprzez zastąpienie harmonogramu Dockera. Przepraszam za późną odpowiedź.
lyschoening
SkyDock nie obsługuje (jeszcze: 03/2015) obsługi wielu hostów . Rejestrator (prosty projekt, który może współpracować z SkyDNS) działa, ale konfiguracja jest bardziej ręczna (usługi muszą mieć porty zmapowane do portów hosta).
turtlemonvh
6
Moje pobieżne badanie roju sugeruje, że koncentruje się on na zarządzaniu klastrem, a nie na łączności między hostami. Ta wada jest jasno określona w demo
Dockera
1
@lyschoening Docker ogłosił natywną sieć z wieloma hostami, którą warto zaktualizować
Thomasleveil
15

AKTUALIZACJA 3

Libswarm został przemianowany na swarm i jest teraz oddzielną aplikacją.

Oto demo strony github do wykorzystania jako punkt wyjścia:

# 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>

AKTUALIZACJA 2

Oficjalnym podejściem jest teraz użycie libswarm, zobacz demo tutaj

AKTUALIZACJA

Jest całkiem niezłe sedno komunikacji hostów openvswitch w dockerze przy użyciu tego samego podejścia.

Aby umożliwić wykrywanie usług, istnieje interesujące podejście oparte na DNS o nazwie skydock .

Jest też screencast .


To także fajny artykuł wykorzystujący te same elementy układanki, ale dodający również vlany na wierzchu:

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

Patchowanie nie ma nic wspólnego z solidnością rozwiązania. Docker jest właściwie tylko rodzajem DSL w kontenerach Linuksa, a oba rozwiązania w tych artykułach po prostu omijają niektóre automatyczne ustawienia Dockera i wracają bezpośrednio do kontenerów Linuksa.

Możesz więc bezpiecznie korzystać z rozwiązań i poczekać, aż będziesz mógł to zrobić w prostszy sposób, gdy Docker je zaimplementuje.

tommasop
źródło
2
Ostatnio libswarm nie jest zbyt aktywny. Zastanawiam się, czy zespół dokerów zmierza w innym kierunku?
Raman
12

Weave to nowa technologia sieci wirtualnej Docker, która działa jako wirtualny przełącznik Ethernet przez TCP / UDP - wszystko, czego potrzebujesz, to kontener Docker z uruchomionym Weave na hoście.

Co tu jest interesujące

  • Zamiast linków używaj statycznych adresów IP / nazw hostów w sieci wirtualnej
  • Hosty nie potrzebują pełnej łączności, siatka jest tworzona na podstawie dostępnych peerów, a pakiety będą kierowane z wieloma przeskokami do miejsca, w którym muszą iść

Prowadzi to do ciekawych scenariuszy, takich jak

  • Utwórz sieć wirtualną w całej sieci WAN, żaden z kontenerów Docker nie będzie wiedział, w jakiej rzeczywistej sieci się znajduje, ani nie będzie go obchodzić
  • Przenieś swoje kontenery do różnych fizycznych hostów dockera, Weave odpowiednio wykryje peera

Na przykład istnieje przykładowy przewodnik dotyczący tworzenia wielowęzłowego klastra Cassandra na laptopie i kilku hostach w chmurze (EC2) z dwoma poleceniami na host. Uruchomiłem klaster CoreOS z AWS CloudFormation, zainstalowałem splot na każdym z elementów / home / core, a także moją maszynę wirtualną z laptopem vagrant docker i utworzyłem klaster w niecałą godzinę. Mój laptop ma zaporę ogniową, ale Weave wydawał się być w porządku, po prostu łączy się ze swoimi rówieśnikami EC2.

Stuart Charlton
źródło
Z tego, co rozumiem, splot to nakładka sieciowa, która działa wewnątrz kontenerów w celu zapewnienia łączności z usługami, podczas gdy rój to technologia klastrowania, która rozszerza interfejs wiersza polecenia platformy Docker w celu orkiestracji infrastruktury. Łączność w podczerwieni musi być wykonywana poza rojem (np. Przy użyciu zwykłych przełączników) i orkiestracja usług poza splotem (przy użyciu np. Mesos / Kubernetes). Czy to pasuje do Twojego wyobrażenia, jak to działa?
Henrik
Oto, jak bym na to spojrzał: docker compose dotyczy łączenia kontenerów i orkiestracji, docker swarm dotyczy uruchamiania platformy docker na wielu hostach docker, socketplane (obecnie należące do docker) i weave to sieci nakładkowe. Socketplane jest oparty na openvswitch, który jest powszechnie używany do nakładek w maszynach wirtualnych (np. Openstack); Z drugiej strony splot jest przeznaczony tylko dla dokerów. Spośród nich Mesos / Kubernetes / Lattice zastępują rój docker z nieco innymi doświadczeniami użytkownika i poziomami skalowalności niż docker CLI.
Stuart Charlton,
7

Aktualizacja

Docker 1.12 zawiera tak zwany tryb roju, a także dodaje serviceabstrakcję. Prawdopodobnie nie są wystarczająco dojrzałe dla każdego przypadku użycia, ale sugeruję, abyś je obserwował. Tryb roju pomaga przynajmniej w konfiguracji wielu hostów, co niekoniecznie ułatwia łączenie. Wewnętrzny serwer DNS platformy Docker (od wersji 1.11) powinien pomóc ci uzyskać dostęp do nazw kontenerów, jeśli są dobrze znane - co oznacza, że ​​wygenerowane nazwy w kontekście Swarm nie będą tak łatwe do zaadresowania.


Wraz z wydaniem Docker 1.9 uzyskasz wbudowaną obsługę wielu hostów . Dostarczają również przykładowego skryptu ułatwiającego obsługę działającego klastra.

Będziesz potrzebował sklepu K / V (np. Consul), który umożliwia udostępnianie stanu w różnych silnikach Docker na każdym hoście. Każdy silnik Dockera musi być skonfigurowany z tym sklepem K / V, a następnie możesz użyć Swarm do połączenia swoich hostów.

Następnie utwórz nową sieć nakładek w następujący sposób:

$ docker network create --driver overlay my-network

Kontenery można teraz uruchamiać z nazwą sieci jako parametrem uruchamiania:

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

Można je również podłączyć do sieci, gdy są już uruchomione:

$ docker network connect my-network my-container

Więcej szczegółów znajduje się w dokumentacji .

gesellix
źródło
6

Poniższy artykuł opisuje ładnie jak połączyć kontenery dockerowe na wielu hostach: http://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/

pawelok
źródło
1
To naprawdę bardzo fajne rozwiązanie; Ja też się z tym spotkałem. Martwię się tym, że artykuł został opublikowany dopiero wczoraj i wymaga aktualizacji Dockera. (Biorąc pod uwagę, jak niedawno został opublikowany, poczekałbym trochę, aby zobaczyć, czy scalą tę poprawkę z Dockerem).
lyschoening
Docker jest na wczesnym etapie rozwoju, prawdopodobnie nie wszystkie wymagania są jeszcze jasne, a zdefiniowane wymagania nie zostały wdrożone. Dlatego konieczne jest łatanie.
pawelok
2
To jest brak odpowiedzi. Skopiuj odpowiedź z połączonego artykułu. To jest standard SO.
Bruno Bronosky
6

Możliwe jest połączenie kilku podsieci Dockera razem za pomocą Open vSwitch lub Tinc. Przygotowałem Gists, aby pokazać, jak to zrobić:

Zaletą, jaką widzę stosując to rozwiązanie zamiast --linkopcji i wzorca ambasadora, jest to, że uważam je za bardziej przejrzyste: nie ma potrzeby posiadania dodatkowych kontenerów, a co ważniejsze, nie ma potrzeby eksponowania portów na hoście. Właściwie myślę o --linkopcji bycia tymczasowym hackiem, zanim Docker uzyska ładniejszą historię o konfiguracjach z wieloma hostami (lub wieloma demonami).

Uwaga: wiem, że istnieje inna odpowiedź wskazująca na moje pierwsze streszczenie, ale nie mam wystarczającej karmy, aby edytować lub komentować tę odpowiedź.

uwaga
źródło
Jak wykonałbyś wykrywanie usług? Powiedzmy, że jeśli mam Redis na jednym komputerze, a aplikację kliencką na innym, w jaki sposób aplikacja kliencka uzyska adres IP usługi Redis?
lyschoening
W ten sam sposób zrobiłbyś to na pojedynczym hoście: dostarczając sobie IP / port dla nowo uruchomionych usług lub używając magazynu kluczy / wartości (np. Etcd) lub używając DNS, do którego mogą wysyłać zapytania. Lubię używać DNS, ponieważ wiele istniejących usług może go używać bez modyfikacji.
noteed
1

Jak wspomniano powyżej, Weave jest zdecydowanie realnym rozwiązaniem do łączenia kontenerów Docker między hostami. Opierając się na moim własnym doświadczeniu z nim, skonfigurowanie go jest dość proste. Ma teraz również usługę DNS, do której można adresować kontenera za pomocą jego nazw DNS.

Z drugiej strony istnieje Flannel firmy CoreOS i Opencontrail firmy Juniper do okablowania kontenerów na hostach.

user2661697
źródło
1

Wygląda na to, że docker swarm 1.14umożliwia:

  • przypisanie nazwy hosta do kontenera za pomocą --hostnametagu, ale nie udało mi się to zrobić, kontenery nie są w stanie pingować się nawzajem przez przypisane nazwy hostów.

  • przypisywanie usług do korzystania z maszyny --constraint 'node.hostname == <host>'

saikek
źródło