Decidi criar minha própria alternativa ao Kubernetes. Aqui está o design que escolhi (e por quê).
No meu último post expliquei as motivações que me levaram a pensar "ok, vou criar uma alternativa ao Kubernetes". Se você não leu ainda recomendo começar por lá. Recebi muitos comentários, alguns de apoio, outros questionando se deveria criar mesmo um novo Kubernetes. Justo. Mas a decisão já estava tomada, então o próximo passo era simples: parar de pensar e começar a fazer. Desta vez separei o artigo por tema para ficar de mais fácil leitura.
O nome
A primeira coisa que fiz foi escolher um nome. Pode parecer bobo, mas eu sempre faço isso com meus projetos — dar um nome transforma uma ideia vaga em algo concreto. Deixa de ser "aquela loucura que tive no chuveiro" e passa a ser uma coisa real.
Dessa vez o nome veio instantaneamente. Um dos principais objetivos do projeto é criar algo que simplifique radicalmente a experiência de colocar coisas no ar. Sem stress, sem cursos de 40 horas, sem YAML infinito. Algo que pareça quase... mágico.
Por isso: Houdini.
Harry Houdini foi o primeiro grande mágico e ilusionista do mundo. Talvez seja pretensão da minha parte comparar um projeto open-source com o cara que escapava de caixões debaixo d'água, mas o nome encaixa perfeitamente no que eu quero entregar: fazer algo complexo parecer simples.
A fase de estudo
Vou esclarecer uma coisa que ficou confusa no post anterior — algumas pessoas entenderam que eu não conheço Kubernetes. Não as culpo, provavelmente não fui claro. Quando falei em "usar AI para criar o cluster" me referia a uma questão de tempo e eficiência, não de total desconhecimento. Tenho experiência de uso e implementação de K8s em produção.
Mas uma coisa é usar Kubernetes. Outra coisa é criar algo que compete no mesmo espaço. Para isso, precisei ir muito mais fundo.
Comecei a estudar o código-fonte do Kubernetes. Não a documentação, não os tutoriais — o código. Como as coisas foram implementadas, por que certas decisões foram tomadas, quais trade-offs foram aceitos. Fiz o mesmo com o Nomad da HashiCorp. Esse estudo me levou inclusive a considerar tirar a certificação CKA, não pelo certificado em si, mas pelo processo de aprendizado estruturado.
A AI ajuda muito nessa etapa, vou ser honesto. Ler 2 milhões de linhas de Go do Kubernetes sem nenhum guia seria insano. Mas o entendimento tem que ser meu — a AI acelera, não substitui.
Não é um novo Kubernetes
Um ponto crucial: eu não estou tentando criar um novo Kubernetes. Um desenvolvedor solo dificilmente alcança essa façanha, e nem é o objetivo. Quero criar uma alternativa. Não melhor, não pior — simplesmente uma outra forma de pensar como um orquestrador deveria funcionar.
O projeto é opinativo. Assumidamente. Porque reflete como EU gostaria que um orquestrador funcionasse, baseado em 22 anos escrevendo código e deployando em produção.
O design: aprendendo com os erros dos outros
Para chegar ao design do Houdini, fiz três coisas:
- Estudei a arquitetura do Kubernetes e Nomad em profundidade
- Catáloguei as principais críticas da comunidade a K8s, Nomad e Swarm
- Somei isso à minha experiência prática do que funciona e do que não funciona
As críticas mais comuns que encontrei:
Kubernetes:
- Complexidade absurda para casos de uso simples
- Dezenas de componentes para manter (etcd, kube-apiserver, scheduler, controller-manager, kubelet, kube-proxy...)
- YAML hell — configurações verbosas e difíceis de debugar
- Service mesh requer componentes externos (Istio, Linkerd)
- Curva de aprendizado de meses
Nomad:
- Simples mas incompleto — precisa do Consul para service discovery, Vault para secrets
- Sem service mesh built-in
- Comunidade menor, menos tooling
Docker Swarm:
- Abandonado pela Docker Inc.
- Sem autoscaling real
- Estratégias de deploy limitadas
A arquitetura do Houdini
Com tudo isso em mente, estas são as decisões de design que tomei. Atenção: ainda não digo que são imutáveis — o projeto está em desenvolvimento ativo e certas coisas podem mudar conforme encontro problemas reais.
Princípio #1: Um binário, zero dependências externas
$ houdini server # control plane
$ houdini agent # worker node
$ houdini deploy # CLI
Mesmo binário faz tudo. Sem etcd separado, sem Consul, sem Vault, sem Prometheus server. Tudo embutido. O storage usa BoltDB (key-value embutido em Go), o consenso distribuído usa Raft (a mesma lib que o Nomad usa), o service mesh usa WireGuard nativo.
Por quê? Porque a maior fonte de complexidade operacional do Kubernetes não é o conceito — são os 15 componentes que você precisa manter vivos. Quero que alguém consiga subir um cluster funcional com literalmente houdini server e houdini agent --server <ip>.
Princípio #2: Multi-runtime
O Houdini não executa apenas containers. Ele suporta quatro tipos de workload com a mesma API:
- Container — Docker, para quando você precisa de isolamento completo
- Process — processos nativos do OS, para dev local ou binários que não precisam de container
- WASM — WebAssembly modules, startup em <1ms, sandboxing leve
- Function — serverless, event-driven, scale-to-zero automático
Por quê? Porque nem todo workload precisa de container. Um script Python que roda a cada 5 minutos não precisa de 200MB de imagem Docker. Um webhook handler não precisa estar vivo 24/7 consumindo RAM.
Princípio #3: Networking built-in
Cada node recebe uma subnet WireGuard (10.42.X.0/24). Os containers se comunicam diretamente entre nodes por túneis encriptados. DNS interno resolve servico.namespace.houdini para os IPs corretos. Ingress controller com HTTPS automático (Let's Encrypt) incluso.
Por quê? Porque no Kubernetes você precisa escolher entre Calico, Flannel, Cilium para CNI, depois instalar um Ingress controller (nginx, traefik, envoy), depois configurar cert-manager para TLS. São 3-4 decisões e instalações antes de ter tráfego externo chegando no seu serviço.
Princípio #4: Deploy pipeline inteligente
O deploy não é "manda o YAML e reza". É um pipeline com fases:
- Validação — o spec faz sentido?
- Scheduling — onde rodar? (bin-pack ou spread, com anti-affinity, constraints, failure scoring)
- Dispatch — push direto ao agent via gRPC stream
Quatro estratégias: Rolling (zero-downtime), Canary (testa com % do tráfego), Blue-Green (troca atômica), All-at-once (rápido, aceita downtime).
Se falhar? Retry com backoff exponencial. Esgotou as tentativas? Dead Letter Queue — nada é perdido silenciosamente.
Princípio #5: Reconciliação contínua
A cada 30 segundos, um reconciler compara o estado desejado (o que você pediu) com o estado real (o que está de fato rodando). Se divergir, ele corrige. Workload crashou? Restart com backoff. Node morreu? Reschedule para outro node. Container órfão? GC automático.
Por quê? Esse é o padrão que o Kubernetes acertou em cheio — declarativo + reconciliação. Eu copiei. Não tenho vergonha de copiar o que funciona.
Princípio #6: Segurança não é opcional
- Secrets encriptados com AES-256-GCM (Argon2id para key derivation)
- RBAC com 4 roles (admin, operator, developer, viewer)
- 2FA com TOTP
- Comunicação agent↔server com token + gRPC streams
- Policy engine para admission control (bloqueia :latest em prod, exige health checks, etc.)
Visão geral simplificada
┌─────────── CONTROL PLANE (houdini server) ──────────────┐
│ │
│ REST API (:4646) │ gRPC (:4648) │ Ingress (:443) │
│ │
│ Scheduler │ Reconciler │ Deploy Pipeline │ Autoscaler │
│ │
│ State Store (BoltDB / Raft cluster) │
└──────────────────────────┬───────────────────────────────┘
│ gRPC Streams + WireGuard Mesh
▼
┌──────── WORKER NODE (houdini agent) ─────────┐
│ │
│ Runtime Registry │
│ ├── Docker (containers) │
│ ├── Process (nativos) │
│ ├── WASM (módulos) │
│ └── Function (serverless) │
│ │
│ Workload Manager │ Health Probes │ Logs │
└───────────────────────────────────────────────┘
Mas e a experiência de uso?
Eu sei o que você está pensando: "Ok, muita coisa técnica por baixo dos panos, mas e na prática?" Boa pergunta.
O ponto é que toda essa complexidade — scheduling, mesh, autoscaling, reconciliation — existe para que o utilizador não precise pensar nela. Tudo isso vai ser gerido de forma transparente através de uma Web UI onde você configura, deploya, monitora e escala seus serviços sem abrir um terminal se não quiser.
A ideia é simples: quem quer ir fundo no TOML e na CLI pode ir. Quem quer clicar em "Deploy" e ir tomar café, também pode. Sem julgamento.
A Web UI vai ser tema de um artigo futuro — e prometo que esse vai ser bem menos técnico que este. Aliás, este aqui provavelmente foi o artigo mais técnico que vou escrever nesta série. Se sobreviveu até aqui, os próximos vão ser tranquilos.
Próximos passos
O projeto ainda não está público, mas em breve estará. Estou a preparar tudo para que quando abrir o repositório, as pessoas consigam de facto clonar, rodar e testar — não quero abrir algo meio cozinhado e dar uma primeira impressão errada.
No próximo post vou falar sobre a Web UI e a experiência que quero entregar para quem não quer (ou não precisa) viver no terminal.
Até lá, se tiver perguntas, críticas ou sugestões — manda. Especialmente se discorda de alguma decisão. É assim que projetos melhoram.