Troubleshooting de problemas comuns
Os 12 problemas mais frequentes em clusters HeroCtl, com sintoma, diagnóstico e correção passo a passo.
Este guia cobre os doze problemas que aparecem com mais frequência em clusters HeroCtl. Cada item traz sintoma, diagnóstico e correção. Use como referência rápida em incidente.
1. Cluster não inicia: "cannot bind to port 8080"
Sintoma: o serviço sobe e morre logo em seguida. O log diz que a porta 8080 está em uso.
Diagnóstico:
sudo lsof -i :8080
# ou
sudo ss -tlnp | grep 8080
A saída mostra qual processo está segurando a porta.
Correção:
Se for processo legítimo (outro app), mude a porta do HeroCtl:
# /etc/heroctl/server.yaml
api:
port: 8090
Se for processo zumbi (HeroCtl antigo que não morreu direito):
sudo kill -9 <PID>
sudo systemctl start heroctl-server
2. Nó não consegue entrar no cluster
Sintoma: comando de join trava ou retorna connection refused / invalid token.
Diagnóstico:
Três suspeitos comuns:
# 1. Token expirou?
heroctl cluster join-token list
# 2. Firewall bloqueando?
nc -zv <ip-do-coordenador> 4646
nc -zv <ip-do-coordenador> 4647
nc -zv <ip-do-coordenador> 4648
# 3. Relógios fora de sincronia?
timedatectl status
Correção:
- Token expirado: gere outro com
heroctl cluster join-token create --ttl 1h. - Firewall: libere as portas 4646, 4647 e 4648 entre os nós. Veja firewall.
- Relógio: instale e ative NTP.
sudo apt install chrony
sudo systemctl enable --now chrony
Diferença maior que 30 segundos entre nós quebra a coordenação.
3. Cluster perdeu coordenação
Sintoma: API responde com 503 e mensagens sobre falta de coordenador. Mudanças não são aceitas.
Diagnóstico:
heroctl cluster status
Você verá quantos nós estão saudáveis. Se menos da metade respondem, o cluster trava em modo somente-leitura por segurança.
Correção:
A solução normal é trazer os nós caídos de volta:
ssh nó-caído sudo systemctl start heroctl-server
Se eles não voltam (disco morto, máquina perdida), use bootstrap forçado a partir do snapshot mais recente:
heroctl snapshot restore /backups/ultimo.tar.gz --force-bootstrap
Atenção: bootstrap forçado descarta tudo que aconteceu depois do snapshot. Veja backup e restore.
4. Job fica em "pending"
Sintoma: heroctl jobs status meu-job mostra pending por minutos. Nada inicia.
Diagnóstico:
heroctl jobs explain meu-job
A saída detalha por que o agendador não consegue colocar o job. Causa típica: nenhum nó tem CPU/RAM disponível para os recursos pedidos.
Correção:
Duas opções:
- Adicione mais nós ao cluster.
- Reduza os recursos exigidos pelo job:
resources:
cpu_mhz: 500 # antes era 2000
memory_mb: 256 # antes era 1024
5. Health check falhando
Sintoma: o job sobe mas é marcado como não saudável. Reinicia em loop.
Diagnóstico:
heroctl logs <alloc-id> | tail -50
Frequentemente o app está demorando mais para subir que o healthy_deadline permite.
Correção:
Aumente o prazo:
health_check:
path: /health
port: 8080
interval: 10s
timeout: 3s
healthy_deadline: 120s # era 30s
Se o app está realmente lento para subir (carrega cache enorme, conecta em vários serviços), trabalhe o tempo de boot. Lazy loading geralmente resolve.
6. Certificado TLS não é emitido
Sintoma: site responde com certificado autoassinado ou erro de TLS. Logs do ingress mencionam falha em emissão automática.
Diagnóstico:
# DNS aponta pro IP correto?
dig +short meudominio.com
# Porta 80 acessível externamente?
curl -I http://meudominio.com/.well-known/acme-challenge/test
A emissão automática de certificado precisa de duas coisas: DNS público apontando para um nó do cluster e a porta 80 aberta para o mundo.
Correção:
- DNS errado: corrija o registro A no seu provedor.
- Porta 80 fechada: libere no firewall do servidor e no firewall do provedor (security group, etc).
- Domínio com proxy de CDN ativo: desative o proxy temporariamente para a emissão; reative depois.
7. App lento sob carga
Sintoma: latência sobe quando o tráfego aumenta. Usuários reclamam.
Diagnóstico:
heroctl metrics --job meu-app --since 30m
Olhe CPU, memória e número de instâncias. Verifique também se há um deploy em curso — deploys gradativos retiram capacidade temporariamente.
Correção:
Se está faltando capacidade, escale:
heroctl jobs scale meu-app --count 6 # de 3 para 6
Se está deploy em curso, espere ele terminar antes de avaliar. Se o app está com vazamento de memória ou loop apertado, perfile o código — não tem como o orquestrador resolver problema interno do app.
8. Logs não aparecem
Sintoma: heroctl logs retorna vazio mesmo com app rodando e gerando saída.
Diagnóstico:
docker inspect <container-id> | grep LogConfig
Se aparece "Type": "none" ou um driver não suportado, o problema está aí.
Correção:
Configure o driver de log padrão na máquina:
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
Reinicie o serviço:
sudo systemctl restart docker
9. Conexão com Postgres dando timeout
Sintoma: o app loga connection timeout ou too many clients quando conecta no banco.
Diagnóstico:
No Postgres:
SELECT count(*) FROM pg_stat_activity;
SHOW max_connections;
Se count(*) está perto de max_connections, o pool está saturado.
Correção:
Coloque um pgbouncer entre app e banco:
# job pgbouncer
config:
max_client_conn: 1000
default_pool_size: 25
E aponte os apps para o pgbouncer em vez do banco direto. Você pode atender milhares de conexões de cliente com poucas conexões reais ao banco.
10. Cluster aparenta ter dois coordenadores
Sintoma: comportamentos estranhos — escrita em um nó não aparece no outro. Métricas inconsistentes entre painéis.
Diagnóstico:
heroctl cluster peers
Se a lista de pares varia dependendo do nó que você consulta, houve uma divisão de rede e duas metades acharam que eram a metade boa.
Correção:
Identifique a metade minoritária (a com menos nós) e reinicie esses nós:
sudo systemctl restart heroctl-server
Eles re-sincronizam com a metade majoritária e a inconsistência some. Em seguida verifique se algum dado divergiu durante o intervalo:
heroctl jobs status --all | grep -i diverge
11. Disco cheio
Sintoma: o nó começa a se comportar mal. API lenta. Agente reinicia containers sem motivo aparente. df -h mostra 100%.
Diagnóstico:
sudo du -sh /var/lib/heroctl/* | sort -h
sudo du -sh /var/log/* | sort -h
Os culpados de sempre são logs antigos e snapshots não limpos.
Correção:
Configure rotação:
# /etc/heroctl/server.yaml
logs:
retention_days: 7
max_size_per_alloc_mb: 500
snapshots:
retention_count: 10
E uma faxina manual imediata:
sudo journalctl --vacuum-time=3d
heroctl snapshot prune --keep 10
12. Container morto por falta de memória
Sintoma: heroctl logs termina com OOMKilled. O container reinicia em loop.
Diagnóstico:
heroctl alloc status <id> | grep -A5 "memory"
Compare uso real com o limite definido.
Correção:
Aumente o limite no spec do job:
resources:
memory_mb: 1024 # era 512
Suba a nova versão:
heroctl jobs submit meu-app.json
Se o uso de memória cresce com o tempo (vazamento), aumentar o limite só adia o problema. Investigue o app.
Quando nada disso ajuda
Reúna as seguintes informações antes de abrir um chamado:
heroctl cluster status(saída completa)heroctl versionem todos os nós- O
request_idretornado pelo erro da API - Recorte do log com timestamp do incidente
Mande para suporte@heroctl.com com essas informações no corpo da mensagem. Quanto mais contexto, mais rápida a resposta.
Próximos passos
- Métricas e alertas — detectar problemas antes do usuário.
- Backup e restore — preparação para os cenários mais graves.
- Referência da API — quando o CLI não for suficiente.