Skip to content

Cluster

The cluster (noah) runs Talos Linux v1.12 on Proxmox VMs across four mini PCs. It is provisioned with OpenTofu and managed via Flux CD.

Physical Hosts

Host Hardware CPU RAM
pve1 GMKtec M2 Pro Intel i7-1195G7 (8t) 32 GB
pve2 GMKtec M5 Plus AMD Ryzen 7 5825U (16t) 32 GB
pve3 Beelink S13 Intel N150 (4t) 16 GB
pve4 Beelink S13 Intel N150 (4t) 16 GB

Node Topology

graph LR
    subgraph pve1["pve1 — GMKtec M2 Pro"]
        cp00["cp-00\n2 vCPU · 4 GB"]
        w0a["worker-0a\n6 vCPU · 14 GB · iGPU"]
        w0b["worker-0b\n6 vCPU · 13 GB"]
    end
    subgraph pve2["pve2 — GMKtec M5 Plus"]
        cp01["cp-01\n4 vCPU · 4 GB"]
        w1a["worker-1a\n10 vCPU · 14 GB"]
        w1b["worker-1b\n10 vCPU · 13 GB"]
    end
    subgraph pve3["pve3 — Beelink S13"]
        cp02["cp-02\n2 vCPU · 4 GB"]
        w2a["worker-2a\n4 vCPU · 11 GB"]
    end
    subgraph pve4["pve4 — Beelink S13"]
        w3a["worker-3a\n4 vCPU · 15 GB"]
    end
    cp00 ~~~ w0a ~~~ w0b
    cp01 ~~~ w1a ~~~ w1b
    cp02 ~~~ w2a
    pve1 ~~~ pve2 ~~~ pve3 ~~~ pve4
Hold "Alt" / "Option" to enable pan & zoom

Node Details

Node Host vCPU RAM
cp-00 pve1 2 4 GB
cp-01 pve2 4 4 GB
cp-02 pve3 2 4 GB
Node Host vCPU RAM Local Disk Notes
worker-0a pve1 6 14 GB 400 GB Intel iGPU; tainted dedicated=media:NoSchedule
worker-0b pve1 6 13 GB 400 GB
worker-1a pve2 10 14 GB 100 GB
worker-1b pve2 10 13 GB 100 GB
worker-2a pve3 4 11 GB 100 GB
worker-3a pve4 4 15 GB 100 GB

Media node

worker-0a is dedicated to media workloads (Jellyfin, Emby, etc.) via the dedicated=media:NoSchedule taint. Only pods with the matching toleration are scheduled there.

Networking

Subnet / Range Purpose
192.168.68.0/22 Home network / Proxmox hosts
192.168.68.50–192.168.70.255 DHCP range (dynamic clients)
192.168.71.0/24 Kubernetes nodes

Static IPs (Proxmox hosts, NAS, Kubernetes nodes, etc.) are assigned below 192.168.68.50, outside the DHCP range. Cilium manages an L2 LoadBalancer IP pool within the 192.168.71.0/24 subnet, used for the shared Gateway and Ingress Controller.

Storage

Type Used for
local-path Node-local PVCs; apps requiring fast local storage (e.g. SQLite)
Synology NFS CSI Shared persistent volumes backed by the NAS

See Storage for StorageClass details and provisioning patterns.

Management

The cluster is provisioned with OpenTofu (infrastructure as code) and application deployments are managed by Flux CD watching the flux branch of the Gitea repository.

Headlamp

Headlamp is a Kubernetes UI running at headlamp.hdhomelab.com. It provides a web interface for browsing cluster resources, workloads, events, and logs.

Authentication

Headlamp is authenticated via Authentik OIDC. Group membership maps to Kubernetes RBAC roles:

Authentik Group Kubernetes ClusterRole
headlamp_admin cluster-admin
headlamp_editor edit
headlamp_viewer view

Plugins

Plugins are installed by init containers at pod startup, each copying their assets into a shared headlamp-plugins PVC:

Plugin Source
Flux ghcr.io/headlamp-k8s/headlamp-plugin-flux
AI Assistant ghcr.io/headlamp-k8s/headlamp-plugin-ai-assistant
cert-manager ghcr.io/headlamp-k8s/headlamp-plugin-cert-manager
Prometheus Downloaded from GitHub releases at startup
App Catalog Downloaded from GitHub releases at startup
Plugin Catalog Downloaded from GitHub releases at startup

Plugin persistence

Plugins are stored in a PVC (headlamp-plugins) so they survive pod restarts without re-downloading. The init containers re-copy on each start to pick up image updates.