Lab · Sheet 03
The stack.
What runs on the metal, layer by layer. Dashed is next.
| Rev | Description | Date | By |
|---|---|---|---|
| A | First issue | 2026-09-29 | TD |
| B | Gateway, cert-manager, first app | 2026-09-29 | TD |
| C | Metrics, logs, Grafana | 2026-09-29 | TD |
| D | R730, CloudNativePG, RustFS, three apps, GitHub runner | 2026-10-03 | TD |
- Project
- HOMELAB
- Title
- The stack
- Scale
- AS NOTED
- Units
- mm
- Sheet
- 3 OF 3
- Rev
- D
- Date
- 2026-10-03
- Drawn
- TD
- Checked
- TD
- Dwg no
- TD-LAB-03
Metal
Dell PowerEdge R730
- 64 threads, 512 GB RAM, ten drives.
- Its RAID card runs in HBA mode, so every disk goes straight to ZFS.
Storage
ZFS pools
- rpool: boot, a 3-way mirror.
- fast: VM disks, a 3-way mirror with a hot spare.
- bulk: scratch, one disk.
Hypervisor
Proxmox VE 9.2
- Installed by hand, on ZFS.
- Ansible configures it after that.
Ansible playbook
Host config
- Hourly and daily ZFS snapshots of the VM pool.
- SMART self-tests and ZFS event alerts.
- Push alerts to my phone, through ntfy.
- Metrics exporters for the host and its hardware.
Control node
Raspberry Pi 4
- The control node, on the top shelf.
- Configured by Ansible, like the host.
Gateway
UniFi Dream Machine Pro
- Router and firewall. Everything else hangs off it.
Network storage
UniFi UNAS Pro 8
- NFS storage, 10 GbE from the gateway.
Kubernetes cluster
Talos nodes ×3
- Three VMs, each 8 vCPU, 24 GiB RAM and 64 GB on fast.
- Talos 1.14, running Kubernetes 1.37.
- All three are control plane, and all three run workloads.
- The OS image comes from Sidero’s Image Factory.
Standalone VM
GitHub runner
- Self-hosted GitHub Actions runners, in their own VM.
- 8 vCPU, 16 GiB RAM, 200 GB on bulk.
Standalone VM · planned
robomp
- The oh-my-pi GitHub bot, in its own VM.
- It will triage my personal projects and fix them through PRs.
Networking
Cilium 1.20
- The cluster’s network (CNI).
- Replaces kube-proxy.
- Hubble shows the traffic.
- Its Gateway API serves my apps over HTTPS.
Metrics
metrics-server 0.9
- CPU and memory use per node and pod.
- It’s what makes kubectl top work.
GitOps
Flux
- Keeps the cluster in step with the repo.
- Took over Cilium from Helm, and runs everything after it.
Certificates
cert-manager 1.21
- Issues and renews certificates.
- Let’s Encrypt ones, so my apps get real HTTPS.
Secrets
External Secrets
- External Secrets with 1Password Connect.
- Apps get their secrets from 1Password.
Block storage
Proxmox CSI
- Volumes carved out of the fast pool by default, bulk on request.
- Attached to whichever node runs the pod.
Metrics and logs
Observability
- VictoriaMetrics for metrics, VictoriaLogs for logs.
- Grafana for looking at both.
- The alert rules run, and they page my phone through ntfy.
Databases
CloudNativePG 1.30
- Postgres, for the apps that want one.
- Its backups land in RustFS.
Object storage
RustFS 1.0
- S3-compatible storage inside the cluster.
- Database backups land here.
Guardrails
Admission policies
- Built-in Kubernetes rules that turn risky changes away.
Shared storage · planned
NFS CSI
- Volumes on the UNAS, over NFS.
Backups · planned
VolSync
- Backs up the cluster’s volumes to the UNAS.
Cluster UI
Headlamp
- A web UI for the cluster.
- The first app in, mostly so I can click instead of type.
Dashboard
Homepage 2.4
- A start page for the lab.
- Everything I run, one click away.
Status page
Gatus 5.37
- Checks that everything answers.
- Pages my phone when something doesn’t.
Registry
Zot 2.1
- A private container registry.
- Container images stay in the lab.
Hypervisor
Proxmox VE 9.2
- Installed by hand, on ZFS.
- Ansible configures it after that.
Kubernetes cluster
Talos nodes ×3
- Three VMs, each 8 vCPU, 24 GiB RAM and 64 GB on fast.
- Talos 1.14, running Kubernetes 1.37.
- All three are control plane, and all three run workloads.
- The OS image comes from Sidero’s Image Factory.
Networking
Cilium 1.20
- The cluster’s network (CNI).
- Replaces kube-proxy.
- Hubble shows the traffic.
- Its Gateway API serves my apps over HTTPS.
Block storage
Proxmox CSI
- Volumes carved out of the fast pool by default, bulk on request.
- Attached to whichever node runs the pod.
VM disks · 3-way mirror
fast
- Bays 1, 2 and 3, about 1.45 TiB.
- Bay 0 is the hot spare.
- Where the VMs and the cluster’s volumes live.
One endpoint
Kubernetes API
- One address for the whole cluster, shared by every node.
- One node answers at a time. If it goes down, another takes over.
Line key
- Running
- Planned
- Cut: walls, floors, pools
- Network
Layer by layer
- Layers
- 3
- Running
- 23
- Planned
- 3
- Talos nodes
- 3
03 Kubernetes
Built with Helm → Flux
- Cilium 1.20 Networking: CNI, kube-proxy replacement, Hubble running
- metrics-server 0.9 CPU and memory use, for kubectl top running
- Flux GitOps from the repo running
- cert-manager 1.21 Certificates running
- External Secrets Secrets from 1Password running
- Proxmox CSI Block storage on fast and bulk running
- VictoriaMetrics + VictoriaLogs + Grafana Metrics, logs and dashboards running
- CloudNativePG 1.30 Postgres running
- RustFS 1.0 S3 storage in the cluster running
- Admission policies Guardrails running
- NFS CSI Shared storage on the UNAS planned
- VolSync Backups planned
- Headlamp A web UI for the cluster running
- Homepage 2.4 A start page for the lab running
- Gatus 5.37 Status page and uptime checks running
- Zot 2.1 A private container registry running
02 Virtual machines
Built with OpenTofu
- Talos nodes 1.14 Control plane and workloads, all three running
- GitHub runner Self-hosted CI runners running
- robomp The oh-my-pi GitHub bot planned
01 Bootstrap
Built with Ansible
- Dell R730 The one server: 64 threads, 512 GB running
- ZFS pools rpool, fast and bulk running
- Proxmox VE 9.2 The hypervisor, on ZFS running
- Host config Snapshots, disk checks, alerts, metrics running
- Raspberry Pi 4 The control node running
- UDM Pro Gateway and firewall running
- UNAS Pro 8 NFS storage over 10 GbE running