Como vincular serviços Docker entre hosts?


115

O Docker permite que servidores de vários contêineres se conectem entre si por meio de links e descoberta de serviço . No entanto, pelo que posso ver, essa descoberta de serviço é local do host. Gostaria de implementar um serviço que use outros serviços hospedados em uma máquina diferente.

Houve várias abordagens para resolver esse problema no Docker, como CoreOSjumpers , serviços locais de host que essencialmente fazem proxy para a outra máquina e um monte de projetos github para gerenciar implantações do Docker que parecem ter tentado oferecer suporte a este caso de uso .

Dado o ritmo de desenvolvimento, é difícil seguir as melhores práticas atuais. Portanto, minha pergunta é essencialmente:

  1. Qual (se houver) é o método predominante atual para vincular hosts no Docker, e
  2. Há algum plano para oferecer suporte a essa funcionalidade diretamente no sistema Docker?

Respostas:


58

Atualizar

Docker anunciou recentemente uma nova ferramenta chamada Swarm para orquestração Docker.

Enxame permite que você "junte" vários daemons do docker: primeiro você cria um swarm, inicia um gerenciador de swarm em uma máquina e faz com que os daemons do docker se "juntem" ao gerenciador de swarm usando o identificador do swarm. O cliente docker se conecta ao gerenciador de enxame como se fosse um servidor docker normal.

Quando um contêiner é iniciado com Swarm, ele é automaticamente atribuído a um nó livre que atende a quaisquer restrições que tenham sido definidas. O exemplo a seguir foi retirado da postagem do blog:

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

Uma das restrições com suporte é "node"permitir que você fixe um contêiner a um nome de host específico. O enxame também resolve links entre nós.

Em meus testes, tive a impressão de que o Swarm ainda não funciona muito bem com volumes em um local fixo (ou pelo menos o processo de vinculá-los não é muito intuitivo), então isso é algo para se manter em mente.

Swarm está agora em fase beta.


Até recentemente, o Ambassador Pattern era a única abordagem nativa do Docker para descoberta de serviço de host remoto. Esse padrão ainda pode ser usado e não requer nenhuma mágica além do Docker simples, pois o padrão consiste em um ou mais contêineres adicionais que agem como proxies.

Além disso, existem várias extensões de terceiros para tornar o Docker compatível com cluster. As soluções de terceiros incluem:

  • Conectando as pontes de rede Docker em dois hosts, existem soluções leves e diversas, mas geralmente com algumas ressalvas
  • Descoberta baseada em DNS, por exemplo, com skydock e SkyDNS
  • Ferramentas de gerenciamento do Docker, como Shipyard e ferramentas de orquestração do Docker. Veja esta pergunta para uma lista extensa: Como dimensionar contêineres Docker em produção

2
Então, basicamente, ainda não há uma maneira de vincular hosts cruzados de containers que não envolva o padrão ambasador ou contornar o docker e falar com o lxc diretamente?
user3012759

@ user3012759 O Ambassador Pattern é a única forma nativa estabelecida, mas Swarm (em alfa) é outra forma nativa que funciona substituindo o planejador Docker. Desculpe pela resposta tardia.
lyschoening

O SkyDock (ainda: 03/2015) não inclui suporte a vários hosts . O registrador (um projeto simples que pode funcionar com SkyDNS) faz, mas a configuração é mais manual (os serviços devem ter portas mapeadas para portas do host).
turtlemonvh

6
Minha investigação superficial do swarm sugere que ele está focado no gerenciamento de cluster e não na conectividade entre hosts. Essa deficiência é claramente indicada pela demonstração do próprio Docker youtube.com/watch?v=M4PFY6RZQHQ&t=3m37s
Bruno Bronosky,

1
@lyschoening Docker anunciou a rede multi-host nativa . Talvez você queira atualizar sua resposta
Thomasleveil

15

ATUALIZAÇÃO 3

Libswarm foi renomeado como swarm e agora é um aplicativo separado.

Aqui está a demonstração da página do github para usar como ponto de partida:

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

ATUALIZAÇÃO 2

A abordagem oficial agora é usar o libswarm; veja uma demonstração aqui

ATUALIZAR

Há uma boa essência para a comunicação de hosts openvswitch no docker usando a mesma abordagem.

Para permitir a descoberta de serviço, há uma abordagem interessante baseada em DNS chamada skydock .

Também há um screencast .


Este também é um bom artigo usando as mesmas peças do quebra-cabeça, mas adicionando também vlans no topo:

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

O patching não tem nada a ver com a robustez da solução. O Docker é, na verdade, apenas uma espécie de DSL nos contêineres do Linux e ambas as soluções nestes artigos simplesmente ignoram algumas configurações automáticas do Docker e recorrem diretamente aos contêineres do Linux.

Portanto, você pode usar as soluções com segurança e esperar para poder fazer isso de uma maneira mais simples, uma vez que o Docker irá implementá-las.


2
Não tem havido muita atividade no libswarm ultimamente. Será que a equipe do docker está se movendo em outra direção?
Raman de

12

Weave é uma nova tecnologia de rede virtual Docker que atua como um switch Ethernet virtual sobre TCP / UDP - tudo que você precisa é um contêiner Docker executando o Weave em seu host.

O que é interessante aqui é

  • Em vez de links, use IPs / nomes de host estáticos em sua rede virtual
  • Os hosts não precisam de conectividade total, uma malha é formada com base nos pares disponíveis e os pacotes serão roteados multi-hop para onde precisam ir

