Architecture

Architecture Diagrams

Physical layout, network trust zones, the platform capability map, and how change and inference actually flow through the system.

Diagrams are created in Excalidraw.


Physical Architecture

Physical Architecture

Three HP workstations form a Proxmox cluster, each running Talos VMs for the Kubernetes control plane and workers. The HP Z440 hosts the GPU worker (kube-worker-ai) with dual RTX 3060s for local LLM inference. The HP EliteDesk 800 also runs the Proxmox Backup Server (PBS) and Home Assistant VMs. All cluster nodes connect to a Synology DS1817+ for iSCSI primary storage, which also receives Proxmox VM backups.


Network Layout

Network Layout

The network is segmented into trust zones enforced at the firewall:

Zone Trust Level Notes
Internal Trusted Primary LAN; unrestricted access to Home Lab
Internal WiFi Trusted Wireless extension of Internal
Home Lab Separated Kubernetes cluster traffic; very restricted DMZ access
IoT Untrusted Isolated; Internal can push to it, not pull
IoT WiFi Untrusted Wireless extension of IoT
DMZ Untrusted Externally exposed services only; Cloudflare fronted
Proxmox Cluster Separated Inter-node cluster traffic
Storage Area Network Separated iSCSI traffic to Synology

Two ingress paths, two jobs. A Cloudflare Tunnel fronts the handful of deliberately public hostnames, terminating in the DMZ. A Tailscale subnet router advertises the LAN into a private tailnet, which is how I administer the platform remotely — no open inbound ports, and admin interfaces never reach the public internet at all. Neither path is a fallback for the other; the reasoning is in ADR 015.


Platform View

Platform View

The Talos Kubernetes platform is organised into seven capability areas:

Area Components
GitOps Development Argo CD, Gitea, Gitea Runner, Renovate, Velero
Networking & Segmentation Cilium, Istio Ambient, MetalLB
Data Persistence CloudNativePG, MinIO, Synology CSI
Observability Dozzle, Netdata, Ntfy, Uptime Kuma, Hubble, Kiali, metrics-server, Goldilocks
Security & Compliance Authentik, Cert-Manager, Checkov, External-Secrets, Falco, Gitleaks, Kube-bench, Polaris, Trivy, Vault
Local AI Platform Nvidia Device Plugin, 12 MCP Servers, Ollama, vLLM, Open Web UI
User Apps Homepage, Karakeep, Outline, Paperless, Wallos, big-ads, big-recipes

Two things this map deliberately does not show. The Tailscale subnet router is absent because it runs in an LXC beside the cluster rather than on it — that separation is the whole point of ADR 015. And Cortexa is absent because it isn’t deployed here; it runs from a local venv and consumes the platform’s Postgres and inference endpoint from outside.


GitOps Delivery Flow

GitOps Delivery Flow

How a change actually reaches production. The distinctive part is the two-repository handoff: CI doesn’t deploy anything. It builds an image, pushes it to the in-cluster registry, then clones the GitOps repo and patches the image tag in the deployment manifest. ArgoCD notices the manifest change and reconciles. Nothing is ever applied directly to the cluster.

Note where the boundary sits: the Git server, the runner, and the container registry all live inside the cluster they deploy to. That circularity is deliberate and its recovery implications are covered in ADR 002. Renovate feeds dependency updates into the same loop, so a base-image bump travels the identical path as a hand-written commit — through tests, secret scanning, and a manifest patch.

big-ads has shipped nine releases through this pipeline with no manual steps.


GPU Inference Stack

GPU Inference Stack

The layered chain behind local inference, and the reason it took real work to get right: every boundary in this diagram is a layer that can fail silently and look like the next layer’s problem. PCIe passthrough with correct IOMMU grouping at the Proxmox layer, NVIDIA kernel extensions baked into a custom Talos image, the device plugin advertising nvidia.com/gpu to the scheduler, and finally CUDA inside the container. The dedicated=ai:NoSchedule taint keeps everything else off the node.

Both RTX 3060s are driven as one pool: vLLM runs tensor-parallel across the pair, which is what makes a quantized 30B model fit at all. The GPU Ollama deployment is scaled to zero — the two runtimes divide the work rather than sharing the silicon (ADR 014).

The dashed line is honest about a migration in progress: Open WebUI still points at the Ollama endpoint and hasn’t been repointed to vLLM’s OpenAI-compatible API. Cortexa sits outside the hardware boundary entirely — it runs on my workstation and reaches vLLM through an external gateway provisioned for exactly that purpose.