Architecture Overview
Personal infrastructure running on Euronodes VPS and home Proxmox nodes, interconnected via WireGuard mesh and orchestrated with Kubernetes (Talos).
Components
mermaid
graph TB
subgraph Internet
CF[Cloudflare DNS]
PD[PagerDuty]
GL[GitLab CI]
end
subgraph Bastion["Bastion (Euronodes VPS)"]
WG_HUB[WireGuard Hub]
OTEL_B[OTel Collector + Relay]
SEMAPHORE[Ansible Semaphore]
WEBHOOK[SigNoz Webhook Relay]
end
subgraph K8s["Kubernetes Cluster — quinza"]
CP[Control Plane - K2R4]
W1[Worker 1 - K4R8]
W2[Worker 2 - K4R8]
METALLB[MetalLB L2]
TRAEFIK[Traefik Ingress]
EXTDNS[ExternalDNS]
CNPG[CloudNativePG]
APPS[Apps Namespace]
ARGO[ArgoCD]
GLRUNNER[GitLab Runner]
OTEL_K8S[OTel DaemonSet]
OTEL_CNPG[OTel CNPG Collector]
end
subgraph EliteDesk["EliteDesk (Proxmox)"]
SIGNOZ[SigNoz - CT 101]
end
subgraph ThinkCentre["ThinkCentre (Proxmox)"]
ONEUPTIME[OneUptime - CT 100]
end
CF -->|HTTPS| TRAEFIK
METALLB -->|VIP 10.10.1.200| TRAEFIK
EXTDNS -->|DNS records| CF
SIGNOZ -->|alerts| WEBHOOK
WEBHOOK -->|triggers| SEMAPHORE
SEMAPHORE -->|runs| K8s
WG_HUB --- CP
WG_HUB --- W1
WG_HUB --- W2
WG_HUB --- EliteDesk
WG_HUB --- ThinkCentre
OTEL_K8S -->|OTLP| OTEL_B
OTEL_B -->|OTLP| SIGNOZ
SIGNOZ -->|alerts| PD
GL -->|triggers| ARGO
ARGO -->|syncs| K8sDesign Decisions
| Decision | Choice | Rationale |
|---|---|---|
| OS for K8s | Talos Linux | Immutable, API-driven, minimal attack surface |
| CNI | Flannel over WireGuard | Simple, works with --iface=wg0 for mesh routing |
| Load balancer | MetalLB (L2 mode) | VIP 10.10.1.200, Traefik behind LoadBalancer service |
| Ingress | Traefik (LoadBalancer) | Single VIP entry point via MetalLB |
| DNS automation | ExternalDNS | Auto-creates Cloudflare DNS A records from K8s Ingress |
| PostgreSQL | CloudNativePG | Operator-managed, HA-ready, StackGres incompatible with K8s v1.36 |
| Mesh VPN | WireGuard | Kernel-level performance, simple config |
| Observability | SigNoz + OTel | Open-source, OpenTelemetry-native, self-hosted |
| Incident management | OneUptime | Open-source PagerDuty alternative, status pages |
| Secrets | SOPS + age | Git-friendly encryption, no external KMS dependency |
| GitOps | ArgoCD | Deployed in K8s, syncs from GitLab, auto-prune |
| Auto-remediation | Ansible Semaphore | SigNoz alerts trigger Ansible playbooks via webhook relay |
| Config management | talosctl patches | talhelper v3 broken, raw patches are reliable |
| IaC | Ansible | WireGuard and Proxmox host provisioning |
| Internal CA | step-ca | Runs on bastion, issues internal TLS certs |
| CI Runner | GitLab Runner (K8s) | Helm chart, Kubernetes executor, no cloud runner dependency |
| Centralized secrets | Rejected (Infisical) | ~20GB RAM for 15 secrets; SOPS + age + Vault + 1Password is enough |
| NAT forwarding | nftables | Persistent MASQUERADE rules for WireGuard-to-LXC traffic |