SkillAgentSearch skills...

Homelabs

4-node k3s cluster on Vagrant/VirtualBox with complete observability stack (Prometheus, Grafana, Loki). Terraform IaC for multi-domain static sites with NFS shared storage and Cloudflare Tunnel. Production-grade homelab for Kubernetes learning and testing.

Install / Use

/learn @luismr/Homelabs

README

Homelabs 4-Node Debian Cluster

A Vagrant-managed 4-node Debian Bookworm cluster with bridged networking on a /22 subnet.

Cluster Configuration

| Node | IP Address | CPU | RAM | SSH Port | |---------|-----------------|-----|------|----------| | master | 192.168.5.200 | 2 | 4GB | 22 | | worker1 | 192.168.5.201 | 2 | 4GB | 22 | | worker2 | 192.168.5.202 | 2 | 4GB | 22 | | worker3 | 192.168.5.203 | 2 | 4GB | 22 |

Network: 192.168.4.0/22 (255.255.252.0)
Gateway: 192.168.4.1
DNS: 8.8.8.8, 8.8.4.4
Bridge Interface: en2: Wi-Fi (AirPort)

Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                           INTERNET                                  │
│                              ↓                                      │
│  ┌────────────────────────────────────────────────────────────┐   │
│  │              Cloudflare Network (Global CDN)               │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐    │   │
│  │  │  pudim.dev   │  │luismachado   │  │ carimbo.vip  │    │   │
│  │  │   (DNS)      │  │ reis.dev     │  │   (DNS)      │    │   │
│  │  │   CNAME ──────────▶ CNAME ────────────▶ CNAME     │    │   │
│  │  └──────────────┘  └──────────────┘  └──────────────┘    │   │
│  │           │                 │                 │            │   │
│  │           └─────────────────┼─────────────────┘            │   │
│  │                             ▼                              │   │
│  │              ┌──────────────────────────┐                  │   │
│  │              │  Cloudflare Tunnel       │                  │   │
│  │              │  (Encrypted Connection)  │                  │   │
│  │              └──────────────┬───────────┘                  │   │
│  └─────────────────────────────┼──────────────────────────────┘   │
└────────────────────────────────┼──────────────────────────────────┘
                                 │ Token Auth
                                 │ HTTPS/QUIC
                                 ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    Kubernetes Cluster (k3s)                         │
│                    192.168.5.200-203 (/22 subnet)                   │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────┐    │
│  │ Namespace: cloudflare-tunnel                              │    │
│  │  ┌────────────────────────────────────────────────────┐   │    │
│  │  │ cloudflared pods (x2 replicas)                     │   │    │
│  │  │ Routes traffic based on hostname                   │   │    │
│  │  └─────┬──────────────┬──────────────┬─────────────────   │    │
│  └────────┼──────────────┼──────────────┼────────────────────┘    │
│           │              │              │                          │
│           ▼              ▼              ▼                          │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐                  │
│  │Namespace:  │  │Namespace:  │  │Namespace:  │                  │
│  │pudim-dev   │  │luismachado │  │carimbo-vip │                  │
│  │            │  │  reis-dev  │  │            │                  │
│  │ ┌────────┐ │  │ ┌────────┐ │  │ ┌────────┐ │                  │
│  │ │Service │ │  │ │Service │ │  │ │Service │ │                  │
│  │ │ static │ │  │ │ static │ │  │ │ static │ │                  │
│  │ │ -site  │ │  │ │ -site  │ │  │ │ -site  │ │                  │
│  │ │ClusterIP│ │  │ │ClusterIP│ │  │ │ClusterIP│ │                  │
│  │ └───┬────┘ │  │ └───┬────┘ │  │ └───┬────┘ │                  │
│  │     │      │  │     │      │  │     │      │                  │
│  │ ┌───▼────┐ │  │ ┌───▼────┐ │  │ ┌───▼────┐ │                  │
│  │ │Nginx   │ │  │ │Nginx   │ │  │ │Nginx   │ │                  │
│  │ │Pods x3 │ │  │ │Pods x3 │ │  │ │Pods x3 │ │                  │
│  │ └───┬────┘ │  │ └───┬────┘ │  │ └───┬────┘ │                  │
│  │     │      │  │     │      │  │     │      │                  │
│  │ ┌───▼────┐ │  │ ┌───▼────┐ │  │ ┌───▼────┐ │                  │
│  │ │PVC     │ │  │ │PVC     │ │  │ │PVC     │ │                  │
│  │ │(NFS)   │ │  │ │(NFS)   │ │  │ │(NFS)   │ │                  │
│  │ │1Gi     │ │  │ │1Gi     │ │  │ │1Gi     │ │                  │
│  │ └───┬────┘ │  │ └───┬────┘ │  │ └───┬────┘ │                  │
│  └─────┼──────┘  └─────┼──────┘  └─────┼──────┘                  │
│        │                │                │                         │
│        └────────────────┼────────────────┘                         │
│                         ▼                                          │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │          NFS Server (Master Node: 192.168.5.200)            │  │
│  │          Shared Storage: /nfs/shared/                       │  │
│  └─────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │ Namespace: monitoring                                       │  │
│  │  Prometheus | Grafana | Loki | Alertmanager | Promtail     │  │
│  └─────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