Isso leva a cenários interessantes como

  • Crie uma rede virtual através da WAN, nenhum dos contêineres Docker saberá ou se importará em qual rede real eles estão
  • Mova seus contêineres para diferentes hosts docker físicos, o Weave detectará o par de acordo

Por exemplo, há um guia de exemplo sobre como criar um cluster Cassandra de vários nós em seu laptop e alguns hosts em nuvem (EC2) com dois comandos por host. Eu lancei um cluster CoreOS com AWS CloudFormation, instalei o weave em cada in / home / core, além do meu laptop vagrant docker VM e coloquei um cluster em menos de uma hora. Meu laptop é protegido por firewall, mas o Weave parecia estar bem com isso, ele apenas se conecta aos seus pares EC2.


Pelo que entendi, weave é uma sobreposição de rede que funciona dentro de contêineres para conectividade de serviço, enquanto swarm é uma tecnologia de cluster que estende o docker CLI para orquestração de infraestrutura. A conectividade de infra-estrutura precisa ser feita fora do swarm (por exemplo, usando switches regulares) e orquestração de serviço fora do weave (usando, por exemplo, Mesos / Kubernetes). Isso corresponde à sua ideia de como funciona?
Henrik

Eu o veria da seguinte forma: docker compose trata de vinculação e orquestração de contêineres, docker swarm trata de executar docker em muitos hosts docker, socketplane (agora pertencente a docker) e weave são redes sobrepostas. Socketplane é baseado em openvswitch que é comumente usado para overlays em VMs (por exemplo, openstack); O Weave, por outro lado, é apenas docker. de tudo isso, Mesos / Kubernetes / Lattice são substitutos para docker swarm com experiências de usuário e níveis de escalabilidade um pouco diferentes do docker CLI.
Stuart Charlton

7

Atualizar

Docker 1.12 contém o chamado modo de enxame e também adiciona uma serviceabstração. Eles provavelmente não são maduros o suficiente para todos os casos de uso, mas sugiro que você os mantenha sob observação. O modo swarm pelo menos ajuda na configuração de vários hosts, o que não necessariamente torna a vinculação mais fácil. O servidor DNS interno do Docker (desde 1.11) deve ajudá-lo a acessar nomes de contêineres, se eles forem bem conhecidos - o que significa que os nomes gerados em um contexto Swarm não serão tão fáceis de endereçar.


Com a versão Docker 1.9, você terá uma rede multi-host integrada . Eles também fornecem um script de exemplo para provisionar facilmente um cluster de trabalho.

Você precisará de uma loja K / V (por exemplo, Consul), que permite compartilhar o estado entre os diferentes mecanismos do Docker em cada host. Cada mecanismo Docker precisa ser configurado com aquele armazenamento K / V e você pode então usar Swarm para conectar seus hosts.

Em seguida, você cria uma nova rede de sobreposição como esta:

$ docker network create --driver overlay my-network

Os contêineres agora podem ser executados com o nome da rede como parâmetro de execução:

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

Eles também podem ser conectados a uma rede quando já estiverem em execução:

$ docker network connect my-network my-container

Mais detalhes estão disponíveis na documentação .


6

O artigo a seguir descreve como conectar contêineres do docker em vários hosts: http://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/


1
Essa é uma solução muito boa; Eu também descobri. O que me preocupa é que o artigo só foi postado ontem e pede um patch do Docker. (Considerando que foi postado recentemente, eu esperaria um pouco para ver se eles mesclam esse patch no Docker).
lyschoening em

O Docker está em um estágio inicial de desenvolvimento, possivelmente nem todos os requisitos estão claros ainda e os requisitos definidos nem todos foram implementados. Portanto, o patch é necessário.
paweloque de

2
Esta é uma não resposta. Copie a resposta do artigo vinculado. Esse é o padrão SO.
Bruno Bronosky

6

É possível conectar várias sub-redes do Docker usando Open vSwitch ou Tinc. Preparei o Gists para mostrar como fazer:

A vantagem que vejo em usar essa solução em vez da --linkopção e do padrão embaixador é que a acho mais transparente: não há necessidade de contêineres adicionais e, mais importante, não há necessidade de expor portas no host. Na verdade, penso na --linkopção de ser um hack temporário antes que o Docker obtenha uma história melhor sobre configurações de vários hosts (ou vários daemon).

Nota: Eu sei que há outra resposta apontando para o meu primeiro Gist, mas não tenho carma suficiente para editar ou comentar essa resposta.


Como você faria a detecção de serviço? Digamos que se eu tiver o Redis em uma máquina e um aplicativo cliente em outra máquina, como o aplicativo cliente obterá o IP do serviço Redis?
lyschoening de

Da mesma maneira, você faria isso em um único host: fornecendo a si mesmo o IP / porta para serviços recém-iniciados, ou usando um armazenamento de chave / valor (por exemplo, etcd) ou usando um DNS que os serviços podem consultar. Gosto de usar DNS porque muitos serviços existentes podem usá-lo sem modificação.
noteed

1

Conforme mencionado acima, Weave é definitivamente uma solução viável para vincular contêineres Docker entre os hosts. Com base na minha própria experiência com ele, é bastante simples configurá-lo. Agora também tem serviço DNS que você pode endereçar ao contêiner por seus nomes DNS.

Por outro lado, há Flannel do CoreOS e Opencontrail da Juniper para conectar os contêineres aos hosts.


1

Parece que o docker swarm 1.14permite que você:

  • atribuindo o nome do host ao contêiner, usando --hostnametag, mas não consegui fazer funcionar, os contêineres não conseguem executar ping uns nos outros pelos nomes de host atribuídos.

  • atribuição de serviços à máquina usando --constraint 'node.hostname == <host>'

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.