Introdução ao modo Swarm

O que é o "modo Swarm"?

O modo Swarm é um recurso do Docker que fornece funcionalidades de orquestração de contêiner, incluindo clustering nativo de hosts do Docker e agendamento de cargas de trabalho de contêineres. Um grupo de hosts do Docker formam um cluster "Swarm" quando seus mecanismos do Docker estão em execução juntos no "modo Swarm". Para obter contexto adicional sobre o modo Swarm, consulte o site de documentação principal do Docker.

Nós gerenciadores e nós de trabalho

Um swarm é composto por dois tipos de hosts de contêiner: nós gerenciadores e nós de trabalho. Cada swarm é inicializado por meio de um nó gerenciador, e todos os comandos CLI do Docker para controlar e monitorar um swarm devem ser executados em um de seus nós gerenciadores. Os nós gerenciadores podem ser considerados os "zeladores" do estado Swarm — juntos, eles formam um grupo de consenso que mantém o reconhecimento do estado dos serviços em execução no swarm, e o trabalho deles é garantir que o estado real do swarm seja sempre condizente com o estado desejado, conforme definido pelo desenvolvedor ou administrador.

Observação: qualquer swarm pode ter vários nós gerenciadores, mas sempre deve ter pelo menos um.

Os nós de trabalho são orquestrados por swarm do Docker por meio de nós gerenciadores. Para ingressar em um swarm, um nó de trabalho deve usar um "token de associação" gerado pelo nó gerenciador quando o swarm foi inicializado. Os nós de trabalho simplesmente recebem e executam tarefas de nós gerenciadores, e, portanto, não exigem (e possuem) reconhecimento do estado do swarm.

Requisitos de sistema do modo Swarm

Pelo menos um sistema de computador físico ou virtual (para usar toda a funcionalidade do swarm, pelo menos dois nós são recomendados) com a Atualização do Windows 10 para Criadores ou Windows Server 2016 *com todas as atualizações recentes**, configuração como host de contêiner (consulte o tópico Contêineres do Windows no Windows 10 ou Contêineres do Windows no Windows Server para obter mais detalhes sobre como começar a usar contêineres do Docker no Windows 10).

*Observação: o Docker Swarm no Windows Server 2016 requer o KB4015217

Docker Engine v1.13.0 ou posterior

Portas abertas: as portas a seguir devem estar disponíveis em cada host. Em alguns sistemas, estas portas são abertas por padrão.

  • Porta TCP 2377 para comunicações de gerenciamento de cluster
  • Porta 7946 TCP e UDP para comunicação entre nós
  • Porta 4789 UDP para o tráfego da rede de sobreposição

Inicializando um cluster Swarm

Para inicializar um swarm, basta executar o comando a seguir em um dos hosts seu contêiner (substituindo <HOSTIPADDRESS> pelo endereço IPv4 local do computador host):

# Initialize a swarm 
C:\> docker swarm init --advertise-addr=<HOSTIPADDRESS> --listen-addr <HOSTIPADDRESS>:2377

Quando esse comando for executado em um determinado host de contêiner, o mecanismo do Docker nesse host iniciará a execução no modo Swarm como nó gerenciador.

Adicionando nós a um swarm

Observação: não são necessários vários nós para usar os recursos do modo Swarm e do modo Rede de sobreposição. Todos os recursos de swarm/sobreposição podem ser usados com um único host em execução no modo Swarm (ou seja, um nó gerenciador, colocado no modo Swarm com o comando docker swarm init).

Adicionando nós de trabalho a um swarm

Depois que um swarm é inicializado em um nó gerenciador, outros hosts podem ser adicionados ao swarm como nós de trabalho com outro comando simples:

C:\> docker swarm join --token <WORKERJOINTOKEN> <MANAGERIPADDRESS>

Aqui, <MANAGERIPADDRESS> é o endereço IP local de um nó gerenciador do swarm, e <WORKERJOINTOKEN> é o token de associação de nó de trabalho fornecido como resultado do comando docker swarm init executado pelo nó gerenciador. O token de associação também pode ser obtido com a execução de um dos seguintes comandos do nó gerenciador depois que o swarm é inicializado:

# Get the full command required to join a worker node to the swarm
C:\> docker swarm join-token worker

# Get only the join-token needed to join a worker node to the swarm
C:\> docker swarm join-token worker -q

Adicionando nós gerenciadores a um swarm

Nós gerenciadores podem ser adicionados a um cluster swarm com o seguinte comando:

