Zum Inhalt

Kueue auf Kubernetes: 6 Lehren zu GPU-Quotas aus der Praxis

Kueue auf Kubernetes aus Sicht von Pexon: GPU-Quotas pro Team, Cohorts, Fair Sharing, MIG vs. Time-Slicing, warum vLLM nicht in die Queue gehört, Kosten.

Aktualisiert 9 Min. LesezeitGastbeitrag: Pexon ConsultingFakten geprüft am 15. Oktober 2026

Gastbeitrag aus der Praxis: Dieser Artikel stammt von Pexon Consulting, dem Betreiber dieser Seite und selbst Kubernetes-Dienstleister. Er beschreibt eigene Projekte und Erfahrungen und ist nicht Teil unserer neutralen Vergleiche.

TL;DR

Kueue auf Kubernetes beantwortet die Frage, die der Default-Scheduler offen lässt: Welches Team bekommt die knappe GPU, und wer wartet? Wir bei Pexon setzen Kueue vor Training und Batch, schneiden die Karten mit MIG oder Time-Slicing und lassen vLLM bewusst außerhalb der Queue auf einem reservierten Pool laufen. Ohne Team-Label gibt es keinen Schedule.

Warum reicht der Kubernetes-Scheduler für GPUs nicht?

Der Kubernetes-Scheduler platziert Pods, er verteilt kein Budget. Wer zuerst ein Manifest mit nvidia.com/gpu anwendet, hält die Karte, bis der Job endet. Bei drei Teams und einer kleinen GPU-Flotte führt das zu Streit ohne Regel. Kueue legt eine Warteschlange mit Quotas davor und entscheidet, wann ein Job starten darf.

Dieser Beitrag ist ein gekennzeichneter Praxisbericht von Pexon Consulting, dem Betreiber dieser Seite. Wir beschreiben, wie wir GPU-Scheduling auf Kubernetes für Plattform-Teams aufbauen, mit den Zahlen und Grenzen, die wir auf unserer Seite zu GPU-Scheduling mit Kueue veröffentlicht haben. Den Gesamt-Stack aus GPU Operator, vLLM und LiteLLM haben wir im Praxisbericht KI auf Kubernetes betreiben beschrieben; hier geht es nur um die Frage, wer wann die Karte bekommt.

Das Grundproblem steht schon in der Kubernetes-Dokumentation: GPUs werden nur im Abschnitt limits angegeben, Requests und Limits müssen gleich sein. Eine halbe GPU kennt Kubernetes nicht. Das Muster, das wir in Erstgesprächen am häufigsten hören, hat drei Folgen:

Symptom ohne Queue Was dahinter steckt Was Kueue ändert
Der Chat wird langsam Training startet auf derselben Node-Gruppe wie vLLM Training wartet in der Queue, Serving bleibt auf eigenem Pool
Ein Team füllt alles Kein Fair Share, wer zuerst kommt, gewinnt Quota pro Team, Borrowing mit Grenze
Im Audit fehlt die Antwort Niemand weiß, wer die Karte wann hielt Workload-Objekte mit Queue, Priorität und Label

Wie bauen wir die Queue mit Kueue auf?

Kueue kennt drei Objekte: Ein ResourceFlavor beschreibt die GPU-Nodes, eine ClusterQueue hält die Quota, eine LocalQueue im Namespace ist der Eingang für das Team. Wir installieren die aktuelle Version v0.20.1 per Helm, gepinnt, und legen pro Team eine ClusterQueue in einem gemeinsamen Cohort an.

Kueue empfiehlt laut Installationsanleitung Kubernetes 1.34 oder neuer, weil nur diese Versionen offiziell getestet sind. Die Installation, wie wir sie in Git ablegen:

helm install kueue oci://registry.k8s.io/kueue/charts/kueue \
  --version=0.20.1 \
  --namespace kueue-system \
  --create-namespace \
  --wait --timeout 300s