Legend:
→  HTTP/HTTPS Traffic Flow
┌─ Kubernetes Namespace Boundary
│  Service/Pod/Resource

Traffic Flow:

  1. User requests pudim.dev, luismachadoreis.dev, or carimbo.vip
  2. DNS resolves to Cloudflare's network (CNAME → tunnel UUID)
  3. Cloudflare routes to your Cloudflare Tunnel (encrypted, token-authenticated)
  4. Tunnel pods inspect hostname and route to appropriate namespace service
  5. Service load-balances across 3 nginx pod replicas
  6. Nginx serves static content from NFS-backed persistent storage

Project Structure

homelabs/
├── README.md                    ← You are here
├── Vagrantfile                  ← VM configuration
├── docs/                        ← Documentation
│   ├── CLUSTER-INFO.md         ← Quick reference & access info
│   ├── SETUP-GUIDE.md          ← Complete setup tutorial
│   ├── LOKI-GUIDE.md           ← Log collection guide
│   ├── NFS-STORAGE-GUIDE.md    ← NFS shared storage guide
│   ├── GIT-QUICK-REFERENCE.md  ← Git commands reference
│   └── .gitignore-README.md    ← .gitignore guide
├── scripts/                     ← Installation & helper scripts
│   ├── setup-cluster.sh         ← Automated cluster setup
│   ├── install-k3s-master.sh    ← Master node installation
│   ├── install-k3s-worker.sh    ← Worker node installation
│   ├── install-observability.sh ← Monitoring stack installation
│   ├── setup-nfs-complete.sh    ← Complete NFS setup
│   ├── setup-nfs-server.sh      ← NFS server setup
│   ├── setup-nfs-clients.sh     ← NFS client setup
│   ├── deploy-nfs-provisioner.sh ← NFS CSI provisioner
│   ├── verify-cluster.sh        ← Cluster health check
│   └── ssh-nodes.sh             ← SSH helper
└── examples/                    ← Example manifests
    ├── nfs-test-deployment.yaml ← NFS test example
    ├── nfs-nginx-deployment.yaml ← Nginx with NFS
    └── nfs-statefulset.yaml     ← StatefulSet with NFS

Quick Start

Vagrant Commands

# Start all nodes
vagrant up

# Stop all nodes
vagrant halt

# Restart all nodes
vagrant reload

# Check status
vagrant status

# Destroy cluster
vagrant destroy -f

# Re-provision (apply configuration changes)
vagrant provision

SSH Access

Your SSH public key has been installed on all nodes for both vagrant and root users.

Direct SSH Access

# SSH as vagrant user
ssh vagrant@192.168.5.200  # master
ssh vagrant@192.168.5.201  # worker1
ssh vagrant@192.168.5.202  # worker2
ssh vagrant@192.168.5.203  # worker3

# SSH as root
ssh root@192.168.5.200     # master (root)
ssh root@192.168.5.201     # worker1 (root)

Using the Helper Script

# Quick access using the helper script
./scripts/ssh-nodes.sh master   # or: ./scripts/ssh-nodes.sh m
./scripts/ssh-nodes.sh worker1  # or: ./scripts/ssh-nodes.sh w1
./scripts/ssh-nodes.sh worker2  # or: ./scripts/ssh-nodes.sh w2
./scripts/ssh-nodes.sh worker3  # or: ./scripts/ssh-nodes.sh w3

Via Vagrant

vagrant ssh master
vagrant ssh worker1
vagrant ssh worker2
vagrant ssh worker3

Features

  • ✅ Debian Bookworm 64-bit
  • ✅ Bridged networking with static IPs
  • ✅ Kubernetes-ready configuration:
    • Swap disabled
    • IP forwarding enabled
    • Bridge netfilter enabled
    • br_netfilter module loaded
  • ✅ SSH key authentication enabled
  • ✅ Essential tools installed: curl, jq, net-tools, gnupg
  • ✅ Custom DNS configuration
  • ✅ Promiscuous mode enabled for networking
  • ✅ NFS shared storage (master node as NFS server)
    • Dynamic volume provisioning
    • ReadWriteMany support
    • Persistent storage for applications

Documentation

Testing Connectivity

# Ping all nodes
for ip in 192.168.5.{200..203}; do ping -c 1 $ip; done

# Run command on all nodes
for ip in 192.168.5.{200..203}; do 
  ssh vagrant@$ip "hostname && uptime"
done

View on GitHub
GitHub Stars14
CategoryDevelopment
Updated26d ago
Forks2

Languages

HCL

Security Score

80/100

Audited on Mar 13, 2026

No findings