Kein NVIDIA Broadcast für Linux? Na und?

Dann müssen wir da eben selbst was bauen …

Wer schon mal einen Streamer mit sauberem Webcam-Overlay gesehen hat — kein Greenscreen, einfach die Person freischwebend über dem Gameplay — der hat mit hoher Wahrscheinlichkeit NVIDIA Broadcast bei der Arbeit beobachtet. Eine App, die per GPU den Hintergrund in Echtzeit entfernt — und sie ist hervorragend. Saubere Kanten um die Haare, weiche Übergänge bei schnellen Bewegungen, null Konfiguration. Ich hab sie jahrelang unter Windows benutzt. Funktioniert einfach.

Dann habe ich mir vorgenommen auf Linux umzusteigen.

NVIDIA Broadcast gibt es nicht für Linux. Nicht „ist in der Beta“, nicht „gibt’s ’nen Workaround“ — es existiert schlicht und einfach nicht. Die zugrundeliegenden SDKs (Maxine, VFX SDK) sind zwar verfügbar, aber kostenpflichtig. NVIDIA möchte, dass ich für KI-Features auf der GPU, die ich bereits gekauft habe, nochmal extra zahle. Für ein Feature, das unter Windows kostenlos ist.

Ihr werdet euch jetzt fragen was das soll, warum macht der das? Ganz einfach:
1. habe ich keine AMD oder Intel GPU zur Hand, kann also nicht testen was Claude fabriziert.
2. Je weniger Code der verstehen muss desto besser funktioniert er (bilde ich mir zumindest ein).

Vor ein paar Monaten wäre das ein Dealbreaker gewesen. Ich bin kein Softwareentwickler. C++ und CUDA sind nicht meine Welt. Aber wir leben in interessanten Zeiten: Ich hab Claude Code aufgemacht und angefangen auszuprobieren was damit inzwischen so geht.

Die Diagnose

obs-backgroundremoval ist ein beeindruckendes Stück Open-Source-Software. Vier Jahre Entwicklung, acht KI-Modelle, Support für jede Plattform und jeden GPU-Hersteller — Windows, macOS, Linux, NVIDIA, AMD, Intel, CPU-Fallback. Das ist ein ausgereiftes Projekt, und was jetzt kommt, ist ausdrücklich kein Bashing des Projekts oder seines Autors. Die haben ein Cross-Platform-Plugin gebaut, das auf beinahe allem läuft. Was ich gemacht habe, ist das genaue Gegenteil: alles außer einem einzigen Ziel rauswerfen. Das ist kein besserer Ansatz — das ist ein anderer. Und genau darum geht’s in diesem Post: zeigen, was möglich ist, wenn man sich KI-Tools zunutze macht, um ein sehr spezifisches Problem zu lösen.

Für meinen Use Case — Linux, NVIDIA-GPU, Echtzeit-Streaming — war das Plugin nahezu unbenutzbar.

Das Plugin erledigt die gesamte KI-Schwerarbeit auf der CPU, während die GPU Däumchen dreht. Schlimmer noch: Es verarbeitet jedes Bild synchron — die gesamte OBS-Video-Pipeline steht still und wartet, während das KI-Modell grübelt, ob dieser Pixelhaufen jetzt eine Schulter ist oder ein Bücherregal. Das Resultat: Frame Drops, sichtbares Ruckeln, und Maskenkanten, die aussehen, als hätte jemand mit der Bastelschere um mich herumgeschnitten. Beim Streamen sieht das dann so aus wie im Video oben: Du bewegst den Kopf, und die Maske zieht eine halbe Sekunde später hinterher, außerdem ist sie nicht exakt genug.

Was nun?

Das Ziel: Echtzeit-Hintergrundentfernung in 1080p bei 30fps mit weichen Kanten in Broadcast-Qualität. Mit einer RTX 2060 Super.

Tabula Rasa

Die erste „Änderung“ war die gröbste. Ich hab Claude Code losgeschickt alles zu löschen was nicht „NVIDIA auf Linux“ war. Windows-Support — weg. macOS — weg. AMD, Intel, CPU-Fallback — alles weg. Vier Jahre sorgfältiger Cross-Platform-Arbeit mal eben entfernt.

Der reinste Vandalismus, sorry dafür. Aber sobald das alles raus war, wurde der kritische Pfad von einem Labyrinth aus #ifdefs zu Code, über den man tatsächlich nachdenken kann.

Manchmal ist das Produktivste, was man tun kann: Löschen.

Die Optimierung

Claude Code hat hier den gesamten Code geschrieben. Mein Job war: Ideen liefern, Richtungsentscheidungen treffen und jeden Zwischenstand testen. Ein Kreislauf aus „Versuch mal X“ → Code → Testen → „Nee, probier’s anders.“

Asynchrone Verarbeitung. Das Original-Plugin blockierte die gesamte OBS-Video-Pipeline während der Inferenz — jedes Bild wartete, bis die KI fertig war. Lösung: eine threadsichere Warteschlange. OBS schiebt Bilder rein, ein separater Thread verarbeitet sie im Hintergrund, und das nächste Bild greift sich das jeweils letzte Ergebnis. Frame Drops: sofort weg. Der Haken: Die Maske lief jetzt 2-3 Bilder hinter dem Video her. Würde ich später fixen. (Spoiler: Es wurde kompliziert.)

Speicher-Diät. Das Plugin kopierte komplette 1080p-Bilder — 8 Megabyte pro Stück — mehrfach pro Frame. Einmal fürs Preprocessing, einmal für den Worker-Thread, einmal für die Ausgabe. Bei 30fps sind das rund 750 MB/s reiner Abfall. Die Lösung: Statt Daten zu kopieren, einfach die Zeiger auf die Daten tauschen — der Computer merkt sich nur, wo das Bild liegt, statt es jedes Mal komplett umzuschaufeln.

GPU-Preprocessing. Fünf separate CPU-Operationen — Farbkonvertierung, Skalierung, Normalisierung, Formatkonvertierung, Layout-Transposition — ersetzt durch einen einzigen GPU-Kernel, der alles in einem Durchgang erledigt. Preprocessing sank von 3ms auf 1,8ms. Kein Gamechanger allein, aber bei einem Gesamtbudget von 33ms pro Frame zählt jede Millisekunde.

Wissen, wann man aufhört. Das Postprocessing (Glättung, Kantenbereinigung) operierte auf 61 Kilobyte Daten. Das passt komplett in den CPU-Cache. Das auf die GPU zu verschieben wäre tatsächlich langsamer gewesen, weil allein der Datentransfer länger dauern würde als die Berechnung selbst. Nicht alles muss auf der GPU laufen. Manchmal ist die langweilige Antwort die richtige.

TensorRT. Automatische Erkennung und Engine-Caching für einen Extra-Geschwindigkeitsboost auf Systemen, die es unterstützen (also RTX 2000 und neuer) — mit sauberem Fallback auf CUDA, wenn nicht.

Die Zahlen sahen auf dem Papier besser aus.
Aber die Maske hing immer noch sichtbar hinter meinen Kopfbewegungen her:

Wo es schmerzhaft wurde

Verdächtiger Nr. 1: Frame-Skipping. Das Plugin hatte einen „Ähnlichkeitscheck“, der aufeinanderfolgende Bilder in voller Auflösung verglich, um zu entscheiden, ob die Inferenz übersprungen werden kann. Klingt clever — warum identische Frames verarbeiten? Nur dass es 8-Megabyte-Bilder Pixel für Pixel verglich und 57% aller Frames übersprang. Abgeschaltet. Lagged immer noch.

Verdächtiger Nr. 2: Masken-Qualität. Wechsel von harten Binärmasken (jeder Pixel ist entweder „Du“ oder „nicht Du“) auf weiche Alpha-Matten — die Rohwahrscheinlichkeit des KI-Modells, bei der Kanten sanfte Übergänge bekommen statt harter Stufen. Echte Qualitätsverbesserung. Lagged immer noch.

Sackgasse: FP16. Halbpräzisions-Version des Modells geladen. OBS crashte beim Start — das Modell erwartete 16-Bit-Eingaben, der Code lieferte 32-Bit. Versuch, das Modell manuell zu konvertieren. Ergebnis: ein kaputter Berechnungsgraph, in dem manche Operationen 16-Bit und andere 32-Bit bekamen. Aufgegeben. Manchmal gewinnt man, manchmal lernt man, und manchmal löscht man den Branch und tut so, als wäre nichts gewesen.

Der Profiler rettet den Tag. NVIDIAs Nsight Systems — ein Profiling-Tool, das zeigt, wo genau die Zeit verbrannt wird. Die Ergebnisse waren ernüchternd:

StufeZeit
Nachbearbeitung (Kantenverfeinerung)13,9ms
KI-Modell-Inferenz7,7ms
GPU-Preprocessing1,8ms

Der Kantenverfeinerungs-Filter, den wir zur Verbesserung der Qualität hinzugefügt hatten, brauchte fast doppelt so lang wie die KI-Inferenz selbst. Die „Verbesserung“ war der Flaschenhals. Rausgerissen. Lektion gelernt: Vorher und nachher profilen, nicht nur vorher.

Lagged immer noch. Ohne den Flaschenhals lag die Inferenz bei etwa 10ms. Mehr als schnell genug. Also warum hing die Maske immer noch hinterher? Ich hab Claude analysieren lassen bis der Groschen fiel.

