digraph storage_flow { rankdir=LR; graph [ fontname="Helvetica Neue", fontsize=16, pad=1.2, nodesep=0.45, ranksep=1.6, bgcolor="#f0f4f8", label="ExpertFab – Speicherfluss & HA-Analyse", labelloc=t, labeljust=c, splines=polyline, compound=true, newrank=true, ]; node [fontname="Helvetica Neue", fontsize=11, shape=box, style="filled,rounded", margin="0.15,0.10"]; edge [fontname="Helvetica Neue", fontsize=10, arrowsize=0.8]; /* ───────────────────────────────────────────── SCHICHT 1 – APPLIKATIONEN ───────────────────────────────────────────── */ subgraph cluster_apps { label=<① APPLIKATIONEN
(K3s Pods)>; style=filled; bgcolor="#e3eef7"; color="#2980b9"; penwidth=2; fontcolor="#1a5276"; subgraph cluster_erpnext { label="ns: erpnext"; style=filled; bgcolor="#d6eaf8"; color="#5dade2"; gui [label=<Gunicorn
+ Workers>, shape=hexagon, fillcolor="#aed6f1", color="#2980b9"]; nginx [label=<Nginx
(Frontend)>, shape=hexagon, fillcolor="#aed6f1", color="#2980b9"]; mdb [label=<MariaDB 10.6
StatefulSet>, shape=cylinder, fillcolor="#fdebd0", color="#d35400"]; } subgraph cluster_paperless { label="ns: paperless"; style=filled; bgcolor="#d6eaf8"; color="#5dade2"; ppl [label=<Paperless-NGX>, shape=hexagon, fillcolor="#aed6f1", color="#2980b9"]; pgp [label=<PostgreSQL>, shape=cylinder, fillcolor="#fdebd0", color="#d35400"]; } subgraph cluster_zitadel { label="ns: zitadel"; style=filled; bgcolor="#d6eaf8"; color="#5dade2"; pgz [label=<PostgreSQL
(Zitadel)>, shape=cylinder, fillcolor="#fdebd0", color="#d35400"]; } subgraph cluster_rmq { label="ns: rabbitmq"; style=filled; bgcolor="#d6eaf8"; color="#5dade2"; rmq [label=<RabbitMQ>, shape=cylinder, fillcolor="#fdebd0", color="#d35400"]; } } /* ───────────────────────────────────────────── SCHICHT 2 – PVCs ───────────────────────────────────────────── */ subgraph cluster_pvcs { label=<② KUBERNETES PVCs>; style=filled; bgcolor="#eaf5ea"; color="#27ae60"; penwidth=2; fontcolor="#1e8449"; subgraph cluster_pvc_erpnext { label=<longhorn-erpnext [Retain ✅]>; style=filled; bgcolor="#d5f5e3"; color="#52be80"; pvc_mdb [label=<mariadb-sts-0
3 Gi RWO>, fillcolor="#d5f5e3", color="#1e8449"]; pvc_sites [label=<erpnext-sites
3 Gi RWX ⚠>, fillcolor="#fef9e7", color="#e67e22"]; pvc_logs [label=<erpnext-logs
1 Gi RWX ⚠>, fillcolor="#fef9e7", color="#e67e22"]; } subgraph cluster_pvc_paperless { label=<longhorn-paperless [Retain ✅]>; style=filled; bgcolor="#d5f5e3"; color="#52be80"; pvc_ppl [label=<media
10 Gi RWO>, fillcolor="#d5f5e3", color="#1e8449"]; pvc_pgp [label=<postgres
5 Gi RWO>, fillcolor="#d5f5e3", color="#1e8449"]; } subgraph cluster_pvc_del { label=<longhorn [Delete ]>; style=filled; bgcolor="#fef9e7"; color="#e67e22"; pvc_pgz [label=<zitadel-pg
10 Gi RWO>, fillcolor="#fef9e7", color="#d35400"]; pvc_rmq [label=<rabbitmq
5 Gi RWO>, fillcolor="#fef9e7", color="#d35400"]; } } /* ───────────────────────────────────────────── SCHICHT 3 – LONGHORN ENGINE ───────────────────────────────────────────── */ subgraph cluster_longhorn { label=<③ LONGHORN STORAGE ENGINE
(driver.longhorn.io)>; style=filled; bgcolor="#f4ecf7"; color="#8e44ad"; penwidth=2; fontcolor="#6c3483"; subgraph cluster_sm { label=<⚠ RWX Share-Manager
läuft auf: efsckubnode02 (Proxmox n01)
→ SPOF: fällt n01, fallen RWX-Volumes (ERPNext)
>; style=filled; bgcolor="#fef9e7"; color="#e67e22"; penwidth=2; sm_sites [label=<share-manager
erpnext-sites>, shape=ellipse, fillcolor="#fdebd0", color="#e67e22"]; sm_logs [label=<share-manager
erpnext-logs>, shape=ellipse, fillcolor="#fdebd0", color="#e67e22"]; } subgraph cluster_replicas { label=<✅ Block-Replikation: 2 Replicas je Volume
Daten auf verschiedenen K3s-Worker-Nodes
>; style=filled; bgcolor="#eafaf1"; color="#27ae60"; penwidth=2; rep_a [label=<Replica A
auf: efsckubnode1
(Proxmox n02)>, shape=cylinder, fillcolor="#d5f5e3", color="#1e8449"]; rep_b [label=<Replica B
auf: efsckubnode02
(Proxmox n01)>, shape=cylinder, fillcolor="#d5f5e3", color="#1e8449"]; } subgraph cluster_csi { label=<⚠ CSI Controller-Pods
Nur auf efsckubnode1 (n02)
→ fällt n02: keine neuen Volumes
>; style=filled; bgcolor="#fef9e7"; color="#e67e22"; csi [label=<csi-attacher (3×)
csi-provisioner (3×)
csi-resizer (3×)>, fillcolor="#fdebd0", color="#e67e22"]; } } /* ───────────────────────────────────────────── SCHICHT 4 – K3s NODES (VMs) ───────────────────────────────────────────── */ subgraph cluster_k3s { label=<④ K3s CLUSTER>; style=filled; bgcolor="#fdf2f8"; color="#c0392b"; penwidth=2; fontcolor="#922b21"; subgraph cluster_ctrl { label=<🔴 Control Plane – SINGLE POINT OF FAILURE
Nur 1 Node, VM auf Proxmox n01
→ n01 fällt = kein Cluster-Management, kein Pod-Rescheduling
>; style=filled; bgcolor="#fadbd8"; color="#e74c3c"; penwidth=3; kubadm [label=<efsckubadm
10.42.71.50
VM: efsckubctl (n01)>, shape=diamond, fillcolor="#f1948a", color="#c0392b"]; } subgraph cluster_workers { label=<✅ Worker Nodes auf verschiedenen Proxmox Hosts>; style=filled; bgcolor="#eafaf1"; color="#27ae60"; node1 [label=<efsckubnode1
10.42.71.51
VM auf: Proxmox n02
→ Replica A + CSI Controllers>, fillcolor="#d5f5e3", color="#1e8449"]; node2 [label=<efsckubnode02
10.42.71.52
VM auf: Proxmox n01
→ Replica B + share-manager>, fillcolor="#fdebd0", color="#e67e22"]; } } /* ───────────────────────────────────────────── SCHICHT 5 – PROXMOX HOSTS ───────────────────────────────────────────── */ subgraph cluster_proxmox { label=<⑤ PROXMOX CLUSTER efproxcl02
⚠ Nur 2 Nodes – kein 3-Node-Quorum / kein automatisches Fencing>; style=filled; bgcolor="#fdfefe"; color="#7f8c8d"; penwidth=2; subgraph cluster_pn01 { label=<efproxcl02n01 10.42.70.1
🔴 KRITISCH: Control-Plane + efsckubnode02 + share-manager
Ausfall → ERPNext vollständig down (kein Rescheduling möglich)
>; style=filled; bgcolor="#fadbd8"; color="#e74c3c"; penwidth=2; pn01 [label=<Proxmox Host 1
64 vCPU / 128 GB RAM>, shape=box, fillcolor="#f1948a", color="#c0392b"]; disk_n01 [label=<Lokaler Speicher
Replica B
erpnext / paperless
zitadel / rabbitmq
>, shape=cylinder, fillcolor="#fadbd8", color="#e74c3c"]; } subgraph cluster_pn02 { label=<efproxcl02n02 10.42.70.2
🟡 Ausfall → degradiert: Daten intakt (Replica B ok)
Keine neuen Volumes (CSI weg), ERPNext-Pods reschedule auf node02
>; style=filled; bgcolor="#fef9e7"; color="#e67e22"; penwidth=2; pn02 [label=<Proxmox Host 2
64 vCPU / 128 GB RAM>, shape=box, fillcolor="#fdebd0", color="#d35400"]; disk_n02 [label=<Lokaler Speicher
Replica A
erpnext / paperless
zitadel / rabbitmq
>, shape=cylinder, fillcolor="#fef9e7", color="#e67e22"]; } } /* ───────────────────────────────────────────── EDGES ───────────────────────────────────────────── */ /* Apps → PVCs */ mdb -> pvc_mdb [color="#2980b9", penwidth=2]; gui -> pvc_sites [color="#2980b9", penwidth=2]; nginx -> pvc_logs [color="#2980b9", penwidth=2]; ppl -> pvc_ppl [color="#2980b9", penwidth=2]; pgp -> pvc_pgp [color="#2980b9", penwidth=2]; pgz -> pvc_pgz [color="#2980b9", penwidth=2]; rmq -> pvc_rmq [color="#2980b9", penwidth=2]; /* RWX PVCs → share-manager */ pvc_sites -> sm_sites [color="#e67e22", penwidth=2, style=dashed, label="NFS"]; pvc_logs -> sm_logs [color="#e67e22", penwidth=2, style=dashed, label="NFS"]; /* share-manager → Replica B */ sm_sites -> rep_b [color="#e67e22", penwidth=2]; sm_logs -> rep_b [color="#e67e22", penwidth=2]; /* RWO PVCs → beide Replicas (Longhorn CSI) */ pvc_mdb -> rep_a [color="#27ae60", penwidth=2, label="Longhorn CSI"]; pvc_mdb -> rep_b [color="#27ae60", penwidth=2]; pvc_ppl -> rep_a [color="#27ae60", penwidth=2]; pvc_ppl -> rep_b [color="#27ae60", penwidth=2]; pvc_pgp -> rep_a [color="#27ae60", penwidth=2]; pvc_pgp -> rep_b [color="#27ae60", penwidth=2]; pvc_pgz -> rep_a [color="#27ae60", penwidth=2]; pvc_pgz -> rep_b [color="#27ae60", penwidth=2]; pvc_rmq -> rep_a [color="#27ae60", penwidth=2]; pvc_rmq -> rep_b [color="#27ae60", penwidth=2]; /* Sync zwischen Replicas */ rep_a -> rep_b [color="#27ae60", penwidth=2.5, style=bold, label="sync\n(synchron)"]; /* CSI → Volumes */ csi -> rep_a [color="#95a5a6", style=dotted, label="provision"]; /* Replicas → K3s Worker Nodes */ rep_a -> node1 [color="#27ae60", penwidth=2, label="physisch auf"]; rep_b -> node2 [color="#27ae60", penwidth=2, label="physisch auf"]; /* Control-Plane → Workers */ kubadm -> node1 [color="#7f8c8d", style=dashed, label="API"]; kubadm -> node2 [color="#7f8c8d", style=dashed]; /* K3s Nodes → Proxmox Hosts */ kubadm -> pn01 [color="#e74c3c", penwidth=3, label="VM auf n01"]; node2 -> pn01 [color="#e67e22", penwidth=2.5, label="VM auf n01"]; node1 -> pn02 [color="#27ae60", penwidth=2, label="VM auf n02"]; /* Proxmox → Disk */ pn01 -> disk_n01 [color="#95a5a6"]; pn02 -> disk_n02 [color="#95a5a6"]; /* Backup */ disk_n01 -> disk_n02 [color="#95a5a6", style=dashed, label="daily-backup CronJob\n(Longhorn, auf efsckubnode02)"]; /* ───────────────────────────────────────────── RANK CONSTRAINTS – Spalten erzwingen (newrank=true erlaubt cross-cluster) ───────────────────────────────────────────── */ subgraph rank_apps { rank=same; gui; nginx; mdb; ppl; pgp; pgz; rmq; } subgraph rank_pvcs { rank=same; pvc_mdb; pvc_sites; pvc_logs; pvc_ppl; pvc_pgp; pvc_pgz; pvc_rmq; } subgraph rank_lh { rank=same; sm_sites; sm_logs; rep_a; rep_b; csi; } subgraph rank_nodes { rank=same; kubadm; node1; node2; } subgraph rank_prox { rank=same; pn01; disk_n01; pn02; disk_n02; } }