Initial commit: Infrastructure documentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-03 13:46:47 +02:00
commit bbe86c55d9
9 changed files with 568 additions and 0 deletions

BIN
diagrams/k8s_cluster.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

View File

@@ -0,0 +1,97 @@
from diagrams import Cluster, Diagram, Edge
from diagrams.k8s.network import Ingress
from diagrams.k8s.compute import Deployment, StatefulSet
from diagrams.k8s.storage import PVC, StorageClass
from diagrams.onprem.network import Opnsense
from diagrams.onprem.certificates import CertManager
from diagrams.onprem.proxmox import ProxmoxVE
from diagrams.onprem.vcs import Gitea
from diagrams.generic.os import Windows
graph_attr = {
"fontsize": "13",
"pad": "0.6",
"nodesep": "0.5",
"ranksep": "1.0",
"splines": "ortho",
}
with Diagram(
"ExpertFab Infrastruktur",
filename="k8s_cluster",
outformat="png",
show=False,
direction="TB",
graph_attr=graph_attr,
):
# ── Physische Ebene ───────────────────────────────────────────────────────
with Cluster("Proxmox Cluster efproxcl02 95.156.232.42"):
with Cluster("efproxcl02n01 64 vCPU / 128 GB"):
fw = Opnsense("efscfw01\nOPNsense / FW\n10.42.70.1")
n01_kctl = ProxmoxVE("efsckubctl\nK3s control plane")
n01_kn02 = ProxmoxVE("efsckubnode02\nK3s worker")
n01_smtp = ProxmoxVE("efsmtprelay")
n01_trade = ProxmoxVE("eftrade01")
n01_git = Gitea("efgit01 / Gitea\ngit.expertfab.de")
with Cluster("efproxcl02n02 64 vCPU / 128 GB"):
n02_kn1 = ProxmoxVE("efsckubnode1\nK3s worker")
n02_af = ProxmoxVE("efscairflow01\nAirflow")
n02_veeam = ProxmoxVE("efscveeam01\nVeeam Backup")
n02_dc = Windows("efscdc01\nDomain Controller")
n02_print = ProxmoxVE("efscprint01\nPrintserver")
n02_moni = ProxmoxVE("efscmoni01\nMonitoring")
# ── Logische K3s-Ebene ────────────────────────────────────────────────────
# K3s läuft auf: efsckubctl (control) + efsckubnode1 + efsckubnode02
with Cluster("K3s Cluster (efsckubctl · efsckubnode1 · efsckubnode02)"):
cert = CertManager("cert-manager\nLet's Encrypt")
traefik = Ingress("Traefik Ingress\n10.42.71.60")
cert >> traefik
with Cluster("erpnext expertfab.de / www.expertfab.de"):
nginx = Deployment("Nginx")
gunicorn = Deployment("Gunicorn")
workers = Deployment("Workers\ndefault / short / long")
mariadb = StatefulSet("MariaDB 10.6")
df_cache = Deployment("DragonflyDB\ncache")
df_queue = Deployment("DragonflyDB\nqueue")
nginx >> gunicorn >> workers
[gunicorn, workers] >> mariadb
[gunicorn, workers] >> df_cache
workers >> df_queue
with Cluster("paperless docs.expertfab.de"):
paperless = Deployment("Paperless-NGX")
with Cluster("zitadel auth.expertfab.de"):
zitadel = Deployment("Zitadel")
with Cluster("rabbitmq api.expertfab.de"):
fastapi = Deployment("FastAPI")
with Cluster("coworkbase coworkbase.de"):
cowork = Deployment("Coworkbase")
with Cluster("qubicticker qubicticker.qchief.io"):
ticker = Deployment("Qubicticker")
traefik >> [nginx, paperless, zitadel, fastapi, cowork, ticker]
with Cluster("Longhorn Storage"):
sc = StorageClass("longhorn")
pvc_mariadb = PVC("MariaDB 10 Gi RWO")
pvc_sites = PVC("Sites 10 Gi RWX")
pvc_logs = PVC("Logs 5 Gi RWX")
pvc_queue = PVC("Queue 2 Gi RWO")
sc >> [pvc_mariadb, pvc_sites, pvc_logs, pvc_queue]
mariadb >> Edge(style="dashed") >> pvc_mariadb
gunicorn >> Edge(style="dashed") >> pvc_sites
nginx >> Edge(style="dashed") >> pvc_logs
df_queue >> Edge(style="dashed") >> pvc_queue
# ── Verbindungen ──────────────────────────────────────────────────────────
fw >> traefik
n01_git >> Edge(label="image pull", style="dashed") >> nginx

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@@ -0,0 +1,82 @@
from diagrams import Cluster, Diagram, Edge
from diagrams.k8s.compute import Deployment, StatefulSet, Pod, DaemonSet, Job
from diagrams.k8s.storage import PVC, StorageClass
from diagrams.generic.storage import Storage
graph_attr = {
"fontsize": "13",
"pad": "0.8",
"nodesep": "0.6",
"ranksep": "1.2",
}
with Diagram(
"ExpertFab Longhorn Storage Architektur",
filename="storage_architecture",
outformat="png",
show=False,
direction="TB",
graph_attr=graph_attr,
):
# ── Longhorn System Pods pro Node ─────────────────────────────────────────
with Cluster("K3s Worker Nodes (Longhorn System Pods)"):
with Cluster("efsckubnode1 (4 vCPU / 8 GB)"):
n1_mgr = Pod("longhorn-manager")
n1_csi = Pod("longhorn-csi-plugin")
n1_eng = Pod("engine-image")
n1_inst = Pod("instance-manager")
n1_driver = Deployment("driver-deployer")
n1_ui = Deployment("longhorn-ui (2×)")
n1_attacher = Deployment("csi-attacher (3×)")
n1_prov = Deployment("csi-provisioner (3×)")
n1_resizer = Deployment("csi-resizer (3×)")
n1_snap = Deployment("csi-snapshotter (3×)")
with Cluster("efsckubnode2 (4 vCPU / 8 GB)"):
n2_mgr = Pod("longhorn-manager")
n2_csi = Pod("longhorn-csi-plugin")
n2_eng = Pod("engine-image")
n2_inst = Pod("instance-manager")
n2_smgr1 = Pod("share-manager\n(erpnext RWX)")
n2_smgr2 = Pod("share-manager\n(erpnext-logs RWX)")
n2_backup = Job("daily-backup\n(CronJob)")
# ── StorageClasses ────────────────────────────────────────────────────────
with Cluster("StorageClasses (driver.longhorn.io)"):
sc_erpnext = StorageClass("longhorn-erpnext\nRetain / Immediate")
sc_paperless = StorageClass("longhorn-paperless\nRetain / Immediate")
sc_default = StorageClass("longhorn\nDelete / Immediate")
# ── PVCs pro Namespace ────────────────────────────────────────────────────
with Cluster("PVCs"):
with Cluster("namespace: erpnext"):
pvc_mariadb = PVC("data-erpnext-mariadb-sts-0\n3 Gi RWO")
pvc_sites = PVC("erpnext\n3 Gi RWX")
pvc_logs = PVC("erpnext-logs\n1 Gi RWX")
with Cluster("namespace: paperless"):
pvc_pl_media = PVC("paperless-media\n10 Gi RWO")
pvc_pl_consume = PVC("paperless-consume\n5 Gi RWO")
pvc_pl_data = PVC("paperless-data\n5 Gi RWO")
pvc_pl_pg = PVC("postgres-data\n5 Gi RWO")
with Cluster("namespace: rabbitmq"):
pvc_rmq = PVC("rabbitmq-data-rabbitmq-0\n5 Gi RWO")
with Cluster("namespace: zitadel"):
pvc_zit_pg = PVC("postgres-data-postgres-0\n10 Gi RWO")
# ── StorageClass → PVC ────────────────────────────────────────────────────
sc_erpnext >> [pvc_mariadb, pvc_sites, pvc_logs]
sc_paperless >> [pvc_pl_media, pvc_pl_consume, pvc_pl_data, pvc_pl_pg]
sc_default >> [pvc_rmq, pvc_zit_pg]
# ── Share-Manager bedient die RWX-Volumes ─────────────────────────────────
n2_smgr1 >> Edge(label="serves", style="dashed") >> pvc_sites
n2_smgr2 >> Edge(label="serves", style="dashed") >> pvc_logs
# ── Longhorn Manager koordiniert über beide Nodes ─────────────────────────
n1_mgr >> Edge(style="dotted", color="gray") >> n2_mgr