- Complete project structure with Next.js frontend - GraphQL API backend with Apollo Server - Portal application with NextAuth - Crossplane Proxmox provider - GitOps configurations - CI/CD pipelines - Testing infrastructure (Vitest, Jest, Go tests) - Error handling and monitoring - Security hardening - UI component library - Documentation
245 lines
16 KiB
XML
245 lines
16 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1600 1100">
|
|
<defs>
|
|
<style>
|
|
.server { fill: #34495E; stroke: #2C3E50; stroke-width: 2; }
|
|
.k8s-node { fill: #326CE5; stroke: #1E4A8A; stroke-width: 2; }
|
|
.proxmox-node { fill: #E57000; stroke: #B85900; stroke-width: 2; }
|
|
.storage { fill: #95A5A6; stroke: #7F8C8D; stroke-width: 2; }
|
|
.network { fill: #3498DB; stroke: #2980B9; stroke-width: 1; }
|
|
.text { font-family: Arial, sans-serif; font-size: 11px; fill: #333; }
|
|
.title { font-size: 14px; font-weight: bold; }
|
|
.label { font-size: 9px; fill: #666; }
|
|
</style>
|
|
</defs>
|
|
|
|
<text x="800" y="30" text-anchor="middle" class="text title">Deployment Architecture - Infrastructure Layout</text>
|
|
|
|
<!-- Control Plane Cluster -->
|
|
<text x="400" y="70" text-anchor="middle" class="text title">Control Plane Cluster (Primary Site)</text>
|
|
|
|
<!-- K8s Master Nodes -->
|
|
<rect x="50" y="100" width="200" height="120" class="k8s-node" rx="5"/>
|
|
<text x="150" y="125" text-anchor="middle" class="text" fill="white">K8s Master 1</text>
|
|
<text x="150" y="145" text-anchor="middle" class="text" fill="white">etcd, API Server</text>
|
|
<text x="150" y="165" text-anchor="middle" class="text" fill="white">Scheduler, Controller</text>
|
|
<text x="150" y="185" text-anchor="middle" class="label" fill="white">CPU: 8 cores</text>
|
|
<text x="150" y="200" text-anchor="middle" class="label" fill="white">RAM: 32GB</text>
|
|
<text x="150" y="215" text-anchor="middle" class="label" fill="white">Disk: 500GB SSD</text>
|
|
|
|
<rect x="300" y="100" width="200" height="120" class="k8s-node" rx="5"/>
|
|
<text x="400" y="125" text-anchor="middle" class="text" fill="white">K8s Master 2</text>
|
|
<text x="400" y="145" text-anchor="middle" class="text" fill="white">etcd, API Server</text>
|
|
<text x="400" y="165" text-anchor="middle" class="text" fill="white">Scheduler, Controller</text>
|
|
<text x="400" y="185" text-anchor="middle" class="label" fill="white">CPU: 8 cores</text>
|
|
<text x="400" y="200" text-anchor="middle" class="label" fill="white">RAM: 32GB</text>
|
|
<text x="400" y="215" text-anchor="middle" class="label" fill="white">Disk: 500GB SSD</text>
|
|
|
|
<rect x="550" y="100" width="200" height="120" class="k8s-node" rx="5"/>
|
|
<text x="650" y="125" text-anchor="middle" class="text" fill="white">K8s Master 3</text>
|
|
<text x="650" y="145" text-anchor="middle" class="text" fill="white">etcd, API Server</text>
|
|
<text x="650" y="165" text-anchor="middle" class="text" fill="white">Scheduler, Controller</text>
|
|
<text x="650" y="185" text-anchor="middle" class="label" fill="white">CPU: 8 cores</text>
|
|
<text x="650" y="200" text-anchor="middle" class="label" fill="white">RAM: 32GB</text>
|
|
<text x="650" y="215" text-anchor="middle" class="label" fill="white">Disk: 500GB SSD</text>
|
|
|
|
<!-- K8s Worker Nodes -->
|
|
<rect x="100" y="260" width="180" height="100" class="k8s-node" rx="5"/>
|
|
<text x="190" y="285" text-anchor="middle" class="text" fill="white">Worker 1</text>
|
|
<text x="190" y="305" text-anchor="middle" class="text" fill="white">Rancher, Crossplane</text>
|
|
<text x="190" y="325" text-anchor="middle" class="text" fill="white">ArgoCD, Vault</text>
|
|
<text x="190" y="345" text-anchor="middle" class="label" fill="white">CPU: 16 cores, RAM: 64GB</text>
|
|
|
|
<rect x="320" y="260" width="180" height="100" class="k8s-node" rx="5"/>
|
|
<text x="410" y="285" text-anchor="middle" class="text" fill="white">Worker 2</text>
|
|
<text x="410" y="305" text-anchor="middle" class="text" fill="white">Portal (Next.js)</text>
|
|
<text x="410" y="325" text-anchor="middle" class="text" fill="white">Keycloak</text>
|
|
<text x="410" y="345" text-anchor="middle" class="label" fill="white">CPU: 16 cores, RAM: 64GB</text>
|
|
|
|
<rect x="540" y="260" width="180" height="100" class="k8s-node" rx="5"/>
|
|
<text x="630" y="285" text-anchor="middle" class="text" fill="white">Worker 3</text>
|
|
<text x="630" y="305" text-anchor="middle" class="text" fill="white">Prometheus, Grafana</text>
|
|
<text x="630" y="325" text-anchor="middle" class="text" fill="white">Loki, Tempo</text>
|
|
<text x="630" y="345" text-anchor="middle" class="label" fill="white">CPU: 16 cores, RAM: 64GB</text>
|
|
|
|
<!-- Storage for Control Plane -->
|
|
<rect x="750" y="100" width="150" height="260" class="storage" rx="5"/>
|
|
<text x="825" y="125" text-anchor="middle" class="text" fill="white">Shared Storage</text>
|
|
<text x="825" y="150" text-anchor="middle" class="text" fill="white">(NFS/Ceph)</text>
|
|
<text x="825" y="180" text-anchor="middle" class="label" fill="white">• ETCD Backups</text>
|
|
<text x="825" y="200" text-anchor="middle" class="label" fill="white">• PVC Storage</text>
|
|
<text x="825" y="220" text-anchor="middle" class="label" fill="white">• Log Archives</text>
|
|
<text x="825" y="240" text-anchor="middle" class="label" fill="white">• Metrics Data</text>
|
|
<text x="825" y="260" text-anchor="middle" class="label" fill="white">• Config Backups</text>
|
|
<text x="825" y="280" text-anchor="middle" class="label" fill="white">Capacity: 10TB</text>
|
|
<text x="825" y="300" text-anchor="middle" class="label" fill="white">Replication: 3x</text>
|
|
<text x="825" y="320" text-anchor="middle" class="label" fill="white">Type: Ceph RBD</text>
|
|
<text x="825" y="340" text-anchor="middle" class="label" fill="white">Performance: NVMe</text>
|
|
|
|
<!-- Proxmox Site 1 -->
|
|
<text x="1200" y="70" text-anchor="middle" class="text title">Proxmox Site 1 - US-East</text>
|
|
|
|
<rect x="950" y="100" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="1050" y="125" text-anchor="middle" class="text" fill="white">PVE Node 1</text>
|
|
<text x="1050" y="145" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="1050" y="165" text-anchor="middle" class="label" fill="white">CPU: 32 cores</text>
|
|
<text x="1050" y="180" text-anchor="middle" class="label" fill="white">RAM: 256GB</text>
|
|
<text x="1050" y="195" text-anchor="middle" class="label" fill="white">VMs: 20</text>
|
|
<text x="1050" y="210" text-anchor="middle" class="label" fill="white">Storage: Ceph OSD</text>
|
|
|
|
<rect x="1200" y="100" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="1300" y="125" text-anchor="middle" class="text" fill="white">PVE Node 2</text>
|
|
<text x="1300" y="145" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="1300" y="165" text-anchor="middle" class="label" fill="white">CPU: 32 cores</text>
|
|
<text x="1300" y="180" text-anchor="middle" class="label" fill="white">RAM: 256GB</text>
|
|
<text x="1300" y="195" text-anchor="middle" class="label" fill="white">VMs: 18</text>
|
|
<text x="1300" y="210" text-anchor="middle" class="label" fill="white">Storage: Ceph OSD</text>
|
|
|
|
<rect x="1450" y="100" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="1550" y="125" text-anchor="middle" class="text" fill="white">PVE Node 3</text>
|
|
<text x="1550" y="145" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="1550" y="165" text-anchor="middle" class="label" fill="white">CPU: 32 cores</text>
|
|
<text x="1550" y="180" text-anchor="middle" class="label" fill="white">RAM: 256GB</text>
|
|
<text x="1550" y="195" text-anchor="middle" class="label" fill="white">VMs: 15</text>
|
|
<text x="1550" y="210" text-anchor="middle" class="label" fill="white">Storage: Ceph OSD</text>
|
|
|
|
<!-- Ceph Storage Cluster -->
|
|
<rect x="1000" y="260" width="500" height="100" class="storage" rx="5"/>
|
|
<text x="1250" y="285" text-anchor="middle" class="text" fill="white">Ceph Storage Cluster</text>
|
|
<text x="1100" y="310" text-anchor="middle" class="label" fill="white">MON: 3 nodes</text>
|
|
<text x="1250" y="310" text-anchor="middle" class="label" fill="white">OSD: 9 nodes</text>
|
|
<text x="1400" y="310" text-anchor="middle" class="label" fill="white">MDS: 2 nodes</text>
|
|
<text x="1250" y="330" text-anchor="middle" class="label" fill="white">Total: 200TB, Replication: 3x</text>
|
|
|
|
<!-- Proxmox Site 2 -->
|
|
<text x="400" y="420" text-anchor="middle" class="text title">Proxmox Site 2 - EU-West</text>
|
|
|
|
<rect x="50" y="450" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="150" y="475" text-anchor="middle" class="text" fill="white">PVE Node 1</text>
|
|
<text x="150" y="495" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="150" y="515" text-anchor="middle" class="label" fill="white">CPU: 24 cores</text>
|
|
<text x="150" y="530" text-anchor="middle" class="label" fill="white">RAM: 192GB</text>
|
|
<text x="150" y="545" text-anchor="middle" class="label" fill="white">VMs: 15</text>
|
|
<text x="150" y="560" text-anchor="middle" class="label" fill="white">Storage: ZFS</text>
|
|
|
|
<rect x="300" y="450" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="400" y="475" text-anchor="middle" class="text" fill="white">PVE Node 2</text>
|
|
<text x="400" y="495" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="400" y="515" text-anchor="middle" class="label" fill="white">CPU: 24 cores</text>
|
|
<text x="400" y="530" text-anchor="middle" class="label" fill="white">RAM: 192GB</text>
|
|
<text x="400" y="545" text-anchor="middle" class="label" fill="white">VMs: 12</text>
|
|
<text x="400" y="560" text-anchor="middle" class="label" fill="white">Storage: ZFS</text>
|
|
|
|
<rect x="550" y="450" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="650" y="475" text-anchor="middle" class="text" fill="white">PVE Node 3</text>
|
|
<text x="650" y="495" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="650" y="515" text-anchor="middle" class="label" fill="white">CPU: 24 cores</text>
|
|
<text x="650" y="530" text-anchor="middle" class="label" fill="white">RAM: 192GB</text>
|
|
<text x="650" y="545" text-anchor="middle" class="label" fill="white">VMs: 10</text>
|
|
<text x="650" y="560" text-anchor="middle" class="label" fill="white">Storage: ZFS</text>
|
|
|
|
<!-- ZFS Storage -->
|
|
<rect x="100" y="610" width="500" height="80" class="storage" rx="5"/>
|
|
<text x="350" y="635" text-anchor="middle" class="text" fill="white">ZFS Storage Pools</text>
|
|
<text x="250" y="660" text-anchor="middle" class="label" fill="white">Pool 1: 50TB (RAID-Z2)</text>
|
|
<text x="450" y="660" text-anchor="middle" class="label" fill="white">Pool 2: 30TB (RAID-Z1)</text>
|
|
<text x="350" y="680" text-anchor="middle" class="label" fill="white">Replication: Async to Site 1</text>
|
|
|
|
<!-- Proxmox Site 3 -->
|
|
<text x="1200" y="420" text-anchor="middle" class="text title">Proxmox Site 3 - APAC</text>
|
|
|
|
<rect x="950" y="450" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="1050" y="475" text-anchor="middle" class="text" fill="white">PVE Node 1</text>
|
|
<text x="1050" y="495" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="1050" y="515" text-anchor="middle" class="label" fill="white">CPU: 16 cores</text>
|
|
<text x="1050" y="530" text-anchor="middle" class="label" fill="white">RAM: 128GB</text>
|
|
<text x="1050" y="545" text-anchor="middle" class="label" fill="white">VMs: 10</text>
|
|
<text x="1050" y="560" text-anchor="middle" class="label" fill="white">Storage: Local</text>
|
|
|
|
<rect x="1200" y="450" width="200" height="120" class="proxmox-node" rx="5"/>
|
|
<text x="1300" y="475" text-anchor="middle" class="text" fill="white">PVE Node 2</text>
|
|
<text x="1300" y="495" text-anchor="middle" class="text" fill="white">Hypervisor</text>
|
|
<text x="1300" y="515" text-anchor="middle" class="label" fill="white">CPU: 16 cores</text>
|
|
<text x="1300" y="530" text-anchor="middle" class="label" fill="white">RAM: 128GB</text>
|
|
<text x="1300" y="545" text-anchor="middle" class="label" fill="white">VMs: 8</text>
|
|
<text x="1300" y="560" text-anchor="middle" class="label" fill="white">Storage: Local</text>
|
|
|
|
<!-- Local Storage -->
|
|
<rect x="1000" y="610" width="400" height="80" class="storage" rx="5"/>
|
|
<text x="1200" y="635" text-anchor="middle" class="text" fill="white">Local Storage</text>
|
|
<text x="1100" y="660" text-anchor="middle" class="label" fill="white">Node 1: 20TB SSD</text>
|
|
<text x="1300" y="660" text-anchor="middle" class="label" fill="white">Node 2: 20TB SSD</text>
|
|
<text x="1200" y="680" text-anchor="middle" class="label" fill="white">Backup: Daily to Site 1</text>
|
|
|
|
<!-- Network Infrastructure -->
|
|
<rect x="50" y="730" width="1500" height="120" class="network" rx="5"/>
|
|
<text x="800" y="755" text-anchor="middle" class="text title">Network Infrastructure</text>
|
|
|
|
<rect x="100" y="770" width="200" height="60" class="server" rx="3"/>
|
|
<text x="200" y="790" text-anchor="middle" class="text" fill="white">Load Balancer</text>
|
|
<text x="200" y="810" text-anchor="middle" class="label" fill="white">HAProxy / MetalLB</text>
|
|
<text x="200" y="825" text-anchor="middle" class="label" fill="white">VIP: 10.0.0.10</text>
|
|
|
|
<rect x="350" y="770" width="200" height="60" class="server" rx="3"/>
|
|
<text x="450" y="790" text-anchor="middle" class="text" fill="white">Gateway Router</text>
|
|
<text x="450" y="810" text-anchor="middle" class="label" fill="white">BGP / OSPF</text>
|
|
<text x="450" y="825" text-anchor="middle" class="label" fill="white">10.0.0.1</text>
|
|
|
|
<rect x="600" y="770" width="200" height="60" class="server" rx="3"/>
|
|
<text x="700" y="790" text-anchor="middle" class="text" fill="white">DNS Server</text>
|
|
<text x="700" y="810" text-anchor="middle" class="label" fill="white">CoreDNS / BIND</text>
|
|
<text x="700" y="825" text-anchor="middle" class="label" fill="white">10.0.0.53</text>
|
|
|
|
<rect x="850" y="770" width="200" height="60" class="server" rx="3"/>
|
|
<text x="950" y="790" text-anchor="middle" class="text" fill="white">NTP Server</text>
|
|
<text x="950" y="810" text-anchor="middle" class="label" fill="white">Chrony / NTPd</text>
|
|
<text x="950" y="825" text-anchor="middle" class="label" fill="white">Time Sync</text>
|
|
|
|
<rect x="1100" y="770" width="200" height="60" class="server" rx="3"/>
|
|
<text x="1200" y="790" text-anchor="middle" class="text" fill="white">Monitoring Node</text>
|
|
<text x="1200" y="810" text-anchor="middle" class="label" fill="white">Prometheus Exporter</text>
|
|
<text x="1200" y="825" text-anchor="middle" class="label" fill="white">10.0.0.100</text>
|
|
|
|
<rect x="1350" y="770" width="200" height="60" class="server" rx="3"/>
|
|
<text x="1450" y="790" text-anchor="middle" class="text" fill="white">Backup Server</text>
|
|
<text x="1450" y="810" text-anchor="middle" class="label" fill="white">Proxmox Backup</text>
|
|
<text x="1450" y="825" text-anchor="middle" class="label" fill="white">10.0.0.200</text>
|
|
|
|
<!-- Cloudflare Tunnels -->
|
|
<rect x="50" y="890" width="1500" height="80" class="network" rx="5" fill="#F38020" opacity="0.3"/>
|
|
<text x="800" y="915" text-anchor="middle" class="text title">Cloudflare Tunnel Agents</text>
|
|
|
|
<rect x="100" y="930" width="150" height="30" class="server" rx="3"/>
|
|
<text x="175" y="948" text-anchor="middle" class="label">Control Plane Tunnel</text>
|
|
|
|
<rect x="300" y="930" width="150" height="30" class="server" rx="3"/>
|
|
<text x="375" y="948" text-anchor="middle" class="label">Site 1 Tunnel</text>
|
|
|
|
<rect x="500" y="930" width="150" height="30" class="server" rx="3"/>
|
|
<text x="575" y="948" text-anchor="middle" class="label">Site 2 Tunnel</text>
|
|
|
|
<rect x="700" y="930" width="150" height="30" class="server" rx="3"/>
|
|
<text x="775" y="948" text-anchor="middle" class="label">Site 3 Tunnel</text>
|
|
|
|
<rect x="900" y="930" width="150" height="30" class="server" rx="3"/>
|
|
<text x="975" y="948" text-anchor="middle" class="label">Portal Tunnel</text>
|
|
|
|
<rect x="1100" y="930" width="150" height="30" class="server" rx="3"/>
|
|
<text x="1175" y="948" text-anchor="middle" class="label">API Tunnel</text>
|
|
|
|
<rect x="1300" y="930" width="150" height="30" class="server" rx="3"/>
|
|
<text x="1375" y="948" text-anchor="middle" class="label">Monitoring Tunnel</text>
|
|
|
|
<!-- Legend -->
|
|
<rect x="50" y="1000" width="300" height="80" class="network" rx="5"/>
|
|
<text x="200" y="1020" text-anchor="middle" class="text title">Legend</text>
|
|
<rect x="70" y="1030" width="30" height="20" class="k8s-node" rx="2"/>
|
|
<text x="110" y="1045" class="label">Kubernetes Node</text>
|
|
<rect x="70" y="1055" width="30" height="20" class="proxmox-node" rx="2"/>
|
|
<text x="110" y="1070" class="label">Proxmox Node</text>
|
|
<rect x="200" y="1030" width="30" height="20" class="storage" rx="2"/>
|
|
<text x="240" y="1045" class="label">Storage</text>
|
|
<rect x="200" y="1055" width="30" height="20" class="network" rx="2"/>
|
|
<text x="240" y="1070" class="label">Network/Service</text>
|
|
</svg>
|
|
|