C:\> docker swarm join --token <MANAGERJOINTOKEN> <MANAGERIPADDRESS>

Novamente, <MANAGERIPADDRESS> é o endereço IP local de um nó gerenciador do swarm. O token de associação, <MANAGERJOINTOKEN>, é um token de associação de gerenciador para o swarm, que pode ser obtido com a execução de um dos seguintes comandos em um nó gerenciador existente:

# Get the full command required to join a **manager** node to the swarm
C:\> docker swarm join-token manager

# Get only the join-token needed to join a **manager** node to the swarm
C:\> docker swarm join-token manager -q

Criando uma rede de sobreposição

Depois que um cluster swarm é configurado, redes de sobreposição podem ser criadas no swarm. Uma rede de sobreposição pode ser criada com a execução do seguinte comando em um nó gerenciador do swarm:

# Create an overlay network 
C:\> docker network create --driver=overlay <NETWORKNAME>

Aqui, <NETWORKNAME> é o nome que você gostaria de dar à sua rede.

Implantando serviços em um swarm

Depois que uma rede de sobreposição é criada, serviços podem ser criados e conectados à rede. Um serviço é criado com a seguinte sintaxe:

# Deploy a service to the swarm
C:\> docker service create --name=<SERVICENAME> --endpoint-mode dnsrr --network=<NETWORKNAME> <CONTAINERIMAGE> [COMMAND] [ARGS…]

Aqui, <SERVICENAME> é o nome que você gostaria de dar ao serviço – esse é o nome que você usará para referenciar o serviço por meio da descoberta de serviço (que usa o servidor DNS nativo do Docker). <NETWORKNAME> é o nome da rede à qual você gostaria de conectar esse serviço (por exemplo, "myOverlayNet"). <CONTAINERIMAGE> é o nome da imagem de contêiner que definirá o serviço.

Observação: o segundo argumento para esse comando, --endpoint-mode dnsrr, é necessário para especificar para o mecanismo do Docker que a política Round Robin de DNS será usada para equilibrar o tráfego de rede entre pontos de extremidade de contêiner de serviço. Atualmente, o Round Robin de DNS é a única estratégia de balanceamento de carga com suporte no Windows. Ainda não há suporte para a malha de roteamento para hosts docker do Windows, mas haverá em breve. Os usuários que atualmente buscam um estratégia alternativa de balanceamento de carga podem configurar um balanceador de carga externo (por exemplo, NGINX) e usar o modo publish-port do Swarm para expor as portas de host do contêiner pelas quais a carga será balanceada.

Dimensionando um serviço

Quando um serviço é implantado a um cluster swarm, as instâncias de contêiner que compõem esse serviço são implantadas no cluster. Por padrão, o número de instâncias de contêiner que dão suporte a um serviço — o número de "réplicas" ou "tarefas" para um serviço — é um. No entanto, um serviço pode ser criado com várias tarefas usando a opção --replicas para o comando docker service create ou dimensionando o serviço depois que ele é criado.

A escalabilidade do serviço é dos principais benefícios oferecido pelo Docker Swarm, e ele também pode ser usado com um único comando do Docker:

C:\> docker service scale <SERVICENAME>=<REPLICAS>

Aqui, <SERVICENAME> é o nome do serviço que está sendo dimensionado, e <REPLICAS> é o número de tarefas ou instâncias de contêiner para as quais o serviço está sendo dimensionado.

Exibindo o estado do swarm

Há vários comandos úteis para exibir o estado de um swarm e dos serviços em execução no swarm.

Listar nós do swarm

Use o comando a seguir para ver uma lista de nós que atualmente estão associados a um swarm, incluindo informações sobre o estado de cada nó. Este comando deve ser executado em um nó gerenciador.

C:\> docker node ls

No resultado desse comando, você verá que um dos nós está marcado com um asterisco (*); o asterisco simplesmente indica o nó atual – o nó no qual o comando docker node ls foi executado.

Listar redes

Use o comando a seguir para ver uma lista das redes que existem em um determinado nó. Para ver as redes de sobreposição, este comando deve ser executado em um nó gerenciador em execução no modo Swarm.

C:\> docker network ls

Listar serviços

Use o comando a seguir para ver uma lista dos serviços atualmente em execução em um swarm, incluindo informações sobre o estado deles.

C:\> docker service ls

Listar as instâncias de contêiner que definem um serviço