kubectl wait deploy/kueue-controller-manager -nkueue-system --for=condition=available --timeout=5m

Danach folgen die Objekte. Der ResourceFlavor verweist per Node-Label auf den Trainings-Pool und setzt die Toleration für den GPU-Taint automatisch in die Pods. Die ClusterQueue gibt Team A eine Nominal-Quota von zwei GPUs und erlaubt, maximal zwei weitere aus dem Cohort zu leihen. Die Feldnamen folgen der API kueue.x-k8s.io/v1beta2 aus der Kueue-Dokumentation:

apiVersion: kueue.x-k8s.io/v1beta2
kind: ResourceFlavor
metadata:
  name: gpu-training
spec:
  nodeLabels:
    pool: gpu-training
  tolerations:
  - key: nvidia.com/gpu
    operator: Exists
    effect: NoSchedule
---
apiVersion: kueue.x-k8s.io/v1beta2
kind: ClusterQueue
metadata:
  name: team-a-cq
spec:
  namespaceSelector: {}
  cohortName: gpu-flotte
  fairSharing:
    weight: "1"
  preemption:
    reclaimWithinCohort: Any
    withinClusterQueue: LowerPriority
  resourceGroups:
  - coveredResources: ["cpu", "memory", "nvidia.com/gpu"]
    flavors:
    - name: gpu-training
      resources:
      - name: "cpu"
        nominalQuota: 32
      - name: "memory"
        nominalQuota: 256Gi
      - name: "nvidia.com/gpu"
        nominalQuota: 2
        borrowingLimit: 2
---
apiVersion: kueue.x-k8s.io/v1beta2
kind: LocalQueue
metadata:
  namespace: team-a
  name: team-a-queue
spec:
  clusterQueue: team-a-cq

Ein Job landet in der Queue über das Label kueue.x-k8s.io/queue-name: team-a-queue. Den Job muss niemand suspendiert anlegen; Kueue übernimmt das per Webhook und startet ihn, sobald Quota frei ist. CPU und Speicher stehen bewusst in derselben Resource Group wie die GPU, damit alle drei aus demselben Flavor kommen.

Fair Sharing oder klassische Preemption?

Für Teams, die sich eine Flotte dauerhaft teilen, schalten wir Fair Sharing ein. Es ist in Kueue seit v0.7 stabil. Kueue lässt dann die ClusterQueue mit dem niedrigsten gewichteten Anteil zuerst zu und verdrängt bei Engpass zuerst Workloads aus der Queue mit dem höchsten Anteil. Klassische Preemption reicht, wenn Borrowing selten ist.

Die beiden Verfahren unterscheiden sich in einem Punkt, der in der Praxis oft übersehen wird: Laut Kueue-Dokumentation zur Preemption verteilt Classic Preemption geliehene Kapazität nach dem Prinzip “wer zuerst kommt”. Fair Sharing verdrängt dagegen so lange, bis die wartende Queue ihren gleichen oder gewichteten Anteil erreicht hat. Das Feld borrowWithinCohort funktioniert nur mit Classic Preemption, nicht mit Fair Sharing.

Kriterium Classic Preemption Fair Sharing
Verteilung geliehener Quota in Reihenfolge des Eingangs gleicher oder gewichteter Anteil (fairSharing.weight)
Unterbrechungen weniger mehr, bis der Anteil stimmt
borrowWithinCohort möglich nicht möglich
Passt, wenn Teams selten leihen mehrere Teams die Flotte dauerhaft teilen

Fair Sharing wird in der Kueue-Konfiguration aktiviert, nicht in der ClusterQueue:

apiVersion: config.kueue.x-k8s.io/v1beta2
kind: Configuration
fairSharing:
  preemptionStrategies: [LessThanOrEqualToFinalShare, LessThanInitialShare]

