Add reproducible Docker and WireGuard host bootstrap
This commit is contained in:
+67
-92
@@ -1,107 +1,82 @@
|
||||
# Architektur
|
||||
# Zielarchitektur des neuen KI-Hosts
|
||||
|
||||
## Ziel
|
||||
## Grundsatz
|
||||
|
||||
Die Plattform stellt eine private, lokal betriebene OpenAI-kompatible API
|
||||
bereit. Jede Komponente hat genau eine Aufgabe und kann unabhängig ersetzt
|
||||
werden. Ein Neuaufbau darf keine Dateien vom alten Host voraussetzen, die nicht
|
||||
in diesem Repository oder im Modellmanifest beschrieben sind.
|
||||
Der Host läuft auf Debian 13. Das Betriebssystem darf im Universitätsnetz
|
||||
administrierbar bleiben; die KI-Plattform wird ausschließlich an die
|
||||
WireGuard-Adresse gebunden. KI-Container erreichen Heimnetz und Internet über
|
||||
den Heim-WireGuard-Peer. Bei Tunnelausfall verhindert eine Blackhole-Route den
|
||||
unbeabsichtigten Rückfall auf das Universitätsgateway.
|
||||
|
||||
## Komponenten
|
||||
```text
|
||||
Heimnetz / VPN-Clients
|
||||
|
|
||||
WireGuard
|
||||
|
|
||||
10.77.0.2:8080 Open WebUI
|
||||
10.77.0.2:8081 Profile Router API
|
||||
|
|
||||
Docker-intern
|
||||
+-- Profile Controller -- Docker Socket (feste Allowlist)
|
||||
+-- llama-fast --\
|
||||
+-- llama-medium > exakt einer aktiv
|
||||
+-- llama-long --/
|
||||
+-- llama-experimental
|
||||
+-- SearXNG + Web-MCP
|
||||
```
|
||||
|
||||
| Komponente | Port | Ausführung | Aufgabe |
|
||||
|---|---:|---|---|
|
||||
| AI Profile Router | 8081 | systemd, gehärtet | zentrale Client-API und Orchestrierung |
|
||||
| llama.cpp | 8080 | systemd | Textmodell, Tool Calling und MCP |
|
||||
| Whisper | 8084, nur localhost | systemd | Speech-to-Text |
|
||||
| XTTS | 8085, nur localhost | systemd | Text-to-Speech |
|
||||
| TinySearch | 8000, nur localhost | Docker | kompakte Websuche |
|
||||
| SearXNG | intern | Docker | Suchmaschinen-Metasuche |
|
||||
| LLama-GUI | 5240, optional | systemd | manuelle Administration |
|
||||
| Glances | lokal, optional | systemd | Systemmetriken |
|
||||
## Container und Vertrauensgrenzen
|
||||
|
||||
## Request-Fluss
|
||||
| Komponente | Außen erreichbar | Aufgabe |
|
||||
|---|---|---|
|
||||
| Open WebUI | nur WireGuard, Port 8080 | Chat-Oberfläche |
|
||||
| Profile Router | nur WireGuard, Port 8081 | OpenAI-API und Profilwahl |
|
||||
| Profile Controller | nein | startet ausschließlich vier bekannte Profile |
|
||||
| llama.cpp Profile | nein | Inferenz, Tool Calling, integrierte Vision |
|
||||
| SearXNG | nein | Websuche für den lokalen Web-MCP |
|
||||
|
||||
1. Ein Client verwendet ausschließlich Port 8081.
|
||||
2. Der Router veröffentlicht `qwen-fast`, `qwen-medium` und `qwen-long`.
|
||||
3. Passt das aktive Profil nicht zum virtuellen Modell, wird llama.cpp kontrolliert
|
||||
mit dem passenden Profil neu gestartet.
|
||||
4. Der Router wartet auf Modellname und erwartete Kontextgröße.
|
||||
5. Erst dann wird die Anfrage an Port 8080 weitergeleitet.
|
||||
|
||||
Profilwahl und Weiterleitung bilden dabei eine atomare Modell-Lease. Ein
|
||||
zweiter Request kann das Profil nicht mehr zwischen Auswahl und Inferenz
|
||||
wechseln. Laufende Requests werden vor einem GPU-Hotswap vollständig beendet;
|
||||
bei Überschreiten des Drain-Timeouts wird der Wechsel abgebrochen, nicht der
|
||||
Chat.
|
||||
Nur der Profile Controller erhält den Docker-Socket. Der Router erhält weder
|
||||
Socket noch Shell-Zugriff und kann dem Controller nur `fast`, `medium`, `long`
|
||||
oder `experimental` übergeben. Die llama-Container laufen ohne UI,
|
||||
Capabilities und Schreibzugriff auf die Modelldateien.
|
||||
|
||||
## Profilprinzip
|
||||
|
||||
Die Profile sind vollständige systemd-Overrides. Ein Profilwechsel kopiert die
|
||||
gewählte Datei atomar auf `override.conf`, lädt systemd neu und startet genau
|
||||
einen llama.cpp-Dienst neu. Es gibt niemals mehrere Textmodelle gleichzeitig.
|
||||
Das unabhängige Register `/etc/mike-ai/router-profiles.json` definiert Kontext
|
||||
und erwarteten Modellalias. Readiness gilt nur, wenn beides exakt passt; eine
|
||||
abweichende oder fehlende Registry verhindert den Start.
|
||||
Alle Profile verwenden dasselbe selbst gebaute llama.cpp-Image. Separate,
|
||||
normalerweise gestoppte Containerdefinitionen halten Parameter wie Kontext,
|
||||
MTP und CPU-Offload reproduzierbar. Ein Wechsel stoppt das alte Profil und
|
||||
startet genau einen bereits angelegten Container. Dadurch lassen sich Profile
|
||||
einzeln verändern oder duplizieren, ohne vier Modelle parallel im VRAM zu
|
||||
halten.
|
||||
|
||||
## GPU-Hotswap
|
||||
| Profil | Ausgangswert | Zweck |
|
||||
|---|---:|---|
|
||||
| fast | 76.800 Kontext, MTP | mindestens ungefähr 80 Token/s anstreben |
|
||||
| medium | 94.208 Kontext | mehr Kontext ohne CPU-FFN-Offload |
|
||||
| long | 131.072 Kontext | maximale Nutzbarkeit, CPU-Offload erlaubt |
|
||||
| experimental | 76.800 Kontext | isolierte Tests ohne Produktion zu ändern |
|
||||
|
||||
Vision und Bildgenerierung teilen sich die RTX mit dem Textmodell. Der Router:
|
||||
Diese Werte sind reproduzierbare Startwerte, keine Garantie. Nach Einbau der
|
||||
RTX 3060 werden sie auf dem Zielhost erneut gemessen. Die zweite Karte wird
|
||||
nicht automatisch in die Produktionsprofile aufgenommen.
|
||||
|
||||
1. sperrt die GPU-Orchestrierung,
|
||||
2. merkt sich das aktive Textprofil,
|
||||
3. stoppt llama.cpp,
|
||||
4. startet vorübergehend Vision oder FLUX,
|
||||
5. beendet den Hilfsprozess vollständig,
|
||||
6. stellt das ursprüngliche Textprofil wieder her,
|
||||
7. prüft Modell und Kontext vor der Freigabe.
|
||||
## Netzwerk
|
||||
|
||||
Der zuletzt stabile Zustand und temporäre Worker-PIDs werden atomar unter
|
||||
`/var/lib/mike-ai-profile-router/state.json` festgehalten. Beim Routerstart
|
||||
werden ausschließlich dort erfasste Prozesse nach zusätzlicher
|
||||
Kommandozeilenprüfung beendet und das letzte Profil wiederhergestellt.
|
||||
- Docker-Netze liegen ausschließlich unter `172.30.0.0/16`.
|
||||
- Open WebUI und Router binden an `AI_BIND_ADDRESS`, die WireGuard-IP.
|
||||
- Quellrouting schickt KI-Container in Tabelle 51820 über WireGuard.
|
||||
- Eine Blackhole-Default-Route bleibt als Fail-Closed-Fallback bestehen.
|
||||
- Firewallregeln gestatten aus dem VPN nur die beiden veröffentlichten Ports.
|
||||
- Der Host routet weder Universitätsverkehr ins Heimnetz noch Heimverkehr ins
|
||||
Universitätsnetz.
|
||||
- Das Heimnetz muss die Rückroute zur WireGuard-Adresse kennen. Soll auch der
|
||||
Internetzugang der KI über zuhause laufen, braucht der Heim-Peer zusätzlich
|
||||
IP-Forwarding und NAT ins Heim-WAN.
|
||||
|
||||
## Vertrauensgrenzen
|
||||
## Nicht automatisch installiert
|
||||
|
||||
- Port 8081 verlangt einen eigenen API-Key; nur `/health` und `/ready` sind
|
||||
absichtlich anonym und enthalten keine privaten Daten.
|
||||
- Der Client-Key wird vor dem lokalen Upstream entfernt.
|
||||
- Bild-Uploads sind begrenzt. Remote-Bild-URLs sind standardmäßig aus, damit
|
||||
der Vision-Pfad nicht als Zugriff auf Intranet oder Metadatenendpunkte dient.
|
||||
- Maximal 16 Requests werden gleichzeitig bearbeitet; weitere erhalten 429.
|
||||
- Der Dienst benötigt derzeit wegen systemd-Profilwechsel und GPU-Hotswap noch
|
||||
Root-Rechte. Die systemd-Sandbox begrenzt diese, ersetzt aber keine künftige
|
||||
Aufteilung in unprivilegierten Proxy und eng begrenzten Root-Helper.
|
||||
|
||||
## Verzeichnislayout auf dem Zielhost
|
||||
|
||||
```text
|
||||
/opt/mike-ai/
|
||||
ai-profile-router/ Routercode und eigenes Venv
|
||||
llama.cpp/ exakt ein produktiver Build
|
||||
models/ Modelle nach Manifest
|
||||
whisper.cpp/ Speech-to-Text Runtime
|
||||
xtts/ XTTS Runtime und Cache
|
||||
web-search/ Docker Compose für TinySearch/SearXNG
|
||||
|
||||
/etc/mike-ai/
|
||||
mcp-servers.json lokale, geheime produktive Konfiguration
|
||||
*.env Credentials, niemals im Git
|
||||
|
||||
/etc/systemd/system/
|
||||
mike-ai-*.service
|
||||
mike-ai-llama-ui.service.d/
|
||||
override.conf
|
||||
profile-fast.conf.disabled
|
||||
profile-medium.conf.disabled
|
||||
profile-long.conf.disabled
|
||||
```
|
||||
|
||||
## Nicht Teil der Zielarchitektur
|
||||
|
||||
- parallele llama.cpp-Builds
|
||||
- allgemeiner Shell-MCP im Standardprofil
|
||||
- doppelte Unraid-MCPs
|
||||
- RX-spezifische Dienste ohne eingebaute RX
|
||||
- automatisch startende Benchmark-Dienste
|
||||
- Modellkopien außerhalb des dokumentierten Modellverzeichnisses
|
||||
Bildgenerierung, Whisper, TTS sowie Home-Assistant-, ARR- und Unraid-MCPs sind
|
||||
Erweiterungen. Sie benötigen eigene Modelle, Rechte oder Secrets und bleiben
|
||||
im sauberen Basissystem deaktiviert. Multimodale Bildanalyse erfolgt direkt
|
||||
über Qwen plus Projektor. Nicht installierte Worker-Endpunkte antworten klar
|
||||
mit `feature_disabled`, statt alte systemd-Pfade aufzurufen.
|
||||
|
||||
Reference in New Issue
Block a user