Matheus Monteiro

Construindo um Homelab Production-Grade com Proxmox, Talos, Kubernetes e GitOps

· Matheus Monteiro

Eu queria um lab que falhasse como produção sem derrubar produção.

Esse era o ponto. Eu não queria mais um cluster de brinquedo rodando um dashboard, dois apps de exemplo e morrendo na primeira vez que storage ficasse estranho. Eu queria um sistema pequeno com pressão operacional real: infraestrutura declarativa, GitOps, nós imutáveis, segredos fora do repositório, acesso remoto sem port forwarding e storage que sobrevivesse ao restart de um pod.

O resultado é meu homelab: uma máquina física rodando Proxmox, um cluster Kubernetes com Talos em VMs, TrueNAS para storage, ArgoCD para GitOps, 1Password para segredos, Tailscale para acesso, MetalLB para load balancers bare metal e Istio Ambient para experimentos com service mesh.

Tudo vive no Git: github.com/matheus3301/homelab.

Production-grade, com asterisco

Isso é um homelab. Ele roda em uma única máquina física. Se essa máquina morrer, o cluster morre junto.

Então o termo production-grade precisa ser usado com cuidado. Eu não estou falando de alta disponibilidade. Estou falando de hábitos de produção.

Production-grade aqui significa que as partes importantes são reproduzíveis. As VMs vêm do Terraform. Os nós Kubernetes vêm de machine configs do Talos. As aplicações vêm do ArgoCD. Os segredos vêm do 1Password em runtime. O acesso remoto passa pelo Tailscale. Volumes persistentes ficam no TrueNAS em vez de cair no disco aleatório de algum pod.

O hardware pode ser modesto. Os hábitos não.

O formato do sistema

A camada física é o Proxmox VE. Ele roda as máquinas que formam o lab:

Kubernetes roda em cima do Talos Linux. TrueNAS fornece o backend de storage. ArgoCD controla a camada de aplicações. Tailscale dá acesso de qualquer lugar sem abrir portas no roteador.

A stack fica assim:

Diagrama da arquitetura do homelab

A parte importante é a fronteira entre as camadas. Proxmox controla VMs. Talos controla os nós Kubernetes. ArgoCD controla objetos Kubernetes. 1Password controla segredos. TrueNAS controla discos.

Cada ferramenta tem um trabalho claro.

Proxmox é a fundação chata

Proxmox não é o protagonista do sistema. Esse é o ponto.

Ele me dá uma camada estável de virtualização e a liberdade de destruir máquinas sem tocar no host físico. Nós Kubernetes são descartáveis. TrueNAS é uma VM com acesso direto a um NVMe. A VM misc cuida dos trabalhos estranhos que não pertencem ao cluster.

Terraform gerencia a camada Proxmox. As VMs Talos usam VirtIO para disco e rede. A VM TrueNAS usa PCIe passthrough para que o ZFS enxergue o NVMe diretamente.

Essa separação importa. Kubernetes não deve fingir que é dono do disco. TrueNAS não deve fingir que é Kubernetes. Proxmox mantém as partes separadas.

Virtualização dá ao homelab sua função mais útil: jogar coisas fora sem medo.

Talos remove a tentação do SSH

Talos Linux é a melhor decisão desse setup.

Um nó Kubernetes com Linux tradicional convida drift. Entra por SSH. Instala pacote. Edita arquivo. Reinicia serviço. Corrige o problema na mão e esquece o que mudou.

Talos remove esse caminho. Não tem SSH. Não tem package manager. O nó é configurado por uma API e uma machine config. Se a config está errada, corrija a config. Se o nó quebrou, reconstrua.

Parece duro até salvar você de você mesmo.

O cluster é bootstrapped com o provider Terraform da Sidero Labs. Terraform gera as machine configs, aplica nos nós, faz bootstrap do control plane e exporta o kubeconfig.

Eu uso uma imagem customizada do Talos com a extensão do QEMU guest agent para o Proxmox ler métricas da VM de forma limpa. O resto fica mínimo.

Talos transforma gerenciamento de nó Kubernetes em um problema menor. Sem snowflake nodes. Sem pacote misterioso. Sem sessão heroica de shell de madrugada.

GitOps desde o primeiro dia

ArgoCD roda a camada de aplicações.

O primeiro passo manual depois que o cluster sobe é pequeno:

kubectl apply -f kubernetes/00-bootstrap/ -n argocd

Depois disso, o Git assume.

Diagrama do fluxo GitOps

O repositório é dividido por responsabilidade:

kubernetes/
├── 00-bootstrap/   # bootstrap inicial do ArgoCD
├── 01-core/        # infraestrutura do cluster
├── 02-services/    # serviços compartilhados
└── 03-apps/        # aplicações

ApplicationSets do ArgoCD varrem esses diretórios e criam aplicações automaticamente. Para adicionar um componente core, eu crio uma pasta e um manifesto. Para publicar um app, coloco ele em 03-apps. O ArgoCD vê a mudança e reconcilia o cluster.

A regra é simples: se importa, passa pelo Git.

Isso pagou o esforço logo no começo. GitOps dá memória ao lab. Eu consigo ver o que mudou, reverter uma ideia ruim, reconstruir do zero e evitar um estado criado por clique que ninguém sabe explicar.

Adicionar GitOps depois dói. Comece por ele.

As peças centrais da plataforma

Um cluster Kubernetes novo é encanamento vazio. A plataforma começa quando as partes chatas entram.