Für Prioritäten innerhalb einer Queue nutzen wir eine WorkloadPriorityClass, gesetzt per Label kueue.x-k8s.io/priority-class. Sie wirkt nur auf Kueue und ändert nicht die Pod-Priorität. So kann ein Produktions-Training einen Entwicklungs-Job derselben Queue verdrängen, ohne dass sich am Verhalten des Kubernetes-Schedulers etwas ändert. Wichtig für den Betrieb: Verdrängte Jobs müssen Checkpoints schreiben, sonst verliert das Team Stunden an Rechenzeit.

MIG, Time-Slicing oder volle GPU: Welchen Schnitt wählen wir?

Die Queue entscheidet, wer wartet; der Schnitt entscheidet, wie hart die Karte geteilt wird. MIG teilt eine Datacenter-GPU in bis zu sieben Instanzen mit eigener Speicher- und Fault-Isolation. Time-Slicing teilt weich und ohne diese Isolation. Für Training mit großem Kontext bleibt die volle Karte. Time-Slicing gewinnt nicht automatisch.

Die NVIDIA-Dokumentation zum Time-Slicing ist hier deutlich: Zwischen den Replicas gibt es keine Speicher- und keine Fault-Isolation, und wer mehr als ein Time-Sliced-Replica anfordert, bekommt dafür keinen proportionalen Anteil an Rechenleistung. MIG setzt laut NVIDIA GPUs ab der Ampere-Architektur voraus, etwa die A100. Der aktuelle GPU Operator ist v26.7.2.

Schnitt Was er teilt Isolation Unsere Wahl für
Time-Slicing viele kleine Workloads auf einer Karte keine Speicher- oder Fault-Isolation Entwicklung, kleine Inferenz, Latenz darf schwanken
MIG bis zu 7 Hardware-Instanzen pro GPU Speicher und Faults getrennt mehrere Teams, die Isolation nachweisen müssen
Volle GPU eine Karte, ein Job maximal Training, großer Kontext

So schalten wir Time-Slicing für einen Entwicklungs-Pool mit vier Replicas pro GPU. Die ConfigMap stammt aus dem NVIDIA-Beispiel:

apiVersion: v1
kind: ConfigMap
metadata:
  name: time-slicing-config
data:
  any: |-
    version: v1
    flags:
      migStrategy: none
    sharing:
      timeSlicing:
        renameByDefault: false
        failRequestsGreaterThanOne: false
        resources:
        - name: nvidia.com/gpu
          replicas: 4

Ein Knoten mit zwei GPUs meldet danach acht GPUs. Genau hier liegt eine Falle für die Quota: Kueue zählt nvidia.com/gpu so, wie der Node es meldet. Eine Quota von “4 GPUs” bedeutet auf einem Time-Sliced-Pool vier Replicas, also eine physische Karte. Wir führen deshalb für jeden Schnitt einen eigenen ResourceFlavor, damit Quota und Hardware in derselben Einheit bleiben.

Warum gehört vLLM nicht in die Queue?

Weil Inferenz ein dauerhaft laufendes Deployment ist und kein Job mit Ende. Wer den Chat durch Kueue schickt, kauft Fairness mit Wartezeit: Der Endpunkt startet erst, wenn Quota frei ist, und kann verdrängt werden. Wir reservieren für vLLM einen eigenen Node-Pool und halten Training per Queue davon fern.

Unsere Trennung hat zwei Schichten. Das Gateway, bei uns LiteLLM, wählt das Modell und rechnet Tokens pro Team ab. Die Queue wählt die Karte für Training und Batch-Auswertungen. Beide berühren sich nicht. In der Praxis heißt das: Der vLLM-Pool trägt einen eigenen Taint, den nur die Serving-Deployments tolerieren, und der ResourceFlavor der Queue zeigt ausschließlich auf den Trainings-Pool. So verdrängt kein nächtliches Fine-Tuning-Experiment eines Teams den Chat, den Kunden am Morgen nutzen.