Use o comando a seguir para ver detalhes sobre as instâncias de contêiner em execução para um determinado serviço. O resultado deste comando inclui as IDs e os nós nos quais cada contêiner é executado, bem como informações sobre o estado dos contêineres.

C:\> docker service ps <SERVICENAME>

Clusters de SO misto Linux+Windows

Recentemente, um membro de nossa equipe postou uma breve demonstração de três partes sobre como configurar um aplicativo de SO misto Windows+Linux usando o Docker Swarm. É um ótimo ponto de partida para quem é iniciante no Docker Swarm ou para usá-lo para executar aplicativos de SO misto. Confira agora mesmo:

Inicializando um cluster de SO misto Linux+Windows

Inicializar um cluster swarm de SO misto é fácil, desde que as regras de firewall sejam configuradas corretamente e os hosts tenham acesso a um ao outro. Tudo que é preciso fazer para adicionar um host do Linux a um swarm é o comando docker swarm join padrão:

C:\> docker swarm join --token <JOINTOKEN> <MANAGERIPADDRESS>

Você também pode inicializar um swarm em um host do Linux usando o mesmo comando que executaria para inicializar o swarm em um host do Windows:

# Initialize a swarm 
C:\> docker swarm init --advertise-addr=<HOSTIPADDRESS> --listen-addr <HOSTIPADDRESS>:2377

Adicionando rótulos a nós de swarm

Para iniciar um serviço Docker em um cluster swarm de SO misto, deve haver uma maneira de diferenciar quais nós de swarm estão executando o sistema operacional ao qual esse serviço é designado, e quais não são. Os rótulos de objeto do Docker fornecem uma maneira útil de rotular os nós, para que os serviços possam ser criados e configurados para serem executados apenas em nós que correspondam ao seu sistema operacional.

Observação: os rótulos de objeto do Docker podem ser usados para aplicar metadados a uma variedade de objetos do Docker (incluindo imagens de contêiner, contêineres, volumes e redes) e para uma variedade de finalidades (por exemplo, os rótulos podem ser usados para separar os componentes 'front-end' e 'back-end' de um aplicativo, permitindo que os microsserviços de front-end sejam agendados somente nos nós rotulados como 'front-end' e que os microsserviços de back-end sejam agendados somente nos nós rotulados como 'back-end'). Neste caso, usamos rótulos nos nós para distinguir nós do sistema operacional Windows e nós do sistema operacional Linux.

Para rotular os nós de swarm existentes, use a seguinte sintaxe:

C:\> docker node update --label-add <LABELNAME>=<LABELVALUE> <NODENAME>

Aqui, <LABELNAME> é o nome do rótulo que você está criando – por exemplo, neste caso estamos distinguindo os nós pelo sistema operacional, então um nome lógico para o rótulo poderia ser "so". <LABELVALUE> é o valor do rótulo – neste caso, você pode optar por usar os valores "windows" e "linux". (É claro que você pode usar outras opções de nomenclatura para o rótulo e valores de rótulo, contanto que seja consistente). <NODENAME> é o nome do nó que você está rotulando; você pode lembrar-se dos nomes dos nós executando docker node ls.

Por exemplo, se você tiver quatro nós de swarm no cluster, incluindo dois nós do Windows e dois nós do Linux, os comandos de atualização de rótulo podem ter o seguinte formato:

# Example -- labeling 2 Windows nodes and 2 Linux nodes in a cluster...
C:\> docker node update --label-add os=windows Windows-SwarmMaster
C:\> docker node update --label-add os=windows Windows-SwarmWorker1
C:\> docker node update --label-add os=linux Linux-SwarmNode1
C:\> docker node update --label-add os=linux Linux-SwarmNode2

Implantando serviços em um swarm de SO misto

Com rótulos para seus nós de swarm, implantar serviços no cluster é fácil; basta usar a opção --constraint para o comando docker service create:

# Deploy a service with swarm node constraint
C:\> docker service create --name=<SERVICENAME> --endpoint-mode dnsrr --network=<NETWORKNAME> --constraint node.labels.<LABELNAME>=<LABELVALUE> <CONTAINERIMAGE> [COMMAND] [ARGS…]

Por exemplo, usando a nomenclatura de rótulo e valor de rótulo do exemplo acima, um conjunto de comandos de criação de serviço – um para um serviço baseado no Windows e outro para um serviço baseado no Linux – teria este formato:

# Example -- using the 'os' label and 'windows'/'linux' label values, service creation commands might look like these...

