- Castro/
- blog/
- Como pensar observabilidade para uma frota de VPS Docker sem partir direto para Kubernetes/
Como pensar observabilidade para uma frota de VPS Docker sem partir direto para Kubernetes
Uma arquitetura incremental de observabilidade para hosts Docker com Prometheus, Grafana, Loki, Promtail, cAdvisor e node-exporter, sem transformar Kubernetes em pré-requisito.
Quando a operação cresce em VPS e Docker Compose, é comum aparecer uma conclusão automática:
Agora precisa colocar tudo em Kubernetes para conseguir monitorar direito.
Não necessariamente.
Uma stack real que usei como base de observabilidade rodava no próprio Docker Compose e já separava métricas de host, métricas de containers, logs e visualização usando:
| |
A fonte recuperada prova essa arquitetura em um host de produção. Ela não prova “centenas de VPS”. Por isso reduzi o título original desta pauta para uma frota de VPS Docker.
A ideia que vale reaproveitar é arquitetural: começar por componentes simples e replicáveis antes de transformar orquestrador em requisito da observabilidade.
O que eu queria enxergar #
Em um host Docker típico, as perguntas básicas são previsíveis:
| |
Nenhuma dessas perguntas exige Kubernetes para existir.
Elas exigem coleta consistente e uma forma de centralizar contexto.
Métrica de host: node-exporter #
O node-exporter cobre a visão do sistema operacional.
Na stack real, ele rodava com acesso read-only ao filesystem do host e pid: host.
Conceitualmente:
| |
Com isso, Prometheus consegue acompanhar métricas como:
- CPU;
- memória;
- filesystem;
- load;
- rede;
- pressão do host.
É a camada que responde se o problema está afetando a máquina inteira ou só uma aplicação.
Métrica de container: cAdvisor #
Para enxergar o runtime Docker, a stack usava cAdvisor.
Ele precisa de uma visão bem mais privilegiada do host, montando recursos como:
| |
Na fonte, o container estava como privileged.
Isso merece ser tratado como decisão de segurança, não só como detalhe de Compose.
cAdvisor entrega informação muito útil sobre consumo por container, mas a permissão que recebe também é maior que a de uma aplicação comum.
Então eu prefiro deixá-lo apenas em rede interna e não publicar a UI/porta diretamente na internet.
Prometheus: histórico curto e previsível #
Na stack recuperada, Prometheus estava configurado com:
| |
E persistia os dados em volume local:
| |
A configuração era montada em modo read-only:
| |
Quinze dias não são uma lei.
É uma decisão de capacidade.
O ponto é ter retenção explícita. Se ninguém define, o armazenamento cresce até a infraestrutura decidir por você.
Logs: Loki + Promtail #
Métrica mostra quanto algo desviou.
Log costuma mostrar o que aconteceu.
A stack usava Loki com persistência local:
| |
E Promtail coletava fontes do host/containers usando mounts read-only, incluindo:
| |
Além disso, havia acesso ao socket Docker para enriquecer a descoberta/contexto dos containers.
Esse último ponto merece o mesmo cuidado do cAdvisor: montar /var/run/docker.sock dá ao processo uma interface extremamente sensível do Docker daemon.
Se a arquitetura puder obter os metadados necessários sem expor o socket, melhor. Se ele for necessário, precisa permanecer restrito à rede interna e ao host controlado.
Rede interna para coletores #
Um detalhe do Compose que considero bom era a separação de redes.
Prometheus, node-exporter, cAdvisor, Loki e Promtail ficavam em uma bridge interna da stack.
Conceitualmente:
| |
Sem publicação direta dessas portas no host.
As portas existiam dentro da rede Docker:
| |
Mas isso é diferente de fazer:
| |
No host observado, apenas a camada de proxy publicava 80/443 externamente.
Isso reduz bastante a superfície acidental da observabilidade.
Grafana é a exceção deliberada #
Grafana precisa ser acessado por pessoas.
Na arquitetura, ele participava de duas redes:
| |
A publicação era feita por Traefik com TLS, encaminhando para a porta interna 3000.
Isso cria uma fronteira útil:
| |
Prometheus e Loki não precisam ficar públicos só porque Grafana consulta os dois.
Grafana também precisa de persistência #
Na stack real:
| |
Sem persistência, reiniciar o container pode transformar dashboard, datasource e configuração em estado efêmero dependendo de como o provisioning foi feito.
O mesmo vale para Loki e Prometheus.
Observabilidade sem persistência pode falhar justamente quando você precisa investigar algo que aconteceu antes do restart.
O que essa stack resolve em um único host #
Mesmo antes de centralizar uma frota inteira, um Compose desses já cria uma base consistente:
| |
A vantagem é começar entendendo a telemetria local antes de resolver a distribuição em escala.
Como eu evoluiria de um host para uma frota #
A próxima etapa não precisa ser “instalar Kubernetes”.
Primeiro eu decidiria qual modelo operacional a frota precisa.
Modelo A — coletores locais, backend central #
Em cada VPS:
| |
Em um ponto central:
| |
Modelo B — Prometheus local + agregação #
Pode fazer sentido quando cada ambiente precisa continuar consultável mesmo com perda de conectividade ao centro.
Modelo C — agente único/OTel Collector #
Conforme a operação amadurece, OpenTelemetry Collector pode reduzir a quantidade de agentes e abrir espaço para traces.
A escolha depende de volume, isolamento entre clientes, conectividade, custo e retenção.
O problema que aparece quando a frota cresce #
Em poucos hosts, editar target manualmente ainda parece aceitável.
Em uma frota, começam os problemas:
| |
A partir daí, o desafio deixa de ser instalar Prometheus.
Vira service discovery e governança de metadados.
Isso ainda não obriga Kubernetes. Pode ser resolvido com inventário, geração de targets, Consul, file-based discovery, automação ou outro catálogo operacional.
E quando Kubernetes passa a fazer sentido? #
Kubernetes pode trazer vantagens fortes quando você já precisa dele por motivos de plataforma:
- scheduler;
- autoscaling;
- abstração de serviços;
- deployment padronizado;
- operadores;
- service discovery nativo;
- políticas de workload.
O que eu evitaria é adotar Kubernetes só para instalar Prometheus e Grafana.
Você troca um problema de observabilidade por um novo domínio operacional inteiro.
Se as aplicações continuam bem atendidas por VPS + Docker Compose, a observabilidade pode evoluir incrementalmente sobre esse modelo.
Segurança precisa entrar no desenho desde o começo #
Na stack real, alguns pontos pediam atenção explícita:
- cAdvisor privilegiado;
- Promtail com acesso ao Docker socket;
- senha administrativa do Grafana parametrizada;
- signup desabilitado;
- Grafana publicado só atrás de Traefik/TLS;
- coletores sem portas expostas diretamente.
Esses detalhes importam mais do que escolher o dashboard bonito.
Uma stack de monitoramento com acesso ao host pode virar uma excelente fonte de telemetria — ou uma nova superfície administrativa crítica.
O que eu padronizaria por VPS #
Para uma frota Docker, eu tentaria manter um contrato pequeno por host:
| |
O backend pode mudar com o tempo.
Esse contrato deveria mudar muito menos.
Por que tirei “centenas” do título #
O plano editorial original tinha:
Como pensar observabilidade para centenas de VPS Docker sem partir direto para Kubernetes
Mas a fonte técnica recuperada prova em detalhe uma stack Compose em um host, e o histórico prova uma operação com múltiplos VPS/hosts Docker — não uma evidência técnica desta implementação em centenas deles.
Então o artigo ficou deliberadamente menor:
uma frota de VPS Docker
A arquitetura continua útil.
A escala afirmada agora fica do tamanho da evidência disponível.
O principal aprendizado #
O primeiro passo para observar vários hosts não é necessariamente escolher um orquestrador.
É decidir:
| |
Prometheus, Loki, Grafana, node-exporter, cAdvisor e Promtail em Docker Compose já conseguem responder boa parte disso.
Depois, se Kubernetes fizer sentido para a plataforma, a observabilidade acompanha.
Não precisa ser o motivo para começar a usá-lo.
Me chama.
Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.