Die asynchrone Pipeline selbst war das Problem. Sie fügt bauartbedingt 2-3 Frames Latenz hinzu — der Worker-Thread verarbeitet immer ein Bild aus der Vergangenheit. Bei 30fps sind das 66-100ms Verzögerung. Sichtbar. Störend. Innerhalb einer asynchronen Architektur nicht behebbar.

Aber: 10ms Inferenz passen locker in ein 33ms-Frame-Budget. Das Modell war schnell genug, um synchron zu laufen — Bild verarbeiten und Ergebnis im selben Tick liefern, null Latenz. Die asynchrone Queue, die uns am Anfang vor Frame Drops gerettet hatte, hielt uns jetzt zurück.

Ein simpler Check: Wenn das Modell schnell genug ist, Queue überspringen und die Inferenz direkt inline ausführen. Die Maske ging von „hinkt hinterher“ zu „trackt viel besser.“ Null Frames Verzögerung (nicht die Maske sondern die Pipeline, das merkt man nur wenn man davor sitzt und das Video hinter den eigenen Bewegungen ein bisschen her hinkt).

Lies das Paper, nicht nur die API

Nach dem gelöschten Code, den GPU-Kernels, der Async-dann-doch-Sync-Pipeline, dem Profiling und den Sackgassen — kam die mit Abstand größte Verbesserung des ganzen Projekts. Und sie kam weder aus Code-Optimierung noch aus meiner Richtung. Claude hat sich das Research Paper zum KI-Modell durchgelesen.

Das Plugin fütterte das KI-Modell (RVM — Robust Video Matting) mit vorgeschrumpften 320×192-Bildern und streckte die resultierende winzige Maske dann wieder auf 1080p. Natürlich waren die Kanten matschig. Man kann eine 320 Pixel breite Maske nicht einfach hochskalieren und knackige Haarsträhnen erwarten.

Was Claude im Paper fand: RVM hat einen eingebauten Deep Guided Filter. Das Modell ist dafür konzipiert, das volle 1080p-Bild zu empfangen, es intern für die schnelle Inferenz herunterzurechnen, und dann das originale hochauflösende Bild als Orientierung zu nutzen, um die Maske auf volle Auflösung hochzuschärfen. Es benutzt die tatsächlichen Kanten im Webcam-Bild — Haare, Finger, die Konturen des Hoodies — um pixelgenaue Grenzen zu erzeugen. Schon besser.

Das Plugin umging das komplett. Durch das Vorverkleinern des Bildes und downsample_ratio=1.0 bekam der Guided Filter identische „niedrigauflösende“ und „hochauflösende“ Eingaben. Er war effektiv ein No-Op — er lief zwar, hatte aber nichts, womit er arbeiten konnte. Das beste Feature des Modells wurde einfach übersprungen.

Der Fix:

static constexpr int INPUT_WIDTH = 1920;
static constexpr int INPUT_HEIGHT = 1080;
static constexpr float DOWNSAMPLE_RATIO = 0.25f;

Drei Zeilen. Gib ihm das echte Bild. Lass das Modell das tun, wofür es gebaut wurde.

Das Backbone läuft intern weiterhin auf niedriger Auflösung, aber der Deep Guided Filter muss jetzt bei voller 1080p arbeiten — die GPU hat mehr zu tun, passt aber immer noch bequem ins 33ms-Budget. Ich hab den Stream gestartet, die Kamera angemacht und es war tatsächlich besser. Von „ausgeschnitten mit der Bastelschere“ zu beinahe natürlichen Kanten.

Das Ergebnis

VorherNachher
Frame Drops bei 1080pHäufigKeine
Masken-Latenz2-3 Frames (66-100ms)0 Frames
KantenqualitätHart, zackigWeichere Übergänge
GPU-Auslastung~15%~70%
Gesamte Frame-Zeit>33ms (zu langsam)~20ms (Luft nach oben)

An dieser Stelle machen wir einen Break, die Lösung ist immer noch nicht wirklich brauchbar, aber schon eine ganze Ecke weiter. Vor allem 70% GPU Auslastung „nur dafür“, das muss noch besser gehen. Doch dazu mehr im nächsten Beitrag.

Zum Abschluss möchte ich noch einmal reflektieren.

Vor einem Jahr wäre dieses Problem für mich unlösbar gewesen. Nicht „schwierig“ — unlösbar. GPU-optimierte Echtzeit-Video-Pipelines in C++ sind keine Sache, die man sich an einem Nachmittag beibringt. Aber mit Tools wie Claude Code verschiebt sich, was „zu schwierig“ bedeutet. Nicht, weil die KI alles besser kann — sie braucht Richtung, Feedback, jemanden, der testet und entscheidet. Aber sie gibt einem die Möglichkeit, Probleme anzupacken, die vorher schlicht außer Reichweite waren. Es bleibt also spannend.

Das hier ist Teil 1 meiner Linux-Journey. Als Nächstes: Die Middleware komplett rauswerfen — eine eigenständige TensorRT-Pipeline, die direkt von der Kamera zur virtuellen Webcam geht, in unter 7ms. Die Reise geht weiter.

-GF

Veröffentlicht unter Betriebssysteme, KI/AI | Verschlagwortet mit , , | Kommentare deaktiviert für Kein NVIDIA Broadcast für Linux? Na und?

OPNsense Unbound DNS:

Warum die Whitelist nicht funktioniert (und wie man es richtig macht)

Wer in OPNsense die Unbound-DNS-Blocklisten nutzt (z. B. Steven Black oder YoYo), kennt vermutlich das Problem: Man trägt eine Domain in die Whitelist ein — und sie wird trotzdem geblockt. Was auf den ersten Blick wie ein Bug aussieht, hat zwei konkrete Ursachen.

Das Problem: Einfache Domain-Einträge reichen nicht

Angenommen, man möchte beispiel-domain.com freigeben und trägt sie brav in das Feld Whitelist Domains unter Services → Unbound DNS → Blocklist ein. Das Ergebnis: Die Hauptdomain wird vielleicht durchgelassen, aber Subdomains wie track.beispiel-domain.com oder click.beispiel-domain.com bleiben weiterhin geblockt.

Ursache 1: CNAME-Bug

Es gibt einen bekannten Bug in der DNSBL-Implementierung: Wenn eine freigegebene Domain ein CNAME-Record ist, der auf eine geblockte Domain zeigt, wird sie trotzdem geblockt. Man müsste also zusätzlich die Zieldomain des CNAME-Records whitelisten — was mühsam und fehleranfällig ist.

Ursache 2: Subdomains werden nicht erfasst

Ein einfacher Eintrag wie beispiel-domain.com matcht eben nur genau diese Domain. Subdomains sind nicht automatisch eingeschlossen.

Die Lösung: Regex in der Whitelist

Was viele nicht wissen: Das Whitelist-Feld unterstützt reguläre Ausdrücke. Damit lässt sich eine Domain inklusive aller Subdomains auf einen Schlag freigeben.

Das Pattern dafür sieht so aus:

(.*)?(\.)?beispiel-domain.com

Dieser Ausdruck matcht sowohl beispiel-domain.com selbst als auch beliebige Subdomains wie track.beispiel-domain.com, click.beispiel-domain.com usw.

Wo wird das eingetragen?

Ganz normal im Feld Whitelist Domains unter Services → Unbound DNS → Blocklist. Pro Zeile ein Eintrag — entweder eine einfache Domain oder eben ein Regex-Pattern.

Fehlerdiagnose

Wenn ein Regex-Ausdruck ungültig ist, erscheint im Log unter /var/log/resolver/latest.log eine Meldung wie:

blocklist download : skip invalid whitelist exclude pattern "custom_pattern_1" (*\.example.net)

Der Stern allein (*\.example.net) ist kein gültiger Regex — man braucht das vollständige Pattern mit (.*)?(\.)?.

Fazit

Wer Domains in der OPNsense-Unbound-Blocklist zuverlässig whitelisten will, sollte immer das Regex-Pattern (.*)?(\.)?domain.com verwenden. Der einfache Domain-Eintrag ohne Regex funktioniert in vielen Fällen schlicht nicht — insbesondere bei Subdomains und CNAME-Auflösungen.


Quelle: OPNsense Forum – White Listed Domains not working in Unbound DNS: Blocklist

-GF

Der OPNsense-Praktiker: Enterprise-Firewalls mit Open Source
  • Einfache Paketfilter waren gestern
  • Selbst im Open-Source-Bereich haben Next-Generation Firewalls Einzug gehalten
  • Und OPNsense ist ganz vorne dabei, wenn es um Einbruchserkennung, Applikationskontrolle, Web-Filter oder Antivirus geht
  • Denn kein Netz ist zu unbedeutend, um nicht angegriffen zu werden
  • Auch Heimnetze, Armbanduhren und Lichtschalter sind bedroht und erwarten eine sichere Umgebung