# A Windows service
C:\> docker service create --name=win_s1 --endpoint-mode dnsrr --network testoverlay --constraint 'node.labels.os==windows' microsoft/nanoserver:latest powershell -command { sleep 3600 }

# A Linux service
C:\> docker service create --name=linux_s1 --endpoint-mode dnsrr --network testoverlay --constraint 'node.labels.os==linux' redis

Limitações

Atualmente, o modo Swarm no Windows tem as seguintes limitações:

  • Não há suporte para a criptografia de plano de dados (ou seja, um tráfego de contêiner para contêiner usando a opção --opt encrypted)
  • A malha de roteamento para hosts docker do Windows ainda não tem suporte, mas terá em breve. Os usuários que atualmente buscam um estratégia alternativa de balanceamento de carga podem configurar um balanceador de carga externo (por exemplo, NGINX) e usar o modo publish-port do Swarm para expor as portas de host do contêiner pelas quais a carga será balanceada. Mais detalhes sobre isso abaixo.

Portas de publicação para pontos de extremidade de serviço

O recurso de malha de roteamento do Docker Swarm ainda não tem suporte no Windows, mas os usuários que procuram portas de publicação para seus pontos de extremidade de serviço podem fazer isso hoje usando o modo publish-port.

Para fazer com que as portas de host sejam publicadas para cada um dos pontos de extremidade de tarefas/contêiner que definem um serviço, use o argumento --publish mode=host,target=<CONTAINERPORT> para o comando docker service create:

# Create a service for which tasks are exposed via host port
C:\ > docker service create --name=<SERVICENAME> --publish mode=host,target=<CONTAINERPORT> --endpoint-mode dnsrr --network=<NETWORKNAME> <CONTAINERIMAGE> [COMMAND] [ARGS…]

Por exemplo, o seguinte comando criaria um serviço, 's1', para o qual cada tarefa será exposta por meio da porta de contêiner 80 e uma porta de host selecionada aleatoriamente.

C:\ > docker service create --name=s1 --publish mode=host,target=80 --endpoint-mode dnsrr web_1 powershell -command {echo sleep; sleep 360000;}

Depois de criar um serviço usando o modo publish-port, o serviço pode ser consultado para exibir o mapeamento de portas para cada tarefa de serviço:

C:\ > docker service ps <SERVICENAME>

O comando acima retornará detalhes sobre cada instância de contêiner em execução para seu serviço (entre todos os seus hosts do swarm). Uma coluna do resultado, a coluna "ports", incluirá informações de porta para cada host do formato <HOSTPORT>-><CONTAINERPORT>/tcp. Os valores de <HOSTPORT> serão diferentes para cada instância de contêiner, já que cada contêiner é publicado na própria porta de host.

Dicas e percepções

A rede transparente existente pode impedir a criação da rede de inicialização/sobreposição do swarm

No Windows, os drivers da rede transparente e de sobreposição exigem que um vSwitch externo seja vinculado a um adaptador de rede host (virtual). Quando uma rede de sobreposição é criada, um novo computador é criado e conectado a um adaptador de rede aberta. O modo de rede transparente também usa um adaptador de rede host. Ao mesmo tempo, qualquer adaptador de rede pode ser vinculado apenas a um comutador de cada vez – se um host tiver apenas um adaptador de rede, ele poderá conectar apenas um vSwitch externo ao mesmo tempo, seja esse vSwitch para uma rede de sobreposição ou para uma rede transparente.

Portanto, se um host do contêiner tiver apenas um adaptador de rede, talvez haja o problema em que a rede transparente impede a criação de uma rede de sobreposição (ou vice-versa), porque a rede transparente está ocupando a interface de rede virtual apenas do host.

Há duas maneiras de contornar esse problema:

  • Opção 1 - excluir a rede transparente existente: antes de inicializar um swarm, certifique-se de que não haja uma rede transparente existente no host do contêiner. Exclua as redes transparentes para verificar se há um adaptador de rede virtual livre em seu host para ser usado para a criação da rede de sobreposição.
  • Opção 2 - criar um adaptador de rede (virtual) adicional em seu host: em vez de remover qualquer rede transparente que esteja no host, você pode criar um adaptador de rede adicional em seu host para ser usado na criação da rede de sobreposição. Para fazer isso, basta criar um novo adaptador de rede externo (usando o PowerShell ou Gerenciador do Hyper-V); com a nova interface implantada, quando seu swarm for inicializado, o Serviço de Rede Host (HNS) o reconhecerá automaticamente no host e o usará para associar o vSwitch externo à criação da rede de sobreposição.