GNAI007: Render- und GPU-Rechte den beiden KI-Konten hinzugefügt.

This commit is contained in:
2026-09-20 22:38:44 +02:00
parent bf7431d672
commit 2f2dbc3252
12 changed files with 399 additions and 21 deletions
+11
View File
@@ -61,6 +61,8 @@ Die Rolle `podman_runtime` wurde am 20.09.2026 angewendet. Sie installierte Podm
Die Rolle `workload_accounts` richtete am 20.09.2026 die gesperrten Konten `gnai-production` (UID/GID 980), `gnai-testing` (981) und `gn-encoding` (982) mit festen, getrennten SubID-Bereichen ein. Konfiguration bleibt rootverwaltet; Daten, rootless Podman-Stores und persistente systemd-User-Manager sind pro Workload getrennt. Der korrigierte Gesamtlauf meldete `ok=36 changed=0 unreachable=0 failed=0` und bestätigte drei unterschiedliche rootless Graph Roots. Images und Container wurden nicht angelegt.
Die Rolle `amd_gpu_access` bestätigte am 20.09.2026 zwei Sapphire-Navi-21-Geräte `1002:73bf` mit dem Kernel-Treiber `amdgpu`, `/dev/kfd` sowie die zugehörigen Render-Nodes `/dev/dri/renderD128` und `/dev/dri/renderD129`. Alle drei Geräte verwenden die Gruppe `render`. `gnai-production` und `gnai-testing` besitzen nachweislich Lese-/Schreibzugriff; `gn-encoding` erhielt keine GPU-Gruppe. Nach Beseitigung einer konkurrierenden Gruppenverwaltung endete der Gesamtlauf mit `ok=55 changed=0 unreachable=0 failed=0`. ROCm im Container und tatsächliche Inferenz sind damit noch nicht nachgewiesen.
## 3. Sicherheitsbefunde mit Priorität
| Befund | dokumentiertes Verfahren / Status |
@@ -105,4 +107,13 @@ rootseitiges `runuser` und eindeutiger Eigentümerzuständigkeit endete der
Gesamtlauf mit `ok=36 changed=0 unreachable=0 failed=0`. Die drei rootless
Podman-Stores sind voneinander getrennt und noch leer.
Der folgende GPU-Zugriffslauf ordnete beide erkannten AMD-Render-Nodes anhand
von PCI-Vendor und Geräte-ID den Navi-21-Karten zu und leitete aus ihnen sowie
`/dev/kfd` ausschließlich die Gruppe `render` ab. Der erste Wiederholungslauf
deckte auf, dass `workload_accounts` ergänzende Gruppen wieder entfernte. Nach
Übernahme von `render` in den expliziten Kontosollzustand blieb
`amd_gpu_access` für Hardwareerkennung und effektive Rechteprüfung zuständig.
Der Abschlusslauf war mit `changed=0` idempotent; Images und Container blieben
weiterhin leer.
Die WireGuard-Evidenz bleibt der Teiltest vom 12.09.2026: CachyOS-Laptop von WAN, Handshake, Ping auf Gateway/Proxmox und direkter IPv4-Internetpfad bestanden; KI-Server war ausgeschaltet. Neue Rollen, weitere Clientvarianten, Gateway-GUI-Zugriff, WAN-/IPv6-Isolation, Neustart und Restore sind noch nicht abgenommen. GNAI-006 ist erst nach Klärung der offenen Werte, Umsetzung und dokumentierter Abnahme technisch abgeschlossen.
+100 -8
View File
@@ -28,6 +28,8 @@
| 2026-09-19 | 0.7 | spektr / Codex | minimale gemeinsame Host-Baseline mit Schutzprüfungen und getrennten Verzeichniswurzeln implementiert, angewendet und auf Idempotenz geprüft |
| 2026-09-20 | 0.8 | spektr / Codex | gemeinsame Podman-/Quadlet-Runtime implementiert, installiert und ohne Images oder Container verifiziert |
| 2026-09-20 | 0.9 | spektr / Codex | getrennte rootless Konten für AI Production, AI Testing und CPU-Encoding eingerichtet; Parallelitäts- und Repository-Grenzen ergänzt |
| 2026-09-20 | 0.10 | spektr / Codex | ROCm als Backend für zwei RX 6900 XT, initialen `llama.cpp`-Modellstand und Layer-Split mit gleicher GPU-Gewichtung festgehalten |
| 2026-09-20 | 0.11 | spektr / Codex | AMD-Gerätezugriff für beide rootless KI-Konten implementiert, angewendet und idempotent geprüft |
---
@@ -378,6 +380,75 @@ rootverwaltet und für die jeweilige Gruppe lesbar. Der Encoding-Workload
verwendet entsprechend `/etc/ghostnet-encoding` und
`/var/lib/ghostnet-encoding`.
### 7.5 ROCm- und `llama.cpp`-Ausgangskonfiguration
Der Betreiber hat zwei Sapphire Nitro+ Radeon RX 6900 XT mit jeweils 16 GiB
VRAM als Zielhardware bestätigt. Für diesen homogenen AMD-Aufbau wird ROCm als
Backend verwendet. Vulkan bleibt eine mögliche spätere Alternative, falls der
Server um GPUs mit unterschiedlichen Backend-Anforderungen erweitert wird.
Als Ausgangspunkt dient eine bereits auf einer RX 7900 XTX verwendete
Podman-Compose-Konfiguration. Die Serverumsetzung wird daraus mit folgenden
Abweichungen als rootless Quadlet erzeugt:
- das Image `ghcr.io/ggml-org/llama.cpp:server-rocm` wird auf eine geprüfte
Version und den zugehörigen Digest festgelegt;
- `/dev/kfd` und die tatsächlich benötigten `/dev/dri`-Geräte werden explizit
eingebunden; `GroupAdd=keep-groups` erhält die nötigen ergänzenden
Geräte-Gruppen im rootless Container;
- das gemeinsame Modellverzeichnis wird nur lesbar unter `/models`
eingebunden;
- `llama-server` erhält keinen Host-Port und ist ausschließlich für LiteLLM im
umgebungseigenen Podman-Netz erreichbar;
- systemd übernimmt Start, Neustart, Abhängigkeiten und Health-Überwachung;
- Modell- und Laufzeitwerte werden als Ansible-Variablen in die
Quadlet-Kommandozeile gerendert. Zusätzliche Container-Environment-Variablen
werden nur verwendet, wenn das Backend sie technisch benötigt;
- `HSA_OVERRIDE_GFX_VERSION=11.0.0` aus der RX-7900-XTX-Konfiguration wird
nicht übernommen. Die RX 6900 XT verwendet nativ `gfx1030`, das im
vorgesehenen ROCm-Image enthalten sein muss. Ein Override wäre nur nach
einem fehlgeschlagenen Geräte-/Backendtest zulässig und müsste für RDNA2
gesondert begründet werden;
- `label=disable` wird nur übernommen, falls eine tatsächlich aktive
SELinux-Konfiguration dies erfordert. Für den dokumentierten Debian-Host
wird es nicht vorsorglich gesetzt.
Der erste Testing-Modellstand verwendet vorbehaltlich Artefakt- und
Checksum-Prüfung:
| Parameter | Ausgangswert |
| --- | --- |
| Modelldatei | `Qwen3.8-27B-UD-IQ4_XS.gguf` |
| API-Alias | `qwen3.8-27b` |
| Kontext | 51.200 Token |
| parallele Slots | 1 |
| maximale Ausgabe | 4.096 Token |
| GPU-Layer | alle |
| Flash Attention | aktiviert |
| K-/V-KV-Cache | jeweils `q8_0` |
| Reasoning Effort | `medium` |
Samplingwerte und Chat-Template-Parameter gehören zum Modellprofil und nicht
zu allgemeinen Rollendefaults. Dadurch können andere Modelle später eigene
geprüfte Profile verwenden, ohne die gemeinsame `llama_cpp`-Rolle zu ändern.
Für die beiden gleich großen GPUs wird zunächst
`--split-mode layer --tensor-split 1,1` festgelegt. Der Layer-Split minimiert
GPU-übergreifende Kommunikation und passt damit zur dokumentierten
PCIe-Topologie, bei der die zweite Karte über einen langsameren, am PCH
angebundenen Slot läuft. `row` wird wegen seiner Ablösung im aktuellen
`llama.cpp` nicht als neue Betriebsvariante vorgesehen. Der experimentelle
`tensor`-Split bleibt ein späterer Benchmarkkandidat; er benötigt deutlich
mehr Kommunikation zwischen den Karten und ist mit dem geplanten
quantisierten V-KV-Cache derzeit nicht kompatibel.
Vor dem dauerhaften Start muss ein begrenzter Test `gfx1030`, beide GPUs,
Device-Reihenfolge, verfügbaren VRAM und die tatsächliche 1:1-Verteilung in
den `llama.cpp`-Startlogs bestätigen. Zusätzlich werden Prompt-Verarbeitung,
Token-Generierung, VRAM-Nutzung und Stabilität bei 51.200 Token Kontext
gemessen. Der 1:1-Wert ist erst nach diesem Test ein abgenommener
Betriebsparameter.
---
## 8. Vorgesehener Workflow
@@ -555,7 +626,8 @@ nicht als Nachweis einer erfolgreichen Einrichtung.
- Podman- und Quadlet-Grundruntime sowie getrennte rootless Workload-Konten
eingerichtet und geprüft;
- AMD-GPU-/ROCm- oder alternative Laufzeit nach technischer Prüfung;
- rootless Host-Gerätezugriff auf beide RX 6900 XT eingerichtet und geprüft;
- ROCm-Funktion im rootless Container prüfen;
- `llama.cpp` und lokaler Funktionstest;
- Wiederanlauf nach geplantem Reboot prüfen.
@@ -635,6 +707,8 @@ Herstellerdokumentationen herangezogen:
- [Ansible Vault](https://docs.ansible.com/projects/ansible/latest/vault_guide/vault.html)
- [Debian 13 – Paket `podman`](https://packages.debian.org/trixie/podman)
- [Podman – Quadlet und systemd](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html)
- [llama.cpp – Multi-GPU](https://github.com/ggml-org/llama.cpp/blob/master/docs/multi-gpu.md)
- [llama.cpp – ROCm-Container](https://github.com/ggml-org/llama.cpp/blob/master/.devops/rocm.Dockerfile)
Vor der Implementierung sind versionsspezifische Aussagen gegen die dann
tatsächlich eingesetzten Gitea-, Runner- und Ansible-Versionen zu prüfen.
@@ -753,25 +827,43 @@ die umgebungsspezifischen Pfade wurden daraufhin vollständig an
systemd-User-Manager sowie drei getrennte rootless Podman Graph Roots. Es
wurden keine Images oder Workload-Container angelegt.
Anschließend wurde `amd_gpu_access` in das gemeinsame Host-Playbook
aufgenommen. Die Rolle verlangt genau zwei Geräte `1002:73bf` mit `amdgpu`,
ordnet über sysfs ausschließlich deren Render-Nodes zu, prüft `/dev/kfd` und
leitet die minimal erforderlichen Gerätegruppen aus dem Istzustand ab. Auf dem
Host sind dies `/dev/kfd`, `/dev/dri/renderD128` und
`/dev/dri/renderD129`, jeweils mit Gruppe `render`.
Der Check-Modus prognostizierte nur die ergänzende Gruppenmitgliedschaft für
`gnai-production` und `gnai-testing`. Der reale Lauf bestätigte danach für
beide Konten Lese- und Schreibzugriff auf alle drei Geräte. Ein erster
Wiederholungslauf deckte auf, dass `workload_accounts` die Gruppe zunächst
entfernte und `amd_gpu_access` sie wieder hinzufügte. `render` wurde deshalb in
den expliziten Sollzustand der beiden KI-Konten übernommen; das Encoding-Konto
bleibt ohne GPU-Gruppe. Der korrigierte Gesamtlauf endete mit
`ok=55 changed=0 unreachable=0 failed=0`. Weder ein ROCm-Image noch ein
Container oder eine Inferenz wurden dabei ausgeführt.
---
## 15. Abschlussgrenze dieses Entwurfs
Mit Version 0.9 sind der aktuelle Planungsstand, der ausdrücklich begrenzte
Mit Version 0.11 sind der aktuelle Planungsstand, der ausdrücklich begrenzte
Ansible-Preflight, der verifizierte Deployment-Account und die angewendete
minimale Host-Baseline, die Podman-/Quadlet-Grundruntime und die getrennten
Workload-Konten persistiert.
Workload-Konten sowie deren begrenzter AMD-Gerätezugriff persistiert.
Insbesondere wurden noch nicht:
- ein Gitea Runner angelegt,
- Gitea Actions oder Schutzregeln konfiguriert,
- GPU- oder Anwendungsrollen, ein Production-Inventar oder ein Vault erstellt,
- eine ROCm-Container- oder Anwendungsrolle, ein Production-Inventar oder ein
Vault erstellt,
- eine Production- oder Testing-Umgebung eingerichtet oder voneinander
abgenommen,
- GPU-Komponenten oder Anwendungen auf dem KI-Server installiert,
- ROCm-Userspace, GPU-Container oder Anwendungen auf dem KI-Server installiert,
- Backups oder Rollbacks praktisch getestet oder
- die geplante Deploymentkette technisch abgenommen.
Die nächsten technischen Schritte sind der begrenzte GPU-Zugriffstest für die
beiden KI-Konten und die Festlegung von Zeitfenster sowie Ressourcenlimits im
getrennten Encoding-Plan. Darauf bauen die jeweiligen Fachrollen und SOPs auf.
Der nächste technische Schritt ist ein begrenzter rootless ROCm-Container-Test
für beide KI-Konten, der beide Karten als `gfx1030` erkennen muss. Darauf bauen
die `llama.cpp`-Rolle, das initiale Testing-Modellprofil und später LiteLLM auf.
+4 -1
View File
@@ -16,6 +16,7 @@
| 2026-09-18 | 1.3 | spektr | Workstation-spezifische Schlüsselpfade und Host-Fingerprint in den lokalen Arbeitskontext verlagert. |
| 2026-09-19 | 1.4 | spektr | Persönlichen Login `ghost` und Agentenlogin `ghost-agent` als erfolgreich getestet dokumentiert. |
| 2026-09-20 | 1.5 | spektr / Codex | Deployment- und getrennte rootless Workload-Konten mit festen IDs und Zuständigkeiten ergänzt. |
| 2026-09-20 | 1.6 | spektr / Codex | `render`-Mitgliedschaft und geprüfte AMD-Geräterechte der beiden KI-Konten ergänzt. |
---
@@ -74,7 +75,8 @@ Die drei Workload-Konten besitzen nicht überlappende SubUID-/SubGID-Bereiche,
eigene Daten- und Podman-Stores sowie persistente systemd-User-Manager. Ihre
rootverwalteten Quadlet-Verzeichnisse liegen unter
`/etc/containers/systemd/users/<UID>`. Direkte SSH-Schlüssel werden dort nicht
hinterlegt.
hinterlegt. `gnai-production` und `gnai-testing` gehören zusätzlich zur
Gerätegruppe `render`; `gn-encoding` erhält keinen GPU-Zugriff.
---
@@ -188,6 +190,7 @@ sudo systemctl restart ssh
* [ ] **Benutzerprüfung:** `ghost` und `debugofen` können ihre vorgesehenen sudo-Rechte nutzen; `ghost-agent` bleibt ohne sudo-Zuweisung.
* [x] **Workload-Konten:** `gnai-production`, `gnai-testing` und `gn-encoding` besitzen getrennte rootless Podman-Stores und aktive persistente User-Manager; geprüft am 20.09.2026.
* [x] **GPU-Geräterechte:** Beide KI-Konten können `/dev/kfd`, `/dev/dri/renderD128` und `/dev/dri/renderD129` lesen und schreiben; das Encoding-Konto gehört nicht zu `render`; geprüft am 20.09.2026.
* [ ] **Netzwerk:** Server ist unter der statischen IP `10.0.0.90` erreichbar. Ausgehender Datenverkehr funktioniert (`ping google.com`).
* [x] **SSH-Aliase:** `ghostnet-ai-ghost` meldet `ghost`, `ghostnet-ai-agent` meldet `ghost-agent`. Beide Zugänge wurden am 19.09.2026 bestätigt. Die Passphrase des persönlichen Schlüssels ist keine Server-Passwortanmeldung.
* [ ] **Root-Sperre:** Direct-Login als Root per SSH wird abgelehnt (`ssh root@10.0.0.90` -> *Permission denied*).