Mini PC Core i3 N300 Firewall Appliance, OPNsense Mini Computer mit 6 Port i226-V 2.5GbE LAN, F5 Fanless Micro PC ohne RAM/SSD/OS, USB Type-C, 4K 3-Display, TF, AES-NI N300 6LAN NO RAM NO SSD
  • Energiesparender Hochleistungs-N300-Prozessor: Das CWWK F5 Mini PC verfügt über den energieeffizienten Core i3-N300 Prozessor mit 8 Kernen und 8 Threads, bis zu 3,8 GHz und 6 MB Cache. Mit einem Basis-TDP von nur 7W ist er ideal für den 24/7-Dauerbetrieb. Die hochfrequente 8-Kern-Leistung bewältigt anspruchsvolle Aufgaben effizient und eignet sich sowohl für energiesparende Firewall-Gateways als auch für leistungsstarke Virtualisierungsaufgaben
  • DDR5 und Dual NVMe Slot: 1 x DDR5 SO-DIMM 4800MHz RAM-Slot, bis zu 32GB. Mit 2 x M.2 Slots (PCIe3.0 x1) für 2280 große NVMe SSDs bietet es auch 1 x SATA3.0 Ports für SATA SSD/HDD-Installation, die extern über ein Kabel verbunden werden können. Wenn ein Wi-Fi/BT-Modul benötigt wird, kann der NVME2 Slot über einen M.2 M-Key zu M.2 E-Key Adapter in einen M.2 Wi-Fi Slot konvertiert werden
  • 6 x 2.5Gb Hochgeschwindigkeits LAN: Ausgestattet mit 6 x i226-V 2.5Gigabit Ethernet Controllern, die an 100M/1000M/2.5G LAN angepasst werden können. Es ist mit verschiedenen gängigen Open-Source-Soft-Router- oder Virtualisierungsplattformen wie OPNsense oder PVE kompatibel, ideal zum Aufbau von Netzwerksicherheitsfirewalls oder All-In-One-Virtualisierung
  • Verschiedene externe I/O-Schnittstellen: Die UHD-Grafik unterstützt hardwarebeschleunigte 4K Videoausgabe. Ausgestattet mit HD + DP + USB Typ-C, unterstützt dreifaches Bildschirm-Display, bis zu 4K@60Hz. 1 x USB3.0, 4 x USB2.0, 1 x MicroSD Slot für Datenspeicherung oder Systemstart, unterstützt das Umschalten der Auto-Power-On-Funktion über einen Kippschalter
  • Fanless Passive Cooling Design: Um eine effiziente Wärmeableitung zu gewährleisten, besteht das gesamte Gehäuse aus Aluminiumlegierung, mit einer wissenschaftlich gestalteten Kühlstruktur an der Ober- und Seitenfläche. Es ist speziell für den 24/7 Dauerbetrieb und energieeffizienten Betrieb konzipiert. Bitte beachten Sie, dass das Benutzerhandbuch und die FAQ-Anleitung vor dem Versand bereitgestellt werden
Veröffentlicht unter DNS, Firewall, OPNsense, unbound | Kommentare deaktiviert für OPNsense Unbound DNS:

Wenn Traefik kranke Container aussortiert

Dieses Problem hat mich kürzlich mehr Zeit gekostet, als ich zugeben möchte – und die Ursache war so subtil wie frustrierend.

aibix

Das Symptom
Ein Docker-Container wird gestartet, der Dienst darin läuft korrekt und beantwortet Anfragen. Doch im Traefik-Dashboard taucht er schlicht nicht auf. Kein Router, kein Service, keine Fehlermeldung. Nichts.

Man prüft die Labels, die Netzwerkkonfiguration, die Docker-Socket-Verbindung – alles sieht korrekt aus. Und doch: Traefik weigert sich, den Container zu routen.

Die Ursache: Hardcodierte Healthchecks
Viele Docker-Images bringen einen eingebauten HEALTHCHECK mit. Im Dockerfile sieht das typischerweise so aus:

```dockerfile
HEALTHCHECK CMD [ "curl", "-f", "http://localhost:8080/health" ]

Das Problem entsteht, wenn der Dienst im Container auf einem anderen Port gestartet wird – etwa weil man --port 8000 als Argument übergibt oder eine Umgebungsvariable den Port ändert. Der Healthcheck prüft weiterhin localhost:8080, dort antwortet aber niemand. Docker markiert den Container daraufhin als unhealthy.

Und genau hier greift Traefik’s Docker-Provider: Container, die den Status unhealthy haben, werden stillschweigend aus dem Routing ausgeschlossen. Kein Fehler im Dashboard, keine Warnung im Standard-Log. Erst auf Loglevel debug erscheint die Meldung „Filtering unhealthy or starting container“ – und selbst die ist leicht zu übersehen.

Dieses Verhalten ist fest im Docker-Provider von Traefik verankert. Es gibt keine Konfigurationsoption, um es abzuschalten. Entsprechende Feature-Requests existieren seit Jahren (z.B. traefik/traefik#7842), wurden aber bislang nicht umgesetzt.

Die Fehlerkette im Detail
1. Der Container startet mit einem vom Standard abweichenden Port (z.B. 8000)
2. Der Dienst bindet sich an diesen Port und funktioniert einwandfrei
3. Docker’s Healthcheck prüft den im Image hartkodierten Port (z.B. 8080) – Verbindung abgelehnt
4. Docker setzt den Container-Status auf unhealthy
5. Traefik erkennt den Status und schließt den Container komplett vom Routing aus
6. Im Dashboard und in den Standard-Logs gibt es keinen Hinweis auf das Problem

Lösungen

Variante A: Internen Port beibehalten, extern mappen
Die einfachste und robusteste Lösung: Den Container-internen Port beim Standard belassen und Docker’s Port-Mapping nutzen, um den Dienst auf dem gewünschten Host-Port verfügbar zu machen.

```bash
docker run -d -p 3010:8080 mein-image:latest

Der Healthcheck funktioniert, Traefik sieht einen gesunden Container, und der Dienst ist extern auf Port 3010 erreichbar. In der Traefik-Konfiguration zeigt der Loadbalancer weiterhin auf den internen Port:

```yaml
labels:
  - "traefik.http.services.mein-service.loadbalancer.server.port=8080"

Variante B: Healthcheck zur Laufzeit überschreiben
Wenn ein anderer interner Port zwingend erforderlich ist, kann der Healthcheck beim Start des Containers angepasst werden:

```bash
docker run --health-cmd "curl -f http://localhost:3010/health" mein-image:latest

Oder in docker-compose.yml:

```yaml
services:
  mein-service:
    image: mein-image:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3010/health"]
      interval: 30s
      timeout: 10s
      retries: 3

Variante C: Healthcheck deaktivieren
Falls kein Healthcheck benötigt wird, lässt er sich komplett abschalten:

```bash
docker run --no-healthcheck mein-image:latest
```

Oder in docker-compose.yml:

```yaml
healthcheck:
  test: ["NONE"]

Ohne definierten Healthcheck meldet Docker keinen Gesundheitsstatus, und Traefik hat keinen Grund, den Container zu filtern.

Fazit

Dieses Problem ist ein Paradebeispiel für eine Fehlerkette, bei der zwei an sich sinnvolle Mechanismen – Docker-Healthchecks und Traefik’s Container-Filterung – in Kombination zu schwer auffindbarem Fehlverhalten führen. Besonders tückisch ist die völlige Abwesenheit von Fehlermeldungen auf Standard-Loglevel.

Wer Traefik als Reverse-Proxy für Docker-Container einsetzt, sollte bei unerklärlichem Routing-Verhalten immer als Erstes den Health-Status der betroffenen Container prüfen:

