Docker Swarm
O Docker Swarm é uma ferramenta de orquestração de contêineres integrada ao Docker, projetada para facilitar a criação, o gerenciamento e a escalabilidade de aplicações distribuídas em um cluster de servidores. Ele transforma um grupo de hosts Docker em um cluster gerenciado, onde você pode implantar e gerenciar serviços de forma centralizada e com alta disponibilidade.
O principal benefício do Docker Swarm é a simplicidade na configuração e operação. Ele permite que você distribua seus contêineres automaticamente entre os nodes do cluster, garantindo equilíbrio de carga e resiliência. Se um nó falhar, o Swarm pode redistribuir os serviços para os nodes restantes, mantendo a aplicação em funcionamento.
Além disso, ele oferece suporte integrado para balanceamento de carga, facilita a criação de redes de sobreposição para comunicação entre contêineres em diferentes hosts e suporta atualizações contínuas de serviços com rollback automático em caso de falha. É uma escolha atraente para quem já usa o Docker, pois está integrado ao Docker CLI, é fácil de configurar e não exige ferramentas externas para pequenas e médias aplicações distribuídas.
Docker Swarm vs Kubernetes
Docker Swarm e Kubernetes são plataformas de orquestração de contêineres, mas têm abordagens diferentes para gerenciar aplicações distribuídas. O Docker Swarm é integrado ao Docker, fácil de configurar e oferece simplicidade para criar clusters e gerenciar serviços com recursos como escalabilidade, balanceamento de carga e alta disponibilidade. É ideal para quem busca uma solução rápida e simples para clusters pequenos ou médios.
O Kubernetes, por outro lado, é uma plataforma mais robusta e complexa, projetada para ambientes em larga escala e com demandas avançadas. Ele oferece funcionalidades como gerenciamento detalhado de estado desejado, maior flexibilidade na configuração de redes e volumes, atualizações avançadas com estratégias como rolling updates e blue-green deployments, além de extensibilidade com operadores e APIs.
Enquanto o Swarm é mais simples e fácil de aprender, o Kubernetes é mais poderoso e amplamente suportado, mas tem uma curva de aprendizado maior. A escolha entre eles depende do tamanho, complexidade e necessidades do seu ambiente: Swarm para simplicidade e Kubernetes para escala e personalização.
Por que usar Orquestração de Containers?
A orquestração de contêineres é essencial para gerenciar aplicações modernas em ambientes distribuídos. Com ferramentas como Docker Swarm e Kubernetes, você pode automatizar tarefas complexas que seriam difíceis de gerenciar manualmente, garantindo eficiência, resiliência e escalabilidade.
Em pequenos números, os contêineres são relativamente fáceis de implantar e gerenciar manualmente. No entanto, à medida que as aplicações baseadas em contêineres se tornam cada vez mais comuns e a necessidade de gerenciá-las em larga escala cresce, isso se torna impraticável sem automação, já que podemos chegar facilmente a ter mais de 2000 containers em operação.
Por exemplo, pipelines de integração e entrega contínuas (CI/CD) ou práticas de DevOps são praticamente impossíveis de implementar sem a orquestração de contêineres. Essas ferramentas automatizam tarefas operacionais relacionadas à implantação e execução de aplicações e serviços containerizados, proporcionando escalabilidade e eficiência.
Migração de Workload
A orquestração detecta automaticamente a falha de um nó no cluster e redistribui os contêineres que estavam sendo executados naquele nó com problema para outros nodes saudáveis. Isso garante que sua aplicação continue funcionando sem interrupções, minimizando o impacto de falhas de hardware ou software.
Escalabilidade de Contêineres
Com a orquestração, você pode escalar sua aplicação para cima ou para baixo com facilidade. Seja adicionando mais réplicas de um serviço durante picos de uso ou reduzindo a quantidade de recursos em horários de baixa demanda, o processo é automático e eficiente, garantindo que os recursos sejam usados de forma otimizada.
Gerenciamento Centralizado
A orquestração fornece uma interface centralizada para gerenciar todos os contêineres do cluster. Você pode monitorar, atualizar e configurar serviços em um único lugar, sem precisar acessar cada nó individualmente. Isso simplifica operações e melhora a produtividade da equipe.
Self-Healing
Em caso de falhas de contêineres, a orquestração reinicia automaticamente os serviços afetados para restaurar o estado desejado da aplicação. Isso reduz a necessidade de intervenções manuais e melhora a confiabilidade do sistema, garantindo alta disponibilidade.
Load Balancing
A orquestração distribui automaticamente o tráfego entre os contêineres disponíveis, garantindo que nenhum nó ou serviço fique sobrecarregado. Isso melhora o desempenho da aplicação e a experiência do usuário, mesmo em cenários de alta carga.
Arquitetura do Docker Swarm
A arquitetura do Docker Swarm segue um modelo distribuído, com componentes bem definidos que garantem alta disponibilidade, escalabilidade e gerenciamento simplificado. Os principais elementos de sua arquitetura incluem os Managers e Workers.
Cluster do Swarm
Um Swarm é um cluster de máquinas (físicas ou virtuais) que executam o Docker e estão unidas sob um único gerenciamento. As máquinas do cluster podem ser de dois tipos:
- Nodes Managers: Nodes responsáveis pela orquestração e controle do cluster.
- Workers Nodes: Nodes que executam as tarefas atribuídas pelos managers.
Os node managers são responsáveis por gerenciar o estado do cluster usando o Raft Consensus Algorithm (para garantir consistência do estado entre os managers). Também agendam serviços e alocam tarefas para os workers executarem, além de expor APIs e interfaces para controle do cluster.
Para garantir alta disponibilidade, recomenda-se ter um número ímpar de managers (geralmente 3 ou 5), pois o Raft exige um quórum para tomar decisões.
Os nodes workers são responsáveis por executar as tarefas atribuídas pelo manager e reportar o estado das tarefas de volta ao manager. Os workers não tomam decisões sobre o estado do cluster; eles apenas executam comandos recebidos. Vale notar que um node manager pode atuar como worker node no Docker Swarm. Nesse caso, ele acumula as duas funções: participa do gerenciamento do cluster como manager e também executa tarefas atribuídas a workers, como rodar contêineres.
Usar nodes managers como workers não é considerado uma boa prática em ambientes de produção. Já em ambientes de teste, é perfeitamente aceitável que um node manager também atue como worker node. Essa configuração simplifica a infraestrutura, reduz os custos e facilita a criação de pequenos clusters para desenvolvimento ou validação de configurações.
Quorum
O quorum é a quantidade mínima necessária de algo para que uma ação, processo ou situação seja válida ou possa ocorrer. Se tratando de Docker Swarm, é quantidade de Nodes Managers que precisam concordar para que decisões importantes sejam tomadas em um cluster distribuído. Ele é fundamental para garantir a consistência e a integridade do estado do cluster, especialmente em sistemas baseados em consenso, como o Raft Consensus Algorithm, utilizado pelo Swarm.
Em um ambiente distribuído, falhas podem ocorrer, como nodes inativos ou problemas de conectividade entre partes do cluster. O quórum é o mecanismo que garante que múltiplos conjuntos de nodes não entrem em desacordo sobre o estado do cluster. Mesmo que alguns nodes falhem, o cluster pode continuar funcionando, desde que o número necessário de nodes managers ativos seja mantido.
Se o quórum não for atingido, o cluster perde a capacidade de tomar decisões administrativas. As tarefas em execução nos worker nodes continuarão rodando, mas os nodes do cluster não poderão ser adicionados, atualizados ou removidos. Além disso, tarefas novas ou existentes não poderão ser iniciadas, interrompidas, movidas ou atualizadas.
Sempre configure um número ímpar de nodes managers (3, 5, 7, etc.) para reduzir a probabilidade de empates e melhorar a tolerância a falhas. Porém, evite adicionar um número excessivo de managers, pois isso pode aumentar a sobrecarga de comunicação. Não há limite para o número de nodes managers, mas a decisão sobre quantos usar deve equilibrar desempenho e tolerância a falhas. Mais managers aumentam a resiliência do cluster, mas reduzem o desempenho de gravação, pois mais nodes precisam reconhecer as atualizações propostas, gerando maior tráfego de rede.
Abaixo deixo uma tabela com a tolerância a falhas.
Número Total de Managers | Número Máximo de Falhas Toleradas |
---|---|
1 | 0 |
3 | 1 |
5 | 2 |
7 | 3 |
Resumindo, um número ímpar de managers é preferível porque adicionar um manager a um número par não aumenta a tolerância a falhas, já que o consenso exige a maioria dos integrantes do quórum. Por exemplo:
- 3 managers e 4 managers: Ambos toleram a falha de apenas 1 node.
- 5 managers e 6 managers: Ambos toleram a falha de até 2 nodes.
Cluster Service
Um service é a definição de como executar um contêiner no Swarm. Ele deve incluir:
- A imagem Docker que será usada.
- O número de réplicas do contêiner.
- Configurações de rede, volumes e políticas de atualização.
O serviço é implementado como uma ou mais tarefas (tasks) distribuídas entre os nodes do cluster.
Cluster Tasks
Uma task é uma unidade de trabalho que executa um contêiner específico no Swarm. Cada contêiner corresponde a uma única tarefa. Elas são gerenciadas pelo manager e distribuídas entre os nodes.
Cluster Network
O Docker Swarm oferece um modelo de rede overlay que conecta todos os nodes do cluster. Isso permite que contêineres se comuniquem de forma segura e transparente, independentemente do nó onde estão sendo executados. Os tipos de redes incluem:
- Ingress Network: Usada para encaminhar tráfego externo para os serviços do Swarm.
- Overlay Network: Interconecta os serviços em diferentes nodes do cluster.
- Host Network: Usa a rede local do nó para contêineres.
Load Balancing
O Swarm realiza balanceamento de carga automaticamente. Ele distribui as requisições para os serviços entre as réplicas disponíveis, garantindo desempenho e alta disponibilidade.
Ambiente de testes
Para testar nosso laboratório com Docker Swarm vou usar usar um Vagrantfile para subir duas máquinas virtuais e já instalar o Docker (também será instalado o Docker Compose e Docker Swarm), vou deixar abaixo o arquivo.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
resultado = system("virsh net-info default 2>/dev/null >&2")
if $?.success?
puts ""
else
system("virsh net-define $(pwd)/docker-network.xml")
system("virsh net-start docker")
end
# Definição dos servidores:
servers = [
{ :hostname => "manager1", :ip => "192.168.145.10", :mem => "1024", :cpu => 1 },
{ :hostname => "manager2", :ip => "192.168.145.11", :mem => "1024", :cpu => 1 },
{ :hostname => "node1", :ip => "192.168.145.12", :mem => "2048", :cpu => 2 },
{ :hostname => "node2", :ip => "192.168.145.13", :mem => "2048", :cpu => 2 }]
# Cria as VMs:
servers.each do |server|
config.vm.define "#{server[:hostname]}" do |set|
set.vm.hostname = "#{server[:hostname]}"
set.vm.network "private_network", ip: "#{server[:ip]}"
set.vm.box = "generic/ubuntu2204"
set.vm.provider :libvirt do |kvm|
kvm.memory = "#{server[:mem]}"
kvm.cpus = "#{server[:cpu]}"
end
set.vm.provision "Define hostname and install Docker on #{server[:hostname]}", type: "shell", inline: <<-SHELL
sudo apt-get -qq update >/dev/null
sudo curl -fsSL https://get.docker.com/ | sh
sudo hostnamectl set-hostname "#{server[:hostname]}"
sudo usermod -a -G docker vagrant
SHELL
end
end
end
# docker-network.xml
#
#<network connections='1'>
# <name>docker</name>
# <forward mode='nat'>
# <nat>
# <port start='1024' end='65535'/>
# </nat>
# </forward>
# <bridge name='virbr-docker' stp='on' delay='0'/>
# <ip address='192.168.145.1' netmask='255.255.255.0'>
# <dhcp>
# <range start='192.168.145.2' end='192.168.145.254'/>
# </dhcp>
# </ip>
#</network>