MetalLB

Clusters em cloud recebem load balancers do cloud provider. Bare metal não recebe nada.

MetalLB cobre esse buraco. Ele dá endereços reais na LAN para Services do tipo LoadBalancer. Eu mantenho pools separados para serviços internos e expostos, o que deixa o roteamento mais fácil de entender.

Istio Ambient

Eu uso Istio Ambient em vez de sidecars.

Sidecars são poderosos, mas adicionam um container a cada pod e deixam debugging mais barulhento. Ambient move a malha L4 para pods ztunnel em nível de nó. Workloads entram no mesh sem injeção de sidecar.

Para um homelab, esse é um tradeoff mais limpo. Menos overhead. Menos partes móveis por pod. Service mesh suficiente para aprender os padrões reais.

External Secrets e 1Password

Segredos não pertencem ao Git.

External Secrets Operator busca valores no 1Password e cria Kubernetes Secrets em runtime. O repositório guarda referências, não valores.

Essa diferença mantém GitOps utilizável. Um repo declarativo com credenciais em texto puro é uma armadilha com sintaxe YAML.

Metrics Server

Metrics Server é pequeno, mas faz o cluster parecer vivo. kubectl top funciona. HPA tem dados. Checagens básicas de capacidade deixam de ser chute.

Com Talos, o chart do metrics-server precisa de ajuste na validação TLS do kubelet por causa dos certificados dos nós. Detalhe pequeno. Vale documentar.

Storage: TrueNAS e SMB

Storage é onde homelabs começam a mentir.

Um pod pode reiniciar em qualquer lugar. Um nó pode sumir. Um disco pode encher. A resposta de demo costuma ser hostPath, que funciona até destruir sua semana.

Eu uso TrueNAS Scale com um NVMe passado direto pelo Proxmox. Kubernetes fala com ele pelo SMB CSI driver. A StorageClass padrão provisiona volumes em cima de SMB.

SMB não é glamouroso. Funciona.

Os benefícios são práticos:

Eu não venderia SMB como resposta universal de produção. Para um homelab, é um bom compromisso. Simples, visível e resiliente o suficiente para os workloads que me importam.

Tailscale mudou o modelo de acesso

O modelo de acesso e storage acabou com dois caminhos limpos: MetalLB para a LAN, Tailscale para acesso remoto e TrueNAS para dados persistentes.

Diagrama do modelo de acesso e storage

Eu não quero portas aleatórias abertas no roteador de casa.

Tailscale dá um formato melhor ao lab. O operador Kubernetes roda dentro do cluster. Um subnet router anuncia a rede de casa para minha tailnet. Serviços também podem ser expostos via Tailscale Ingress, com HTTPS e nomes MagicDNS dentro da tailnet.

MetalLB e Tailscale resolvem problemas diferentes.

MetalLB é para acesso na rede local. Baixa latência. Bom para dispositivos na LAN. Útil para gateways Istio e serviços internos.

Tailscale é para acesso remoto. Criptografado. Controlado por ACLs. Sem port forwarding. Sem cerimônia de IP público.

Manter os dois gera um sistema mais limpo do que forçar uma ferramenta a fazer todos os trabalhos.

Day-2 operations importam

Um artigo de homelab normalmente termina quando o cluster fica verde.

É aí que o trabalho real começa.

Adicionar uma aplicação deveria ser chato. Criar uma pasta de namespace. Adicionar manifestos. Commit. Push. Deixar o ArgoCD sincronizar.

Instalar um Helm chart deveria ser chato. Adicionar uma Application do ArgoCD. Definir values. Commit. Push.

Recuperar um estado ruim do ArgoCD também deveria ser chato. Eu mantenho um script nuclear para finalizers e recursos do ArgoCD, assim o cluster pode ser bootstrapped de novo quando eu faço alguma besteira.

Um lab é útil quando torna falha barata. O objetivo não é evitar quebrar. O objetivo é quebrar, entender e reconstruir sem drama.

Lições aprendidas

Comece com GitOps. Ele muda o sistema inteiro. Você para de pensar em comandos e começa a pensar em estado desejado.

Use um OS imutável se quer aprender operações de Kubernetes. Talos força os hábitos certos. O nó deixa de ser um ambiente de shell de estimação.

Mantenha segredos fora do Git desde o início. External Secrets é mais fácil de colocar cedo do que remediar depois que credenciais vazaram em manifestos.

Use Tailscale antes de pensar em port forwarding. Acesso remoto deveria ser privado por padrão.

Seja honesto sobre storage. SMB no TrueNAS é um tradeoff de homelab, não uma religião. Ele me dá ReadWriteMany e ZFS com baixo custo operacional.

Production-grade é principalmente disciplina. O hardware ajuda. Os hábitos importam mais.

O que vem depois

A próxima camada é observabilidade. Prometheus, Grafana, Loki e tracing pertencem a esse cluster porque vão mostrar como o sistema se comporta sob pressão.

Backups precisam do mesmo tratamento. Velero, snapshots do TrueNAS e exercícios de disaster recovery devem fazer parte do lab, não ficar perdidos em um TODO futuro.

Também quero explorar Crossplane para gerenciamento de recursos externos e pipelines de CI para builds de imagens internas.

O lab já é útil. Esse é o critério. Ele não precisa estar pronto. Ele precisa continuar me ensinando coisas.

#homelab #kubernetes #proxmox #talos #gitops #argocd #sre

Responda a este post por email ↪