```bash
docker inspect --format='{{.State.Health.Status}}' container-name

Zeigt dieser unhealthy, ist die Ursache mit hoher Wahrscheinlichkeit gefunden – auch wenn der Dienst selbst einwandfrei läuft.

-GF

API Gateways for Beginners: Build, Secure & Scale Microservices with NGINX, Kong, AWS API Gateway, Traefik & Kubernetes
  • API Gateways for Beginners: Build, Secure & Scale Microservices with NGINX, Kong, AWS API Gateway, Traefik & KubernetesModern applications rely on APIs—and as systems grow into distributed microservices, Kubernetes clusters, and serverless workloads, API gateways become the critical control plane that determines whether your platform remains fast, secure and reliable
  • Yet most books on API gateways are outdated, theoretical, or tied to a single vendor
  • This book is different
  • It is fully modern, fully hands-on, and built for the real-world architectures used across today’s cloud-native platforms
  • Designed for beginners and professionals alike, this book teaches you how to build, deploy, secure, automate and operate API gateways using industry-leading tools: NGINX, Kong Gateway, Traefik, AWS API Gateway, Kubernetes Gateway API, Prometheus, Grafana, OpenTelemetry, Keycloak, OPA, GitOps, and APIOps pipelines

Veröffentlicht unter traefik | Verschlagwortet mit | Kommentare deaktiviert für Wenn Traefik kranke Container aussortiert

GitLab 18.x hinter Traefik: Warum plötzlich HTTP 400 bei API-Calls auftreten

Beim Upgrade einer selbstgehosteten GitLab-Instanz von 18.1 auf 18.6 kann es zu unerwarteten HTTP-400-Fehlern kommen, etwa bei der Nutzung von glab mr create. Besonders betroffen sind Setups, bei denen GitLab hinter einem Reverse-Proxy wie Traefik betrieben wird.

Das Symptom

API-Aufrufe wie:

GET /api/v4/projects/group%2Fprojektname

schlagen mit 400 Bad Request fehl – obwohl sie in älteren GitLab-Versionen problemlos funktionierten.

Die Ursache

Zwei Änderungen treffen hier aufeinander:

  1. GitLab API
    • Viele API-Endpoints (u. a. Projects, Merge Requests, Resource Groups) akzeptieren Projekt-IDs entweder als numerische ID oder als URL-kodierten Projektpfad.
    • Moderne GitLab-Versionen sind strikter und erwarten korrekt URL-kodierte Pfade (%2F statt /).
  2. Traefik (v3.6.3+)
    • Aus Sicherheitsgründen blockiert Traefik standardmäßig kodierte Sonderzeichen im URL-Pfad, darunter %2F.
    • Solche Requests werden direkt von Traefik mit HTTP 400 abgelehnt und erreichen GitLab gar nicht.

Das Ergebnis: GitLab „funktioniert nicht mehr“, obwohl in Wirklichkeit der Proxy die Anfrage verwirft.

Die Lösung

In Traefik muss das Zulassen kodierter Slashes global auf EntryPoint-Ebene aktiviert werden:

entryPoints:
  https:
    address: ":443"
    http:
      encodedCharacters:
        allowEncodedSlash: true

Nach einem Neustart von Traefik werden API-Requests mit %2F korrekt weitergeleitet, und Tools wie glab funktionieren wieder wie erwartet.

Fazit

Der Fehler liegt weder bei glab noch bei GitLab selbst, sondern in einer Sicherheitsverschärfung von Traefik, die mit den strengeren API-Anforderungen neuer GitLab-Versionen kollidiert. Wer GitLab hinter Traefik betreibt, sollte diese Einstellung prüfen – insbesondere nach Updates.

Kurz gesagt: GitLab wollte korrekt kodierte URLs, Traefik hat sie blockiert.

Veröffentlicht unter gitlab, traefik | Verschlagwortet mit , , , | Kommentare deaktiviert für GitLab 18.x hinter Traefik: Warum plötzlich HTTP 400 bei API-Calls auftreten

Proxmox: GPU sharing in LXC Containern

Warum GPU-Sharing mit LXC-Containern?

Wenn du einen Proxmox-Server mit einer GPU betreibst und verschiedene Dienste wie Ollama (für KI-Modelle), Plex (für Medien-Transcoding) oder Frigate (für Videoüberwachung) mit Hardware-Beschleunigung nutzen möchtest, stehst du vor einer wichtigen Entscheidung.

Die zwei Optionen:

  1. GPU-Passthrough zu einer VM: Funktioniert gut, aber die GPU kann nur an EINE einzige VM weitergegeben werden
  2. GPU-Sharing mit LXC-Containern: Mehrere Container können sich die GPU gleichzeitig teilen

Da die meisten von uns ihre Dienste isoliert voneinander betreiben möchten, ist Option 2 mit LXC-Containern oft die bessere Wahl. Der einzige „Nachteil“: Du musst LXC-Container statt VMs verwenden – was für die meisten Standalone-Dienste aber kein Problem darstellt.

Voraussetzungen

Bevor wir loslegen, stelle sicher, dass folgende Voraussetzungen erfüllt sind:

  • Proxmox VE 8.2+ oder 9.0 (empfohlen für Web-UI Device Passthrough)
  • Eine unterstützte GPU (NVIDIA, AMD oder Intel)
  • Root-Zugriff auf den Proxmox-Host
  • Grundkenntnisse in der Linux-Kommandozeile

💡 Neu in Proxmox VE 9.0: Die Version 9.0 (veröffentlicht im August 2025) basiert auf Debian 13 „Trixie“ mit Linux Kernel 6.14.8-2 und bringt LXC 6.0.4 mit verbesserter Ressourcenverwaltung und Cgroup v2-Integration. Die Web-UI Device Passthrough Funktion wurde bereits in Version 8.2.7 eingeführt und ist in Version 9.0 weiter optimiert.

Wichtiger Hinweis: Falls du bereits GPU-Passthrough für VMs konfiguriert hast (mit Blacklisting von Treibern etc.), musst du diese Änderungen rückgängig machen. LXC-Container benötigen funktionierende Treiber auf dem Host!

Moderne Methode: Web-UI Device Passthrough (Proxmox 8.2.7+)

Seit Proxmox VE 8.2.7 gibt es eine deutlich einfachere Methode für GPU-Passthrough zu LXC-Containern über die Web-Oberfläche. Diese Methode funktioniert sogar mit unprivilegierten Containern!

Schritt 1: GPU im Web-UI hinzufügen

  1. Wähle deinen Container in der Proxmox Web-UI aus
  2. Gehe zu Resources
  3. Klicke auf AddDevice Passthrough
  4. Gib den Device-Pfad ein (z.B. /dev/dri/card0 für Intel/AMD oder /dev/nvidia0 für NVIDIA)
  5. Klicke auf Advanced und setze:
    • Access Mode: 0666
    • GID: 104 (render group) für unprivilegierte Container
    • UID: Optional, je nach Anwendung

Diese Methode ersetzt die manuelle Konfiguration mit lxc.cgroup2.devices.allow und lxc.mount.entry Einträgen!

NVIDIA GPU Konfiguration

Schritt 1: NVIDIA-Treiber auf dem Host installieren

Zuerst müssen die NVIDIA-Treiber auf dem Proxmox-Host installiert werden. Lade den passenden Treiber von der NVIDIA-Website herunter.

# Vorhandene NVIDIA-Pakete entfernen (wichtig!)
apt remove --purge nvidia* libnvidia* libnvcuvid1

# Nouveau-Treiber blacklisten
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
update-initramfs -u

# System neustarten
reboot

# NVIDIA-Treiber installieren (Beispiel für Version 550.127.05)
wget https://us.download.nvidia.com/XFree86/Linux-x86_64/550.127.05/NVIDIA-Linux-x86_64-550.127.05.run
chmod +x NVIDIA-Linux-x86_64-550.127.05.run
./NVIDIA-Linux-x86_64-550.127.05.run --dkms

Schritt 2: GPU-Geräte identifizieren

Nach der Installation überprüfe die NVIDIA-Geräte:

# NVIDIA-Geräte anzeigen
ls -l /dev/nvidia*

# Ausgabe sollte etwa so aussehen:
crw-rw-rw- 1 root root 195,   0 Nov 25 10:00 /dev/nvidia0
crw-rw-rw- 1 root root 195, 255 Nov 25 10:00 /dev/nvidiactl
crw-rw-rw- 1 root root 507,   0 Nov 25 10:00 /dev/nvidia-uvm
crw-rw-rw- 1 root root 507,   1 Nov 25 10:00 /dev/nvidia-uvm-tools

Schritt 3: Container konfigurieren

Option A: Web-UI Methode (empfohlen für Proxmox 8.2.7+/9.0)

Füge über Resources → Add → Device Passthrough folgende Geräte hinzu:

  • /dev/nvidia0 mit Mode: 0666
  • /dev/nvidiactl mit Mode: 0666
  • /dev/nvidia-uvm mit Mode: 0666
  • /dev/nvidia-uvm-tools mit Mode: 0666
  • /dev/nvidia-modeset mit Mode: 0666 (falls vorhanden)

Option B: Manuelle Methode (für ältere Versionen)

Bearbeite die Container-Konfiguration (ersetze 100 mit deiner Container-ID):

nano /etc/pve/lxc/100.conf

Füge folgende Zeilen hinzu (passe die Zahlen an deine Geräte an):

# NVIDIA GPU Support
lxc.cgroup2.devices.allow: c 195:* rwm
lxc.cgroup2.devices.allow: c 507:* rwm
lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file

Schritt 4: NVIDIA-Treiber im Container installieren

Starte den Container und installiere die gleiche Treiberversion:

# Im Container ausführen:
wget https://us.download.nvidia.com/XFree86/Linux-x86_64/550.127.05/NVIDIA-Linux-x86_64-550.127.05.run
chmod +x NVIDIA-Linux-x86_64-550.127.05.run
./NVIDIA-Linux-x86_64-550.127.05.run --no-kernel-module

Wichtig: Der Parameter --no-kernel-module ist essentiell, da der Container den Kernel des Hosts nutzt!

AMD GPU Konfiguration

AMD-GPUs sind besonders interessant für KI-Workloads, da Modelle wie die RX 7900 XTX mit 24GB VRAM ausgestattet sind – perfekt für große LLMs!

Schritt 1: Geräte überprüfen

# AMD GPU-Geräte anzeigen
ls -l /dev/dri
ls -l /dev/kfd

Schritt 2: Container konfigurieren (Web-UI Methode)

In Proxmox 8.2.7+ und 9.0:

  1. Wähle deinen Container aus
  2. Gehe zu Resources
  3. Klicke auf AddDevice Passthrough
  4. Füge folgende Geräte hinzu:
    • /dev/dri/card0 mit Mode: 0666, GID: 104 (render)
    • /dev/dri/renderD128 mit Mode: 0666, GID: 104
    • /dev/kfd mit Mode: 0666 (für ROCm-Support)

Der Vorteil: Diese Methode funktioniert auch perfekt mit unprivilegierten Containern!

Schritt 3: ROCm im Container installieren

# ROCm Repository hinzufügen (Ubuntu/Debian)
wget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | apt-key add -
echo 'deb [arch=amd64] https://repo.radeon.com/rocm/apt/debian/ ubuntu main' > /etc/apt/sources.list.d/rocm.list

# ROCm installieren
apt update
apt install rocm-dkms

Intel GPU Konfiguration

Intel-GPUs eignen sich hervorragend für Media-Transcoding mit Plex oder Jellyfin. Mit Intel VT-d können in Proxmox 8.2+ sogar bis zu 7 VMs die GPU teilen!

Schritt 1: Intel GPU-Unterstützung auf dem Host

# Intel Media Driver installieren
apt update
apt install intel-media-va-driver-non-free

Schritt 2: Container-Konfiguration (Web-UI Methode)

Füge über die Web-UI folgende Geräte hinzu:

  • /dev/dri/card0 mit Mode: 0666, GID: 104
  • /dev/dri/renderD128 mit Mode: 0666, GID: 104

Alternativ für die manuelle Methode in /etc/pve/lxc/100.conf:

# Intel GPU Support
lxc.cgroup2.devices.allow: c 226:* rwm
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir

Schritt 3: Gruppe im Container anpassen

# Im Container die render-Gruppe für den Benutzer hinzufügen
usermod -aG video,render plex  # Beispiel für Plex-User

Unprivilegierte Container – Die sichere Wahl

Mit der Web-UI Device Passthrough Funktion ist es jetzt viel einfacher, GPUs auch in unprivilegierten Containern zu nutzen:

  • Setze einfach die GID auf 104 (render group) in den Advanced Settings
  • Keine komplexen idmap-Konfigurationen mehr nötig
  • Funktioniert out-of-the-box mit den meisten Anwendungen

Dies löst das alte Sicherheitsproblem, bei dem privilegierte Container für einfache GPU-Passthrough benötigt wurden.

Verifizierung der GPU-Funktionalität

Für NVIDIA:

# Im Container ausführen:
nvidia-smi

# Sollte die GPU und aktuelle Auslastung anzeigen

Für AMD:

# ROCm-Info anzeigen
rocm-smi
rocminfo

Für Intel:

# Intel GPU-Tools installieren und testen
apt install intel-gpu-tools
intel_gpu_top

Praktische Anwendungsfälle

Ollama für lokale LLMs

Nach der GPU-Konfiguration kannst du Ollama einfach installieren:

# Ollama installieren
curl -fsSL https://ollama.com/install.sh | sh

# Modell herunterladen und starten
ollama run llama3.2

# GPU-Nutzung überprüfen
nvidia-smi  # sollte Ollama-Prozess zeigen

Plex Media Server mit Hardware-Transcoding

# Nach Plex-Installation Hardware-Transcoding aktivieren:
# 1. Plex Web-Interface öffnen
# 2. Einstellungen → Transcoder
# 3. "Use hardware acceleration when available" aktivieren

Jellyfin mit GPU-Beschleunigung

Jellyfin ist besonders beliebt für GPU-Transcoding in LXC-Containern:

# Jellyfin Installation
apt update
apt install jellyfin

# In Jellyfin Settings → Playback:
# Hardware acceleration: VAAPI (Intel/AMD) oder NVENC (NVIDIA)

Frigate für Videoüberwachung

In der Frigate-Konfiguration config.yml:

ffmpeg:
  hwaccel_args: preset-nvidia-h264  # für NVIDIA
  # oder
  hwaccel_args: preset-vaapi  # für Intel/AMD

Häufige Probleme und Lösungen

Problem: „NVIDIA-SMI has failed“

Lösung: Stelle sicher, dass die Treiberversionen auf Host und Container identisch sind!

Problem: Permission denied beim GPU-Zugriff

Lösung: Bei unprivilegierten Containern: Verwende die Web-UI und setze die GID auf 104 (render group).

Problem: HDR Tone Mapping funktioniert nicht (Intel)

Bekanntes Problem: Bei Intel GPUs in LXC-Containern kann HDR Tone Mapping in Plex problematisch sein. Hardware-Transcoding funktioniert aber weiterhin.

Problem: Container startet nicht nach GPU-Konfiguration

Lösung: Prüfe die Syntax in der Container-Config. Ein fehlendes Komma oder Leerzeichen kann den Start verhindern.

Proxmox VE 9.0 – Was ist neu?

Die im August 2025 veröffentlichte Version 9.0 bringt einige Verbesserungen für Container:

  • LXC 6.0.4: Verbesserte Ressourcenverwaltung und Sicherheitsisolation
  • Cgroup v2: Bessere Integration für moderne Container-Workloads
  • Kernel 6.14.8-2: Verbesserte GPU-Treiberunterstützung
  • SDN Fabric Support: Komplexere Netzwerkarchitekturen für Container-Cluster

Die Web-UI Device Passthrough Funktion wurde bereits in 8.2.7 eingeführt und ist in 9.0 weiter optimiert worden.

Wichtige Überlegungen zur Sicherheit

LXC-Container mit GPU-Zugriff haben erweiterte Rechte. Beachte folgende Punkte:

  • Unprivilegierte Container (empfohlen): Mit der Web-UI Device Passthrough Methode jetzt einfach umsetzbar
  • Privilegierte Container: Nur verwenden, wenn absolut notwendig
  • Verwende GPU-Sharing nur für vertrauenswürdige Workloads
  • Isoliere kritische Dienste in separaten Containern
  • Nutze die GID-Einstellungen für granulare Zugriffskontrolle

Performance-Tipps

  • Mehrere Container können die GPU gleichzeitig nutzen, aber die Performance wird geteilt
  • Für maximale Performance bei einzelnen Workloads: GPU-Passthrough zu einer VM verwenden
  • Überwache die GPU-Auslastung mit nvidia-smi, rocm-smi oder intel_gpu_top
  • Plane GPU-intensive Tasks zeitversetzt, wenn mehrere Dienste die GPU nutzen
  • Nutze die erweiterten Cgroup v2 Features in Proxmox 9.0 für bessere Ressourcenkontrolle

Fazit

GPU-Sharing mit LXC-Containern in Proxmox ist eine elegante Lösung, um Hardware-Beschleunigung für mehrere Dienste gleichzeitig bereitzustellen. Mit den Verbesserungen in Proxmox 8.2.7+ und besonders in Version 9.0 ist die Einrichtung deutlich einfacher geworden – besonders durch die Web-UI Device Passthrough Funktion.

Der große Vorteil gegenüber VM-Passthrough: Du bist nicht auf einen einzigen Dienst beschränkt und kannst die GPU-Ressourcen flexibel zwischen verschiedenen Anwendungen teilen. Mit der Unterstützung für unprivilegierte Container ist dies jetzt auch sicher möglich.

Weiterführende Ressourcen

Hast du Fragen oder eigene Erfahrungen mit GPU-Sharing in Proxmox? Teile sie gerne in den Kommentaren!

Veröffentlicht unter Virtualisierung | Verschlagwortet mit , , | Schreibe einen Kommentar

Intel iGPU Hardware-Transcodierung in Proxmox LXC Container einrichten

In diesem Artikel zeige ich Ihnen, wie Sie Intel GPU Hardware-Transcodierung in einem Proxmox LXC Container erfolgreich einrichten. Diese Anleitung basiert auf einer getesteten Konfiguration mit Debian 13 (Trixie) und einer Intel Alder Lake-N Grafikkarte.

Systemvoraussetzungen

Für dieses Setup benötigen Sie:

  • Host-System: Proxmox VE 9.0 oder höher
  • Container OS: Debian 13 (Trixie) – empfohlen wegen aktueller Treiber
  • Intel GPU: Integrierte Intel Grafik (getestet mit Alder Lake-N)
  • Kernel: Proxmox Kernel 6.14.8-2-pve oder neuer

Die GPU muss bereits im Proxmox Container konfiguriert sein (Device Passthrough). In unserem Fall war die PCI-Adresse 0000:00:02.0.

Schritt 1: Grundlegende Pakete installieren

Melden Sie sich als root in Ihrem Container an und installieren Sie zunächst die grundlegenden Tools:

apt update
apt install -y pciutils udev

Überprüfen Sie, ob die GPU erkannt wird:

lspci | grep VGA
# Ausgabe sollte Ihre Intel GPU zeigen

Schritt 2: Intel Treiber und VA-API installieren

Installieren Sie alle notwendigen Intel-Treiber und VA-API Komponenten:

# Intel Media Treiber
apt install -y intel-media-va-driver-non-free i965-va-driver

# VA-API Bibliotheken und Tools
apt install -y libva2 libva-dev vainfo va-driver-all

# Intel spezifische Bibliotheken
apt install -y libigdgmm12 libvpl2 libmfx-gen1.2

# Monitoring Tools
apt install -y intel-gpu-tools

Schritt 3: FFmpeg mit Hardware-Unterstützung installieren

apt install -y ffmpeg

Debian Trixie liefert FFmpeg bereits mit vollständiger Intel QSV (Quick Sync Video) Unterstützung aus.

Schritt 4: Umgebungsvariablen konfigurieren

Erstellen Sie die Datei /etc/environment mit folgendem Inhalt:

LIBVA_DRIVER_NAME=iHD
LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri

Diese Variablen stellen sicher, dass der Intel iHD Treiber verwendet wird.

Schritt 5: Installation überprüfen

VA-API Test

# VA-API Unterstützung prüfen
vainfo --display drm --device /dev/dri/renderD128

Sie sollten eine Liste der unterstützten Profile und Entrypoints sehen, einschließlich:

  • VAProfileH264Main
  • VAProfileHEVCMain
  • VAProfileVP9Profile0

FFmpeg QSV Support

# Verfügbare Hardware-Beschleuniger anzeigen
ffmpeg -hide_banner -hwaccels | grep qsv

# QSV Encoder auflisten
ffmpeg -hide_banner -encoders | grep qsv

Schritt 6: Test-Script erstellen

Erstellen Sie /root/test_gpu_transcoding.sh mit folgendem Inhalt:

#!/bin/bash

echo "=== Intel GPU Transcoding Test Script ==="
echo

# Farben für Ausgabe
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# Test 1: VA-API Check
echo "1. Checking VA-API support..."
if vainfo --display drm --device /dev/dri/renderD128 2>/dev/null | grep -q "VAProfileH264Main"; then
    echo -e "${GREEN}✓ VA-API is working${NC}"
else
    echo -e "${RED}✗ VA-API not working${NC}"
    exit 1
fi
echo

# Test 2: FFmpeg QSV Check
echo "2. Checking ffmpeg QSV support..."
if ffmpeg -hide_banner -encoders 2>/dev/null | grep -q h264_qsv; then
    echo -e "${GREEN}✓ FFmpeg QSV support detected${NC}"
else
    echo -e "${RED}✗ FFmpeg QSV support not found${NC}"
    exit 1
fi
echo

# Test 3: Create test video
echo "3. Creating test video..."
ffmpeg -f lavfi -i testsrc=duration=5:size=1280x720:rate=30 \
       -f lavfi -i sine=frequency=1000:duration=5 \
       -c:v libx264 -preset ultrafast -c:a aac \
       -y /tmp/test_input.mp4 2>/dev/null
echo -e "${GREEN}✓ Test video created${NC}"
echo

# Test 4: Software encoding
echo "4. Testing software H.264 encoding..."
START=$(date +%s%N)
ffmpeg -i /tmp/test_input.mp4 -c:v libx264 -preset faster \
       -b:v 2M -c:a copy -y /tmp/test_sw.mp4 2>/dev/null
END=$(date +%s%N)
SW_TIME=$((($END - $START)/1000000))
echo -e "${GREEN}✓ Software encoding: ${SW_TIME}ms${NC}"
echo

# Test 5: Hardware encoding
echo "5. Testing hardware H.264 QSV encoding..."
export LIBVA_DRIVER_NAME=iHD
START=$(date +%s%N)
ffmpeg -hwaccel qsv -qsv_device /dev/dri/renderD128 \
       -i /tmp/test_input.mp4 -c:v h264_qsv -preset faster \
       -b:v 2M -c:a copy -y /tmp/test_hw.mp4 2>/dev/null
END=$(date +%s%N)
HW_TIME=$((($END - $START)/1000000))
echo -e "${GREEN}✓ Hardware encoding: ${HW_TIME}ms${NC}"
echo

# Performance comparison
SPEEDUP=$(echo "scale=1; $SW_TIME / $HW_TIME" | bc)
echo "=== Performance Summary ==="
echo "Software encoding: ${SW_TIME}ms"
echo "Hardware encoding: ${HW_TIME}ms"
echo -e "${GREEN}Hardware acceleration is ${SPEEDUP}x faster!${NC}"
echo

# Cleanup
rm -f /tmp/test_*.mp4

echo "All tests completed successfully!"

Machen Sie das Script ausführbar:

chmod +x /root/test_gpu_transcoding.sh

Leistungsvergleich

In unseren Tests mit einem 5-Sekunden 720p Video zeigten sich folgende Ergebnisse:

Encoding-MethodeZeitGeschwindigkeit
Software H.2641471msBaseline
Hardware H.264 (QSV)405ms3.6x schneller
Hardware HEVC (QSV)502ms2.9x schneller

Die Hardware-Beschleunigung erreichte dabei eine Transcodierungsgeschwindigkeit von:

  • 17x Echtzeit für H.264
  • 13x Echtzeit für HEVC

Unterstützte Codecs

Mit diesem Setup stehen folgende Hardware-Codecs zur Verfügung:

  • H.264/AVC (h264_qsv) – Encoding & Decoding
  • HEVC/H.265 (hevc_qsv) – Encoding & Decoding
  • VP9 (vp9_qsv) – Encoding & Decoding
  • MPEG-2 (mpeg2_qsv) – Encoding & Decoding
  • MJPEG (mjpeg_qsv) – Encoding
  • ⚠️ AV1 (av1_qsv) – Je nach GPU-Generation

Praktische FFmpeg Befehle

H.264 Transcodierung mit QSV

export LIBVA_DRIVER_NAME=iHD
ffmpeg -hwaccel qsv -qsv_device /dev/dri/renderD128 -i input.mp4 \
    -c:v h264_qsv -preset faster -b:v 2M -c:a copy output.mp4

HEVC/H.265 Transcodierung

ffmpeg -hwaccel qsv -qsv_device /dev/dri/renderD128 -i input.mp4 \
    -c:v hevc_qsv -preset faster -b:v 1M -c:a copy output_hevc.mp4

Vollständige Hardware-Pipeline (Decode + Encode)

ffmpeg -hwaccel qsv -c:v h264_qsv -i input.mp4 \
    -c:v hevc_qsv -preset faster -b:v 1M -c:a copy output.mp4

GPU-Auslastung überwachen

⚠️ Wichtiger Hinweis: Das Tool intel_gpu_top erfordert einen privilegierten Container für vollen Zugriff auf GPU-Metriken. Falls der Befehl mit einem Fehler wie „Failed to detect engines“ fehlschlägt, müssen Sie Ihren Container als privilegiert konfigurieren:

In der Proxmox Container-Konfiguration unter Options → Features aktivieren Sie:

  • Nesting (für Container-in-Container)
  • Fügen Sie in der Container-Konfigurationsdatei /etc/pve/lxc/[CTID].conf folgende Zeile hinzu:
    lxc.apparmor.profile: unconfined

Mit intel_gpu_top können Sie die GPU-Auslastung in Echtzeit beobachten:

intel_gpu_top

Dies zeigt Ihnen die Auslastung der verschiedenen GPU-Engines, einschließlich der Video-Engine während der Transcodierung.

Alternativ können Sie auch grundlegende GPU-Informationen ohne privilegierten Zugriff abrufen:

# GPU-Frequenz anzeigen
cat /sys/class/drm/card*/gt_cur_freq_mhz

# GPU-Speichernutzung
cat /sys/kernel/debug/dri/*/i915_gem_objects

Anwendungsfälle

Dieses Setup eignet sich hervorragend für:

  • Video-Streaming-Dienste: Jellyfin, Plex, Emby mit Hardware-Transcodierung
  • Live-Streaming: OBS Studio mit QSV Encoder
  • Videokonvertierung: Batch-Konvertierung großer Videobibliotheken
  • Überwachungskameras: Motion Detection und Aufzeichnung mit geringer CPU-Last
  • Videokonferenz-Server: Jitsi, BigBlueButton mit Hardware-Beschleunigung

Fehlerbehebung

Problem: VA-API funktioniert nicht

Prüfen Sie die Berechtigungen der DRM-Geräte:

ls -la /dev/dri/
# renderD128 sollte lesbar sein

Problem: FFmpeg findet QSV nicht

Stellen Sie sicher, dass die Umgebungsvariable gesetzt ist:

export LIBVA_DRIVER_NAME=iHD

Problem: Schlechte Performance

Überprüfen Sie mit intel_gpu_top, ob die GPU tatsächlich verwendet wird. Die Video-Engine sollte während der Transcodierung aktiv sein.

Fazit

Die Einrichtung der Intel GPU Hardware-Transcodierung in einem Proxmox LXC Container bietet erhebliche Leistungsvorteile. Mit einer 3-4fachen Geschwindigkeitssteigerung gegenüber Software-Encoding und Unterstützung für moderne Codecs ist das System ideal für medienintensive Anwendungen.

Die Kombination aus Debian Trixie’s aktuellen Treibern und Proxmox’s Container-Technologie ermöglicht eine effiziente und isolierte Umgebung für Video-Transcodierung mit minimaler CPU-Belastung.

Haben Sie Fragen oder Erfahrungen mit diesem Setup? Hinterlassen Sie gerne einen Kommentar!

Veröffentlicht unter Uncategorized | Kommentare deaktiviert für Intel iGPU Hardware-Transcodierung in Proxmox LXC Container einrichten

KI am Arbeitsplatz: Das neue Office – Warum wir alle lernen müssen, mit künstlicher Intelligenz zu arbeiten

Neulich hatte ich ein Gespräch mit einem Kollegen, das mich zum Nachdenken gebracht hat. Er saß vor seinem Laptop, bastelte an irgendwelchen Diagrammen und Planungen herum. Als ich ihm sagte, dass sowas zukünftig auch die KI für ihn machen könnte, kam eine Antwort, die mich aufhorchen ließ: „Das KI-Zeug habe ich dreimal ausprobiert, dreimal eine bescheidene Antwort bekommen – brauche ich nicht.“

Die Realität außerhalb der Tech-Bubble

Mein Kollege ist ein bodenständiger Familienvater, kein Technik-Nerd, sondern jemand mit einem echten Leben außerhalb der digitalen Welt. Und genau solche Menschen gibt es millionenfach. Das muss man respektieren – nicht jeder lebt in einer Technik-Bubble, wo KI allgegenwärtig ist.

Aber hier liegt das Problem: Während mein YouTube-Feed von oben bis unten mit KI-Content gefüllt ist, beschäftigt sich die arbeitende Bevölkerung mehrheitlich noch nicht ernsthaft mit diesem Thema. Viele sehen keinen Grund, sich in ihrer Freizeit damit auseinanderzusetzen oder den Chef zu drängen, entsprechende Schulungen anzubieten.

KI wird das neue Office

Dabei ist KI nichts anderes als das, was damals mit Office-Programmen passiert ist. Outlook, Excel, Word, PowerPoint – das mussten wir alle irgendwann lernen. Auch die Computer-Verweigerer, die sagten: „Ich brauche das nicht, ich habe meinen Ordner, meinen Stift und meinen Kopierer.“

Heute kann jeder Basic-Office-Programme bedienen, sonst ist man beruflich raus. Bei KI wird es genauso laufen. Wer heute nicht lernt, mit diesen Tools umzugehen, wird morgen ersetzt – nicht durch die KI selbst, sondern durch den Kollegen, der es gelernt hat.

Der falsche Mythos vom KI-Ersatz

Viele Chefs und Investoren glauben fälschlicherweise, sie könnten Informationsmitarbeiter einfach durch KI ersetzen. Das ist grundfalsch. Klar, sie werden es zunächst versuchen: „Warum einen Mitarbeiter für Social Media Postings bezahlen, wenn mein Copilot das auch kann?“

Aber ein ein- oder zweizeiliger Social Media Post ist etwas völlig anderes als ein Businessplan, eine wissenschaftliche Arbeit oder komplexe Programmierung. Für alles Größere braucht die KI das Fachwissen eines Menschen, der sie anleiten kann.

KI als Produktivitäts-Booster

Der Trick liegt darin, KI mit Kontext zu füttern: mit Informationen, Dokumentation, projektspezifischen Daten. Du arbeitest quasi gemeinsam mit der KI einen Plan aus – wie ein Dompteur einer Engineering-Abteilung.

Die KI erhöht den Output eines Mitarbeiters, der weiß, was er tut und wie er das der KI beibringt. Den Mitarbeiter kann man nicht einfach ersetzen. Aber sehr wohl kann man jemanden ersetzen, der sagt: „Brauche ich nicht“ – denn dessen Job macht dann der Kollege, der sich mit KI beschäftigt hat und plötzlich den zehnfachen Output produziert.

Das Skillset der Zukunft

Was wird zukünftig wichtig sein? Eine Sammlung von „Voreinstellungsdateien“ – Prompts und Anweisungen, mit denen du KI-Systeme für verschiedene Aufgaben konfigurierst. Das ist wie das initiale Priming: „Lege immer ein Git-Repository an, achte auf Versionskontrolle, verwende diese Dateistruktur.“

Dazu kommen projektspezifische Vorgaben. Ob du ein Buch schreibst oder Ausschreibungen erstellst – du baust dir Templates und fütterst sie mit projektspezifischen Daten. Dann gibst du der KI Input für zehn Projekte und sie macht die Arbeit von zehn Leuten gleichzeitig.

Künstliche Idioten, nicht künstliche Intelligenz

Der Begriff „künstliche Intelligenz“ ist Marketing-Blabla. Es sind eher „künstliche Idioten“ – wie Savants, die etwas furchtbar gut können (ganz viel, ganz schnell), aber trotzdem angeleitet werden müssen. Sie können das Telefonbuch auswendig lernen, aber danach niemanden anrufen.

Wir müssen diesen Systemen beibringen, wie die Welt funktioniert. Das kostet Zeit und Lernaufwand, aber es ist unvermeidlich.

KI für den Menschen, nicht für den Investor

Die Zukunft heißt KI für den Menschen, nicht für Investoren oder Chefs, die auf dem Hype-Train sitzen. Es geht darum, der Allgemeinheit zugänglich zu machen, warum dieses Thema wichtig ist.

Die Wahrheit ist: Du wirst nicht durch KI ersetzt, sondern durch deinen Kollegen, der gelernt hat, mit KI zu arbeiten und dadurch den zehnfachen Output produziert. Die Competition ist nicht mit der KI, sondern mit dem Arbeitskollegen nebenan.

Es ist wie früher: persönliche Weiterentwicklung, Wissen aneignen, neue Werkzeuge beherrschen. Wer das versteht und umsetzt, bleibt relevant. Wer es ignoriert, wird abgehängt.

Fazit

KI ist kein Hype, sondern das nächste Office. Jeder, der beruflich überleben will, muss lernen, brauchbare und wiederholbare Ergebnisse aus diesen Systemen herauszuholen. Die Zeit der Ausreden ist vorbei – entweder du lernst es, oder dein Kollege übernimmt deinen Job mit zehnfacher Produktivität.

Beschäftige dich damit. Es ist wichtiger, als du denkst.

Veröffentlicht unter KI/AI | Kommentare deaktiviert für KI am Arbeitsplatz: Das neue Office – Warum wir alle lernen müssen, mit künstlicher Intelligenz zu arbeiten

OPNsense VM Platte voll?

Auf einer meiner OPNsense VMs war die zugewiesene Platte voll. Das lässt sich ganz einfach beheben, wie in folgendem Video beschrieben:

Hier habe ich dir noch schnell die passenden Befehle rausgeschrieben.

Zum Anzeigen der Plattenbelegung:

gpart show

Nach dem Vergrößern der Platte musst du zuerst die Partitionstabelle fixen:

gpart recover da0

Setze dabei für da0 die Bezeichnung deiner Patte ein.

Jetzt kannst du die Partition vergrößern:

gpart resize -i 4 da0

Passe dabei auf, die richtige Partitionsnummer einzusetzen.

Überprüfe die erfolgreiche Vergrößerung:

gpart show

Jetzt musst du noch das root-Filesystem vergrößern, dazu musst du unterscheiden, ob du ein UFS oder ZFS hast.

Für UFS:

growfs /dev/gpt/rootfs

Und für ZFS:

zpool online -e zroot da0p4

Hierbei auch wieder aufpassen wegen der Platte und Partition. da0p4 in meinem Fall heißt einfach Platte da0 und Partition 4

Das war’s auch schon 🙂

Falls du noch passende Hardware suchst um deine OPNsense aus der Virtualisierung zu befreien, dann schau doch mal meine Amazon-Links an. Falls etwas für dich dabei ist, würde ich mich freuen wenn du es über meinen Link bestellst, dir entstehen dabei keinerlei Mehrkosten und ich erhalte einen kleinen Anteil von Amazon.

Veröffentlicht unter Firewall, OPNsense, Virtualisierung | Kommentare deaktiviert für OPNsense VM Platte voll?

Synology Let’s Encrypt DNS-Challenge mit IPv64

SSL-Zertifikate?

Secure Socket Layer (SSL)-Zertifikate sind das, was dein Browser verwendet, um eine Website sicher zu kontaktieren und Benutzernamen, Passwörter, Kreditkartendaten usw. zu schützen. Auf den Synology-Geräten ist standardmäßig ein „self-signed“ Zertifikat installiert. Diese bieten zwar Sicherheit, aber der Webbrowser beschwert sich darüber und man muss verschiedene Schaltflächen/Links anklicken, um zur Website zu gelangen. Fragt man nahezu jeden Enterprise-Administrator nach dieser Unannehmlichkeit, sind selbstsignierte SSL-Zertifikate ein alter Hut – sie finden sich in zahlreichen Administrations-Tools. Für einen Endnutzer wirkt es jedoch nicht sonderlich vertrauenserweckend, wenn er Fehlermeldungen wegklicken muss, um auf ein System zuzugreifen, das wichtige und potenziell sensible Daten enthält.

Synology DiskStation DS224+ 2 Bay Dekstop NAS DS224+ ohne HDD
  • Centralized Data Storage – Consolidate all your data for complete data ownership and multi-platform access
  • Sharing and Syncing Across Systems – Access, share, and sync data across different systems and devices using intuitive controls
  • Powerful Backup and Restoration – Back up and restore critical devices and data using a host of intuitive backup tools
  • Built-in Data Management Tools – Leverage built-in file and photo management, data protection, and video surveillance solutions

Es GIBT zwar eine eingebaute Methode, ein gültiges SSL-Zertifikat auf einem Synology-Gerät zu bekommen, doch sie hat einen entscheidenden Nachteil: Dein Synology-Gerät muss dafür auf den Ports 80 und 443 über das öffentliche Internet erreichbar sein ODER du musst den Synology-DDNS-Service nutzen. Für manche Nutzer ist das vielleicht kein großes Problem, aber ich glaube nicht, dass die Mehrheit ihr Synology-Gerät öffentlich zugänglich machen oder eine merkwürdige URL (z. B. DeviceName.synology.me) verwenden möchte, um auf die Daten zuzugreifen.

Die Lösung?

Let’s Encrypt stellt kostenlose SSL-Zertifikate zur Verfügung, und acmesh (https://github.com/acmesh-official/acme.sh) bietet ein Skript, das genutzt werden kann, ohne dass Port 80 und 443 für das öffentliche Internet offen sind.

Wo ist der Haken?

Nun ja, ein bisschen gibt es da schon. Du brauchst eine Domain bei einem Registrar, der eine Programmierschnittstelle (API) bereitstellt, um bestimmte Einträge zu aktualisieren. acme.sh unterstützt auch https://IPv64.net – yay! Andere Anbieter sollten ebenfalls problemlos funktionieren, und das meiste in diesem Beitrag sollte auch für sie passen. Getestet habe ich allerdings nur mit IPv64. Deine Ergebnisse können variieren („YMMV“).

Wo fängt man an?

Als Erstes: Stell sicher, dass du einen Domainnamen bei deinem bevorzugten Registrar oder DynDNS-Anbieter (IPv64 in meinem Fall) registriert hast und beschaffe dir den API-Key. Bei IPv64 kannst du dir den API-Key in deiner Domainübersicht (für die Domain zu der das Zertifikat dann erstellt werden soll) besorgen, er steht auf der rechten Seite und kann dort kopiert werden. Sobald du den API-Key hast, kann es losgehen!

Erstelle einen Benutzer in Synology DSM

Melde dich bei deinem Synology-Gerät an, klicke auf „Systemsteuerung“ und dann auf „Benutzer und Gruppe“. Klicke auf „Erstellen“. Ich habe den Benutzernamen „certadmin“ gewählt und eine entsprechende Beschreibung hinzugefügt. Der Benutzer muss Mitglied der Gruppe „administrators“ sein (das ist erforderlich für den SSH-Zugriff, den wir gleich nutzen werden) und außerdem in der Gruppe „http“ (das ist nötig, damit sich der Prozess im SSH-Session-Kontext bei DSM authentifizieren kann). Der Benutzer „certadmin“ benötigt nur Lese-/Schreibzugriff auf den Ordner „homes“ und du kannst den Zugriff auf alle Anwendungen verweigern. Wenn du den Benutzer erstellt hast, gehe zurück zur „Systemsteuerung“, klicke auf „Terminal & SNMP“ und setze ein Häkchen bei „SSH-Dienst aktivieren“. Klicke auf „Übernehmen“.

Jetzt wird’s spannend!

Wahrscheinlich bist du hier, um eine Anleitung zu bekommen und nicht, um meine ganzen Erklärungen zu lesen – also los!

Verwende einen SSH-Client (z. B. https://www.putty.org für Windows; unter Linux ist SSH standardmäßig verfügbar). Wenn du Putty nutzt, gib dort die IP-Adresse oder den Hostnamen deines Synology-Geräts ein, wähle SSH und klicke auf „Open“. Es erscheint eine Sicherheitswarnung, die du mit „Yes“ bestätigen kannst. Anschließend wirst du nach dem Benutzernamen gefragt („certadmin“ in meinem Fall). Unter macOS oder Linux öffnest du ein Terminal und gibst Folgendes ein:

ssh certadmin@DEINHOSTODERIPADRESSE

Wenn du die Sicherheitswarnung bestätigst, wirst du nach deinem Passwort gefragt. Gib das Passwort ein, das du oben für den Synology-Benutzer festgelegt hast (bei der Eingabe erscheint möglicherweise kein Text) und drücke Enter. Lass dich nicht von der SSH-Sitzung abschrecken – die Kommandozeile ist dein Freund!

Die folgenden Befehle (kopiere sie nacheinander, wenn du möchtest) laden das Skript herunter, entpacken die ZIP-Datei, verschieben die Dateien in einen anderen Ordner, übertragen den Besitz der Dateien an den neuen Benutzer und wechseln in das richtige Verzeichnis. Jeder dieser Befehle sollte in einer einzelnen Zeile ausgeführt werden. Die meisten Befehle stammen aus https://www.driscocity.com/synology-dsm-6-2-lets-encrypt-dns-challenge-route53/.

wget -O /tmp/acme.sh.zip https://github.com/acmesh-official/acme.sh/archive/master.zip
(==> da ist kein Zeilenumbruch, die Zeile wurde nur zu lang)

sudo 7z x -o/usr/local/share /tmp/acme.sh.zip

sudo mv /usr/local/share/acme.sh-master/ /usr/local/share/acme.sh

sudo chown -R certadmin /usr/local/share/acme.sh/

cd /usr/local/share/acme.sh

Nun haben wir die notwendigen Dateien. Jetzt müssen wir ein paar Variablen anlegen, damit das Skript funktioniert. Ersetze die Platzhalter unbedingt durch deine eigenen Informationen!

export IPv64_Token="DEIN_GODADDY_KEY"
export SYNO_Username="certadmin"
export SYNO_Password="DEIN_CERTADMIN_PASSWORT"
export SYNO_Certificate="Let's Encrypt"
export SYNO_Create=1

Wenn du nicht IPv64 als Domain-Registrar/DynDNS-Provider verwendest, kannst du unter
https://github.com/acmesh-official/acme.sh/wiki/dnsapi nach den entsprechenden export-Befehlen für andere Registrare schauen.

Verwende zum Erstellen des ersten Zertifikats folgenden Befehl. Achte darauf, deinen Domainnamen zu ersetzen!

./acme.sh --server letsencrypt --issue -d "*.DEINEDOMAIN.NAME" --dns dns_ipv64 --home $PWD
(==> auch hier: kein Zeilenumbruch!)

Wenn du einen anderen Registrar verwendest, musst du in der oben genannten Github-Dokumentation nachlesen, welchen Wert du für --dns benötigst.

Der Vorgang dauert ca. eine Minute. Keine Sorge: Auf dem Bildschirm siehst du Ausgaben, die den Fortschritt zeigen. Dieser Prozess erstellt und lädt das Zertifikat zwar auf dein Synology-Gerät, sagt diesem aber noch nicht, dass es verwendet werden soll. Das erledigt folgender Befehl:

./acme.sh -d "*.DEINEDOMAIN.NAME" --deploy --deploy-hook synology_dsm --home $PWD
(==> auch hier: kein Zeilenumbruch!)

Du solltest einige Meldungen sehen, die anzeigen, dass sich das Skript erfolgreich bei deinem Synology-Gerät anmelden konnte, die Zertifikate abruft, sie anwendet und den Webserver neu startet.

Das automatische zuweisen der Zertifikate und der Neustart des HTTP-Servers hat bei mir nicht geklappt, ich musste die Zertifikate manuell im DSM zuordnen. Dazu klickst du in der Systemsteuerung auf „Sicherheit“ und dann „Zertifikat“. Dann klickst du auf die Schaltfläche Einstellungen und ordnest dein neues Zertifikat für alle Dienste zu. Beim klicken auf ok werden die Dienste neu gestartet und das neue Zertifikat ist aktiv.

Wenn du dich jetzt per HTTPS bei deinem Synology anmeldest, solltest du ein gültiges Zertifikat sehen!

Wenn du ein gültiges und funktionierendes SSL-Zertifikat hast, stelle sicher, dass deine Browser es verwenden! Melde dich bei deinem Synology-Gerät an, gehe in die Systemsteuerung und rufe „Anmeldeportal“ auf. Setze ein Häkchen bei „HTTP-Verbindungen automatisch zu HTTPS umleiten“ und klicke auf „Speichern“. Sobald alles nach Wunsch funktioniert, gehe wieder zur Systemsteuerung und deaktiviere unter „Terminal & SNMP“ den SSH-Zugriff. Denk dran: Das Deaktivieren unnötiger Dienste ist ein guter Sicherheitsgrundsatz!

Und was kommt jetzt?

Das Zertifikat ist installiert und funktioniert. Wenn du allerdings prüfst, wirst du feststellen, dass es nur 90 Tage gültig ist. Du kannst es ganz einfach automatisch verlängern, indem du in deinem Synology-Gerät in die Systemsteuerung gehst, den „Aufgabenplaner“ öffnest, auf „Erstellen“ und „Geplante Aufgabe“ klickst und „Benutzerdefiniertes Skript“ auswählst. Gib der Aufgabe einen aussagekräftigen Namen und achte darauf, dass als Benutzer „certadmin“ ausgewählt ist. Plane die Aufgabe so, dass sie täglich ausgeführt wird, und trage im Reiter „Aufgabeneinstellungen“ das benutzerdefinierte Skript ein. In meinem Fall sieht das so aus:

/usr/local/share/acme.sh/acme.sh --renew -d "*.DEINEDOMAIN.NAME" --home /usr/local/share/acme.sh --server letsencrypt
(==> auch hier: kein Zeilenumbruch!)

Das war’s!

Nur ein paar relativ einfache Schritte, und du hast ein gültiges SSL-Zertifikat auf deinem Synology-Gerät, das sich automatisch verlängert, bevor es abläuft.

Quellenangabe

Anleitung gefunden auf:
https://dr-b.io/post/Synology-DSM-7-with-Lets-Encrypt-and-DNS-Challenge

Angepasst für IPv64 und ein wenig bereinigt.

Veröffentlicht unter NAS, Synology | Kommentare deaktiviert für Synology Let’s Encrypt DNS-Challenge mit IPv64

Willkommen auf aibix.io

Veröffentlicht unter Uncategorized | Schreibe einen Kommentar