Work

Bare-Metal Kubernetes Homelab

GitOps on physical hardware

Year
2025
Language
Shell
Stars
5
Topics
ansible argocd gitops homelab kubernetes longhorn tailscale

Overview

A personal home cluster running on physical hardware. Ansible bootstraps each node onto Ubuntu 24.04 with Kubernetes pre-configured. ArgoCD drives all workload deployment from a Git repo, Longhorn handles distributed block storage, and the Tailscale Kubernetes operator exposes services across my mesh. Everything is declarative, reproducible, and survives node reboots.

Features

  • Multi-node bare-metal Kubernetes with kubeadm and Cilium
  • GitOps-managed infrastructure and apps via Argo CD ApplicationSets
  • Tailscale Gateway API ingress with split-horizon DNS
  • Vault + External Secrets for centralized secret management
  • Longhorn distributed storage and Prometheus monitoring
  • Automated image updates with Argo CD Image Updater
  • ExternalDNS automation for Gateway API routes
  • Multipass-based local VM rehearsal flow that mirrors the bare-metal topology

Why it exists

Bare-metal first, VMs second

Hardware is the primary target — everything is designed to run on a small cluster of physical machines. The Multipass-based local flow exists so changes can be rehearsed on a laptop before they touch the actual nodes, not as a parallel architecture.

Cilium + Gateway API end-to-end

Cilium handles pod networking and observability (Hubble UI). Envoy Gateway sits on top as the Gateway API data plane. Tailscale is wired as a Gateway API GatewayClass too, so internal services route over the mesh without exposing anything publicly.

Why ApplicationSets

Argo CD ApplicationSets generate per-environment / per-cluster apps from a single template, so adding a new app or a new cluster doesn’t require copy-pasting Application manifests. The repo’s `infrastructure/` and `apps/` trees are scanned automatically and reconciled.

Tech stack

Cluster
Kubernetes (kubeadm) Ubuntu 24.04 LTS Cilium Hubble
Platform
Argo CD Argo CD Image Updater Envoy Gateway cert-manager
Storage & Secrets
Longhorn HashiCorp Vault External Secrets
Networking
Tailscale Operator ExternalDNS MetalLB-free routing
Provisioning
Ansible Multipass (local rehearsal)

Architecture

graph TD
  DEV["Developer"] -->|git push| GH["GitHub Repo"]
  GH -.->|Syncs| AC["ArgoCD"]
  ANS["Ansible<br/>Playbooks"] -->|Bootstraps| N1["Node 1<br/>Ubuntu 24.04"]
  ANS --> N2["Node 2<br/>Ubuntu 24.04"]
  ANS --> N3["Node 3<br/>Ubuntu 24.04"]
  N1 --> K["Kubernetes<br/>Control Plane"]
  N2 --> K
  N3 --> K
  K --> AC
  K --> LH["Longhorn<br/>Distributed Storage"]
  K --> TS["Tailscale<br/>Operator"]
  AC -->|Deploys| APPS["Apps"]
  TS -.->|Exposes| APPS
  LH -.->|Volumes| APPS
  classDef infra fill:#0a0a0a,stroke:#666,color:#fff
  classDef ext fill:#1e1e1e,stroke:#444,color:#ddd
  class N1,N2,N3,K infra
  class GH,DEV ext
Architecture: Bare-Metal Kubernetes Homelab

Quick start

bash
									git clone https://github.com/nsudhanva/homelab
cd homelab
# 1) Provision bare-metal nodes
nano ansible/inventory/hosts.yaml
ansible-playbook -i ansible/inventory/hosts.yaml ansible/playbooks/provision-cpu.yaml

# 2) Bring up the control plane and hand off to Argo CD
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
kubectl apply -k bootstrap/argocd
kubectl apply -f bootstrap/root.yaml