Die Reihenfolge, in der wir einen Pilot aufsetzen:

  1. Flotte und Jobs sehen: Welche GPUs gibt es, welche Teams nutzen sie, läuft vLLM schon auf denselben Nodes?
  2. Schnitt wählen: Time-Slicing, MIG oder volle Karte, pro Pool, Tabelle zuerst.
  3. Quota setzen: Budget pro Team, Pflicht-Label für Team, Modell und Datenklasse, Fair Sharing.
  4. Serving trennen: Inferenz-Pool reservieren, Training in die Queue.
  5. Nachweis schreiben: Wer hielt die Karte, welches Modell, wo lag der Checkpoint?
  6. Betrieb anbinden: Servicezeit Montag bis Freitag, 08:00 bis 18:00 Uhr MEZ. Nachts wartet die Quota, kein Bereitschaftsdienst.

Schritt 5 ist der, den regulierte Kunden zuerst fragen. Ein Job ohne Team- oder Modell-Label bleibt bei uns in der Queue oder fällt bei der Admission durch. Dieselbe Logik eines lückenlosen Nachweises beschreiben wir für Banken im Praxisbericht Kubernetes in Banken.

Was kostet GPU-Scheduling mit Pexon?

Der Einstieg ist eine Architektur-Sprechstunde für 450 € Festpreis, 90 Minuten. Der Umsetzungs-Pilot für einen GPU-Cluster kostet ab 14.500 € und dauert sechs Wochen: Kueue, Labels, Schnitt, Nachweis. Ein Foundation-Aufbau beginnt bei 30.000 €. GPU-Kauf und 24/7-Betrieb sind nicht enthalten.

Alle Preise stammen von unserer Seite zum GPU-Scheduling, Stand 15.10.2026, netto. Der Pilot läuft so:

Phase Dauer Inhalt
Sprechstunde 90 Minuten Queue, Schnitt, ob vLLM überhaupt durch Kueue darf, 450 €
Bestand Woche 1 bis 2 GPUs, Teams, ob Inferenz auf denselben Nodes läuft
Queue Woche 3 bis 5 Kueue, Labels, MIG oder Time-Slicing, Serving-Pool
Übergabe Woche 6 Nachweis, Auslastung vorher und nachher oder bewusst keine Zahl

Was wir nicht versprechen: eine automatische Senkung der GPU-Kosten um zwei Drittel. Im Markt kursieren Zahlen wie 69 Prozent Überprovisionierung; das ist nicht unsere Messung. Kosten sinken, wenn Leerlauf sinkt, und das zeigen wir am Cluster selbst, vorher und nachher, oder wir lassen die Zahl weg. Wenn statt eines einzelnen Piloten der laufende Betrieb der ganzen KI-Plattform gefragt ist, liegt der bei uns bei 5.000 bis 10.000 € im Monat, wie auf unserer Seite KI-Plattform-Betrieb beschrieben. Welche Managed-Kubernetes-Angebote in deutschen Regionen den Unterbau stellen, zeigt der Vergleich Managed Kubernetes Deutschland.

Die 6 Lehren im Überblick

Kurz gesagt: Eine Queue vor der Karte, ein eigener Flavor pro Schnitt, Fair Sharing für geteilte Flotten, Serving außerhalb der Queue, Pflicht-Labels für den Nachweis und keine Kostenzahl ohne eigene Messung. Diese sechs Punkte prüfen wir in jedem GPU-Projekt, bevor wir über zusätzliche Hardware sprechen.

  1. Queue vor der Karte. Ohne Kueue gewinnt das erste Manifest, nicht die wichtigste Aufgabe.
  2. Ein Flavor pro Schnitt. Time-Sliced-Replicas und volle GPUs nie in derselben Quota zählen.
  3. Fair Sharing für geteilte Flotten. Gewichte pro Team statt Absprachen im Chat.
  4. Serving bleibt draußen. vLLM auf reserviertem Pool, Training und Batch in die Queue.
  5. Kein Label, kein Schedule. Team, Modell und Datenklasse sind Pflicht, sonst fehlt der Nachweis.
  6. Zahl nur vom Cluster. Auslastung vorher und nachher messen, keine Branchenzahl übernehmen.

