Subir cluster de 3 nós
Forme um cluster com 3 servidores em menos de 10 minutos. Tolera falha de 1 nó sem indisponibilidade.
Um nó isolado funciona, mas qualquer reboot derruba a aplicação. Para tolerar falhas e fazer deploy sem janela, você precisa de 3 nós formando um plano de controle distribuído.
Por que 3 nós, e não 2 ou 4?
A regra é simples: o consenso entre servidores precisa de maioria. Com 3 nós, perder 1 ainda mantém 2 vivos, ou seja, maioria. Com 2, perder 1 deixa 1 vivo, sem maioria, e o cluster trava por segurança.
| Nós | Tolera falha de | Indicado para |
|---|---|---|
| 1 | 0 | desenvolvimento, lab |
| 3 | 1 | produção pequena/média |
| 5 | 2 | produção crítica |
| 4 ou 6 | mesmo que 3 ou 5 | nunca, é desperdício |
Números pares somam custo sem somar resiliência. Sempre ímpar.
Nota: workers (modo agente puro) não contam para essa matemática. Você pode ter 3 servidores + 50 workers e a regra continua sendo "1 servidor pode cair".
Provisionar os 3 servidores
O HeroCtl não exige máquinas iguais, mas servidores devem ter mesmo perfil de CPU e disco para evitar lentidão em quem fica para trás. Um exemplo barato e funcional:
| Provedor | Plano | Custo/mês | CPU | RAM | Disco |
|---|---|---|---|---|---|
| Hetzner | CPX21 | € 7,99 | 3 vCPU | 4 GB | 80 GB |
| DigitalOcean | s-2vcpu-4gb | US$ 24 | 2 vCPU | 4 GB | 80 GB |
| Vultr | vc2-2c-4gb | US$ 24 | 2 vCPU | 4 GB | 80 GB |
Provisione 3 máquinas no mesmo datacenter, em rede privada se o provedor oferece. Latência entre nós deve ficar abaixo de 10 ms.
Depois siga o passo de instalação em cada um. Quando terminar, você terá 3 servidores com binário pronto e nada mais.
Inicializar o primeiro nó
O primeiro nó "abre" o cluster. Os outros vão se juntar a ele. Esse comando só roda em uma máquina e nunca mais.
# No nó 1, IP privado 10.0.0.1
sudo heroctl cluster init --advertise 10.0.0.1
Saída esperada:
cluster initialized
node-id: node-1
state: healthy
nodes: 1/1
A partir daqui, o nó 1 já aceita jobs. Mas sem os outros dois, não há tolerância a falha.
Gerar token de join
Para que outros nós se juntem, você precisa de um token. Ele é assinado pelo cluster e tem validade configurável.
# No nó 1
heroctl cluster join-token --ttl 1h
# eyJhbGciOi...truncado...8X7Z
Atenção: o token concede entrada no plano de controle. Trate como senha. Use TTL curto (1h é suficiente para juntar 3 nós) e nunca cole em logs ou Slack público.
Conectar nós 2 e 3
Em cada um dos outros dois nós, rode o comando de join. Substitua <TOKEN> pelo token gerado e <IP> pelo IP privado daquela máquina.
# No nó 2, IP privado 10.0.0.2
sudo heroctl cluster join \
--token eyJhbGciOi...8X7Z \
--advertise 10.0.0.2 \
--servers 10.0.0.1:8080
# No nó 3, IP privado 10.0.0.3
sudo heroctl cluster join \
--token eyJhbGciOi...8X7Z \
--advertise 10.0.0.3 \
--servers 10.0.0.1:8080
Cada comando demora de 5 a 15 segundos. O nó baixa o estado atual, sincroniza e passa a receber atualizações em tempo real.
Verificar saúde
Após os 3 estarem conectados, qualquer um responde com a visão do cluster:
heroctl cluster status
Saída saudável:
cluster: 3 nodes
quorum: ok (2/3 required)
leader: node-1 (10.0.0.1)
peers:
- node-1 10.0.0.1 server ready applied=1247
- node-2 10.0.0.2 server ready applied=1247
- node-3 10.0.0.3 server ready applied=1247
last_update: 0.4s ago
O que olhar:
- quorum: ok — maioria viva, cluster aceita escritas.
- applied igual nos 3 nós — todos viram as mesmas mudanças. Diferença pequena (1–2) é normal entre o pulso atual.
- last_update abaixo de 5s — replicação fluindo.
Se applied diverge muito (centenas), há problema de rede ou disco em um nó. Veja Problemas comuns abaixo.
Adicionar workers
Workers rodam apenas contêineres. Não votam, não decidem, não guardam estado. Adicione quantos quiser sem afetar o consenso.
# Em cada worker
sudo heroctl agent \
--token <TOKEN> \
--advertise 10.0.0.10 \
--servers 10.0.0.1:8080,10.0.0.2:8080,10.0.0.3:8080
Confirme com:
heroctl node list
# node-1 server ready 3.2 GB free 2 jobs
# node-2 server ready 3.4 GB free 1 job
# node-3 server ready 3.0 GB free 2 jobs
# node-10 worker ready 7.8 GB free 0 jobs
Nota: sempre passe os 3 IPs em
--servers. Se você apontar só para o nó 1 e ele cair durante o join, o agente fica em retry.
Problemas comuns
Nó não conecta
Sintoma: o cluster join fica em "connecting..." por mais de 30s.
Causa típica: firewall bloqueando porta 8082 entre os nós. Confirme com nc -zv <ip-do-nó-1> 8082. Se falhar, libere a porta no firewall externo do provedor.
Estado divergente entre nós
Sintoma: applied muito diferente entre nós (>100).
Possível causa: um nó ficou offline e está reaplicando histórico. Espere alguns minutos. Se não converge, force resync no nó atrasado:
sudo systemctl restart heroctl
heroctl node info <node-id>
Cluster sem maioria
Sintoma: quorum: degraded ou comandos de escrita travam.
Significa que 2 de 3 nós estão fora. O cluster recusa escritas para evitar inconsistência. Recupere os nós antes de tentar mudar qualquer coisa. Se um dos servidores está perdido em definitivo, substitua-o com cluster leave + novo cluster join.
Dois "líderes" aparecem
Não acontece. Se o status de um nó diz que ele é líder e outro também, há problema de relógio. Sincronize com chrony ou ntpd em todos os nós e reinicie.
Próximo passo: fazer deploy do primeiro app.