FAQ

Was kostet die Einführung von Kueue mit Pexon?

Die Architektur-Sprechstunde kostet 450 € für 90 Minuten, der Pilot für einen GPU-Cluster ab 14.500 € über sechs Wochen, ein Foundation-Aufbau ab 30.000 €, jeweils netto, Stand 15.10.2026. Der Endpreis hängt davon ab, ob mehrere Pools oder ein Hardware-Kauf dazukommen.

Kueue vs. Kubernetes-Scheduler: Was ist der Unterschied?

Der Kubernetes-Scheduler entscheidet, auf welchem Node ein Pod läuft. Kueue entscheidet vorher, ob ein Job überhaupt starten darf, abhängig von Quota, Priorität und Fair Share. Kueue ersetzt den Scheduler nicht, sondern hält Jobs suspendiert, bis Kapazität im Budget des Teams frei ist.

MIG vs. Time-Slicing: Was nehmen wir für mehrere Teams?

MIG, sobald Teams Isolation nachweisen müssen. MIG teilt eine Datacenter-GPU ab Ampere in bis zu sieben Instanzen mit eigener Speicher- und Fault-Isolation. Time-Slicing teilt ohne diese Isolation und passt für Entwicklung und kleine Inferenz, bei der die Latenz schwanken darf.

Welche Kubernetes-Version braucht Kueue?

Die Kueue-Dokumentation empfiehlt Kubernetes 1.34 oder neuer, weil nur diese Versionen offiziell unterstützt und getestet sind. Aktuell ist Kueue v0.20.1 mit der API kueue.x-k8s.io/v1beta2. Installiert wird per kubectl apply --server-side oder per Helm-Chart aus registry.k8s.io.

Sollen Inferenz-Endpunkte wie vLLM durch Kueue laufen?

Meist nein. vLLM läuft als Deployment auf einem reservierten Pool. Ein Endpunkt in der Queue startet erst bei freier Quota und kann verdrängt werden, was Kunden als Ausfall erleben. Kueue hält Training und Batch-Auswertungen vom Serving-Pool fern.

Senkt Kueue die GPU-Kosten automatisch?

Nein. Kueue senkt Leerlauf nur, wenn Quotas, Schnitt und Labels sitzen und die Teams ihre Limits einhalten. Wir zeigen die Auslastung am eigenen Cluster vorher und nachher. Pauschale Branchenzahlen zu Überprovisionierung übernehmen wir nicht.

Quellen

  1. Pexon: GPU-Scheduling auf Kubernetes mit Kueue (abgerufen 15. Oktober 2026)
  2. Pexon: KI-Plattform-Betrieb auf Kubernetes (abgerufen 15. Oktober 2026)
  3. Kueue Docs: Installation (abgerufen 15. Oktober 2026)
  4. Kueue Docs: Administer Cluster Quotas (abgerufen 15. Oktober 2026)
  5. Kueue Docs: Cluster Queue (abgerufen 15. Oktober 2026)
  6. Kueue Docs: Resource Flavor (abgerufen 15. Oktober 2026)
  7. Kueue Docs: Preemption und Fair Sharing (abgerufen 15. Oktober 2026)
  8. Kueue Docs: Workload Priority Class (abgerufen 15. Oktober 2026)
  9. Kueue Docs: Run Jobs (abgerufen 15. Oktober 2026)
  10. NVIDIA GPU Operator: Time-Slicing GPUs in Kubernetes (abgerufen 15. Oktober 2026)
  11. NVIDIA GPU Operator: MIG Support (abgerufen 15. Oktober 2026)
  12. NVIDIA: Multi-Instance GPU (abgerufen 15. Oktober 2026)
  13. Kubernetes Docs: Schedule GPUs (abgerufen 15. Oktober 2026)

Weiterlesen