Kubernetes GPU Scheduling: DRA, Device Plugins und CDI verständlich erklärt
Kubernetes GPU Scheduling bezeichnet die deklarative Zuweisung von Grafikprozessoren und anderen Beschleunigern an Pods. Dabei entscheidet der Scheduler nicht nur, welcher Node technisch passt, sondern auch, wie GPUs per Bin-Packing ausgelastet, über ResourceClaims angefordert und unabhängig von herstellerspezifischen Container-Details bereitgestellt werden.
- Exklusive NVIDIA H200 GPUs für höchste Rechenleistung
- Garantierte Performance durch vollständig dedizierte CPU-Kerne
- 100 % Hosting in Deutschland für maximale Datensicherheit und DSGVO-Konformität
- Einfaches, kalkulierbares Preismodell mit festem Preis pro Stunde
Was ist Kubernetes GPU Scheduling?
Ein Kubernetes-Cluster besteht aus mehreren Servern, die als Nodes bezeichnet werden. Auf diesen Nodes führt Kubernetes Anwendungen in sogenannten Pods aus. Benötigt eine Anwendung eine GPU, muss Kubernetes einen Node auswählen, auf dem eine passende und noch verfügbare GPU vorhanden ist. Diese Entscheidung übernimmt der Kubernetes Scheduler. Er prüft zunächst, welche Nodes die Anforderungen des Pods erfüllen. Anschließend bewertet er die geeigneten Nodes und wählt den am besten passenden aus.
Beim klassischen GPU Scheduling sieht Kubernetes eine GPU im Wesentlichen als zählbare Ressource. Ein Pod fordert beispielsweise eine Einheit der Ressource nvidia.com/gpu an. Kubernetes weiß dann zwar, dass der Pod eine NVIDIA-GPU benötigt, kann über diesen einfachen Mechanismus aber nur begrenzt ausdrücken, welches Modell oder welche Konfiguration benötigt wird.
Dynamic Resource Allocation, kurz DRA, erweitert dieses Modell. Statt lediglich „eine GPU“ anzufordern, kann eine Anwendung beispielsweise eine GPU der Blackwell-Generation, eine bestimmte Speicherkapazität oder eine bestimmte MIG-Konfiguration verlangen.
Device Plugin, MIG und DRA im Vergleich
Für die Zuweisung von GPUs stehen mehrere Verfahren zur Verfügung. Sie schließen sich nicht grundsätzlich gegenseitig aus: MIG beschreibt beispielsweise eine Aufteilung der Hardware, während Device Plugins und DRA bestimmen, wie Kubernetes diese Hardware verwaltet und Pods zuweist.
| Methode | Mechanismus | Vorteil | Best Use Case |
|---|---|---|---|
| Device Plugin | GPUs werden als ganzzahlige Extended Resource am Node registriert. Ein Pod fordert eine oder mehrere Einheiten an. | Bewährtes, einfaches Verfahren mit breiter Unterstützung | Bestehende oder homogene Cluster, in denen überwiegend vollständige GPUs benötigt werden |
| MIG: GPU Slicing | Eine unterstützte physische GPU wird in mehrere voneinander getrennte GPU-Instanzen aufgeteilt. | Bessere Auslastung großer GPUs und stärkere Isolation als einfaches Time-Slicing | Inferenz, kleinere Trainingsjobs und Multi-Tenant-Cluster |
| DRA: neuer Standard | Geräte werden über ResourceSlices beschrieben, über DeviceClasses kategorisiert und mit ResourceClaims angefordert. CEL-Ausdrücke filtern nach Modell, Speicher oder Architektur. | Präzise Hardwareauswahl, dynamische Konfiguration, Sharing und bessere Hardwareabstraktion | Heterogene GPU-Cluster, NVIDIA-Blackwell-Systeme und anspruchsvolle MLOps-Plattformen |
DRA arbeitet mit drei zentralen Kubernetes-Objekten. Sie beschreiben, welche Geräte im Cluster vorhanden sind und welche Hardware ein Pod benötigt:
| DRA-Objekt | Aufgabe |
|---|---|
| ResourceSlice | Zeigt Kubernetes, welche GPUs und anderen Geräte auf den Nodes verfügbar sind |
| DeviceClass | Fasst passende Geräte anhand von Eigenschaften wie Modell oder Architektur zusammen |
| ResourceClaim | Fordert für einen Pod ein Gerät aus einer DeviceClass an |
Der NVIDIA-DRA-Treiber erstellt die ResourceSlices automatisch und installiert bei aktiviertem GPU-Support auch die Standardklassen gpu.nvidia.com und mig.nvidia.com. Zusätzliche, genauer zugeschnittene DeviceClasses, beispielsweise für eine B200, kann die Cluster-Administration selbst definieren. Anwendungen fordern die gewünschte GPU anschließend über ResourceClaims an.
So trifft Kubernetes eine GPU-Scheduling-Entscheidung
Eine Scheduling-Entscheidung besteht vereinfacht aus zwei Phasen: Filtern und Bewerten.
Beim Filtern entfernt Kubernetes alle Nodes, die den Pod nicht ausführen können. Gründe können fehlender Arbeitsspeicher, eine nicht verfügbare GPU, ein unpassendes GPU-Modell, Node Taints oder nicht erfüllte Affinity-Regeln sein. Danach bewertet der Scheduler die verbleibenden Nodes. Der Node mit der höchsten Bewertung wird ausgewählt. Diese Bewertung kann beispielsweise darauf ausgerichtet werden, Anwendungen möglichst gleichmäßig zu verteilen oder vorhandene Nodes möglichst stark zu füllen.
Bei DRA kommt zusätzlich die Geräteauswahl hinzu:
- Der NVIDIA-DRA-Treiber erkennt die GPUs auf jedem Node.
- Er veröffentlicht die verfügbaren Geräte als ResourceSlices.
- Eine DeviceClass beschreibt, welche Geräte zu einer bestimmten Kategorie gehören.
- Ein ResourceClaim beschreibt, welches Gerät eine Anwendung benötigt.
- Der Scheduler sucht nach einer passenden GPU und einem Node, auf dem diese GPU erreichbar ist.
- Der DRA-Treiber bereitet das ausgewählte Gerät für den Pod vor.
- Die Container-Runtime stellt die GPU über CDI im Container bereit.
Was bedeutet Bin-Packing bei GPU-Clustern?
Beim Bin-Packing versucht Kubernetes, GPU-Workloads möglichst kompakt auf vorhandenen Nodes unterzubringen. Dadurch können einzelne Server besser ausgelastet und andere Nodes für größere Jobs freigehalten oder abgeschaltet werden. Der Scheduler bewertet dabei jedoch die angeforderten Ressourcen und nicht die tatsächliche GPU-Auslastung. Für deren Überwachung ist zusätzliches Monitoring erforderlich. Bei Multi-GPU-Workloads sollten außerdem NVLink-, PCIe- und NUMA-Topologien berücksichtigt werden, da eine möglichst dichte Verteilung nicht automatisch die beste Leistung bietet.
Welche Rolle spielt CDI bei NVIDIA Blackwell?
CDI steht für Container Device Interface und standardisiert, wie eine ausgewählte GPU in einen Container eingebunden wird. DRA entscheidet dabei, welche GPU ein Pod erhält. CDI sorgt anschließend dafür, dass das Gerät samt benötigter Zugänge, Bibliotheken und Einstellungen im Container verfügbar ist.
Beim NVIDIA GPU Operator ist CDI standardmäßig aktiviert und arbeitet mit Container-Runtimes wie containerd oder CRI-O zusammen. Für Blackwell-Systeme ist das besonders hilfreich, weil unterschiedliche GPU-Modelle und MIG-Konfigurationen einheitlich bereitgestellt werden können.
Tutorial: NVIDIA-GPUs mit DRA in Kubernetes zuweisen
Das folgende Tutorial zeigt eine vollständige DRA-Zuweisung für eine NVIDIA B200. Sie installieren zunächst den GPU Operator ohne klassisches Device Plugin, richten anschließend den DRA-Treiber ein und erstellen dann eine eigene DeviceClass sowie einen ResourceClaim.
IONOS CLOUD Managed Kubernetes ist die ideale Plattform für performante und hochskalierbare Container-Anwendungen – rund um die Uhr professionell betreut. Ab sofort profitieren Sie von einer automatischen CPU-Zuweisung für Dedicated Cores und kosteneffizienten vCPUs für weniger performance-intensive Workloads. So nutzen Sie Ihre Ressourcen optimal, senken Kosten und behalten jederzeit volle Kontrolle über Ihre Anwendungsperformance.
Voraussetzungen
Für den beschriebenen Aufbau empfiehlt sich Kubernetes 1.34 oder neuer.
Zusätzlich benötigen Sie:
- mindestens einen Kubernetes-Node mit unterstützter NVIDIA-GPU,
- Administratorrechte im Cluster,
- ein konfiguriertes
kubectl, - Helm 3,
- containerd oder CRI-O als Container-Runtime und
- Zugriff auf die NVIDIA-Helm-Charts.
Schritt 1: GPU Operator und DRA-Treiber mit Helm installieren
Zunächst müssen Sie festlegen, auf welchen Nodes der DRA-Kubelet-Plugin-Pod ausgeführt werden soll. Lassen Sie sich die Namen Ihrer Nodes anzeigen:
kubectl get nodesbashKennzeichnen Sie anschließend jeden GPU-Node. Ersetzen Sie <GPU-NODE> durch den tatsächlichen Namen:
kubectl label node <GPU-NODE> nvidia.com/dra-kubelet-plugin=truebashDie Kennzeichnung ist erforderlich, damit der NVIDIA Driver Manager den DRA-Kubelet-Plugin-Pod bei Treiberaktualisierungen korrekt behandeln kann.
Fügen Sie danach das NVIDIA-Helm-Repository hinzu:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo updatebashInstallieren Sie nun den GPU Operator. Der entscheidende Parameter ist devicePlugin.enabled=false. Damit deaktivieren Sie das klassische NVIDIA Kubernetes Device Plugin und vermeiden, dass Device Plugin und DRA-Treiber dieselben GPUs gleichzeitig verwalten.
helm upgrade --install gpu-operator nvidia/gpu-operator \
--version=v26.3.3 \
--create-namespace \
--namespace gpu-operator \
--set devicePlugin.enabled=false \
--set 'driver.manager.env[0].name=NODE_LABEL_FOR_GPU_POD_EVICTION' \
--set 'driver.manager.env[0].value=nvidia.com/dra-kubelet-plugin'bashDas Deaktivieren des Device Plugins allein aktiviert DRA noch nicht. Der DRA-Treiber wird weiterhin über ein eigenes Helm-Chart installiert.
Erstellen Sie dafür die Datei dra-values.yaml mit folgendem Inhalt:
image:
pullPolicy: IfNotPresent
kubeletPlugin:
nodeSelector:
nvidia.com/dra-kubelet-plugin: "true"Installieren Sie anschließend den NVIDIA-DRA-Treiber:
helm upgrade --install dra-driver-nvidia-gpu \
nvidia/dra-driver-nvidia-gpu \
--version=0.4.1 \
--namespace nvidia-dra-driver-gpu \
--create-namespace \
--set nvidiaDriverRoot=/run/nvidia/driver \
--set gpuResourcesEnabledOverride=true \
-f dra-values.yamlbashPrüfen Sie danach, ob die Pods des Treibers laufen:
kubectl get pods -n nvidia-dra-driver-gpubashAbhängig von der aktivierten Konfiguration sollte die Ausgabe ungefähr so aussehen:
NAME READY STATUS
dra-driver-nvidia-gpu-controller-... 1/1 Running
dra-driver-nvidia-gpu-kubelet-plugin-... 2/2 RunningKontrollieren Sie außerdem die automatisch angelegten DeviceClasses:
kubectl get deviceclassbashFür die GPU-Zuweisung sollten mindestens die folgenden Klassen vorhanden sein:
gpu.nvidia.com
mig.nvidia.combashBei aktiviertem ComputeDomain-Support erscheinen zusätzliche Klassen für Multi-Node NVLink. Prüfen Sie abschließend, ob der Treiber die GPUs als ResourceSlices veröffentlicht:
kubectl get resourceslice -o widebashWenn keine ResourceSlices für gpu.nvidia.com erscheinen, kann Kubernetes noch keine GPU über DRA zuweisen.
Schritt 2: DeviceClass für NVIDIA B200 definieren
Der NVIDIA-DRA-Treiber legt bereits die allgemeine DeviceClass gpu.nvidia.com an. Diese umfasst vollständige NVIDIA-GPUs unterschiedlicher Modelle. Für einen heterogenen Cluster können Sie zusätzlich eine eigene Klasse erstellen, die ausschließlich B200-GPUs auswählt.
Sehen Sie sich zunächst die vom Treiber gemeldeten Produktnamen an:
kubectl get resourceslice -o yamlbashSuchen Sie in der Ausgabe nach productName. Die genaue Bezeichnung hängt von Hardware, Treiber und Systemvariante ab. Der folgende reguläre Ausdruck sucht deshalb nicht nach einer vollständig identischen Zeichenfolge, sondern nach dem Bestandteil B200.
Erstellen Sie die Datei b200-deviceclass.yaml:
apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
name: b200.gpu.nvidia.com
spec:
selectors:
- cel:
expression: |
device.driver == 'gpu.nvidia.com' &&
device.attributes['gpu.nvidia.com'].type == 'gpu' &&
device.attributes['gpu.nvidia.com'].productName
.lowerAscii()
.matches('^.*b200.*$')Der Ausdruck enthält drei Bedingungen:
- Das Gerät muss vom NVIDIA-GPU-DRA-Treiber stammen.
- Es muss sich um eine vollständige GPU und nicht um eine MIG-Instanz handeln.
- Der gemeldete Produktname muss
B200enthalten.
Wenden Sie die Datei an:
kubectl apply -f b200-deviceclass.yamlbashKontrollieren Sie die DeviceClass:
kubectl describe deviceclass b200.gpu.nvidia.combashEine DeviceClass reserviert noch keine GPU. Sie definiert lediglich den Gerätepool, aus dem spätere Claims auswählen dürfen.
Schritt 3: ResourceClaim und Pod erstellen
Erstellen Sie zunächst einen eigenen Namespace für den Test:
kubectl create namespace gpu-examplebashDanach erstellen Sie einen ResourceClaim. Speichern Sie den folgenden Inhalt als b200-resourceclaim.yaml:
apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
name: b200-claim
namespace: gpu-example
spec:
devices:
requests:
- name: b200
exactly:
deviceClassName: b200.gpu.nvidia.comOhne weitere Mengenangabe fordert dieser Claim genau ein passendes Gerät an.
Erstellen Sie den ResourceClaim:
kubectl apply -f b200-resourceclaim.yamlbashDer Claim wird normalerweise erst vollständig zugewiesen, wenn ein Pod ihn verwendet. Kubernetes muss schließlich nicht nur eine freie GPU, sondern auch einen dazu passenden Node auswählen.
Erstellen Sie nun die Datei b200-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: b200-test
namespace: gpu-example
spec:
restartPolicy: Never
containers:
- name: gpu-test
image: ubuntu:22.04
command:
- bash
- -c
- |
nvidia-smi -L
sleep 3600
resources:
claims:
- name: gpu
resourceClaims:
- name: gpu
resourceClaimName: b200-claim
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoScheduleIm Pod taucht der Claim an zwei Stellen auf:
- Unter
spec.resourceClaimswird der vorhandene ResourceClaim für den Pod verfügbar gemacht:
resourceClaims:
- name: gpu
resourceClaimName: b200-claim- Unter
containers[].resources.claimswird festgelegt, welcher Container das Gerät verwenden darf:
resources:
claims:
- name: gpuDiese Trennung ermöglicht es, einen Claim gezielt einem oder mehreren Containern im Pod bereitzustellen. Mehrere Container können denselben Claim referenzieren und dadurch dieselbe GPU sehen.
Erstellen Sie den Pod:
kubectl apply -f b200-pod.yamlbashSchritt 4: GPU-Zuweisung mit kubectl validieren
Prüfen Sie zunächst den allgemeinen Pod-Status:
kubectl get pod b200-test -n gpu-example -o widebashDer Pod sollte nach erfolgreicher Zuweisung den Status Running erhalten. In der Spalte NODE sehen Sie, auf welchem GPU-Node er ausgeführt wird.
Rufen Sie anschließend die ausführliche Beschreibung ab:
kubectl describe pod b200-test -n gpu-examplebashAchten Sie insbesondere auf folgende Bereiche:
- Node: Zeigt den ausgewählten GPU-Node.
- Resource Claims: Zeigt den vom Pod verwendeten Claim.
- Containers: Zeigt, welcher Container auf den Claim zugreift.
- Events: Enthält Fehlermeldungen, falls kein passendes Gerät gefunden wurde.
Bleibt der Pod im Status Pending, finden Sie unter Events in aller Regel einen Hinweis auf die Ursache, etwa einen nicht zuweisbare ResourceClaim oder ein fehlendes passendes Gerät.
Prüfen Sie anschließend den ResourceClaim:
kubectl get resourceclaim b200-claim \
-n gpu-example \
-o yamlbashUnter status.allocation.devices.results sollte die zugewiesene GPU erscheinen. Kontrollieren Sie abschließend, ob die GPU im Container verfügbar ist:
kubectl exec -n gpu-example b200-test -- nvidia-smi -LbashEine erfolgreiche Ausgabe kann beispielsweise so aussehen:
GPU 0: NVIDIA B200 (UUID: GPU-...)Damit ist bestätigt, dass Kubernetes eine passende B200 ausgewählt und über CDI im Container bereitgestellt hat.
Häufige Fehler beim Kubernetes GPU Scheduling mit DRA
Der Pod bleibt im Status Pending
Prüfen Sie zunächst die Pod-Events und den ResourceClaim:
kubectl describe pod b200-test -n gpu-example
kubectl describe resourceclaim b200-claim -n gpu-examplebashFehlt eine passende GPU, kontrollieren Sie die veröffentlichten Geräte und deren Produktnamen:
kubectl get resourceslice -o yamlbashEs werden keine ResourceSlices angezeigt
Prüfen Sie, ob die Pods des DRA-Treibers laufen:
kubectl get pods -n nvidia-dra-driver-gpubashBei Fehlern helfen die Logs des Kubelet-Plugins:
kubectl logs \
-n nvidia-dra-driver-gpu \
<NAME-DES-KUBELET-PLUGIN-PODS> \
-c gpusbashHäufige Ursachen sind ein falscher nvidiaDriverRoot, fehlende Node Labels oder nicht erkannte GPUs.
Der B200-Selektor findet kein Gerät
Vergleichen Sie den verwendeten productName mit dem Eintrag in der ResourceSlice. Zum Test können Sie den Selektor vorübergehend auf alle vollständigen NVIDIA-GPUs erweitern:
expression: |
device.driver == 'gpu.nvidia.com' &&
device.attributes['gpu.nvidia.com'].type == 'gpu'bashFunktioniert die Zuweisung damit, liegt der Fehler wahrscheinlich im Modellselektor.
Das klassische Device Plugin sollte im DRA-Modus deaktiviert sein. Außerdem können höher priorisierte Pods bereits belegte DRA-GPUs derzeit nicht automatisch übernehmen.
- Vollständige Kontrolle und maximale Datenhoheit
- Garantierte Verfügbarkeit: >99,95 %
- Dedizierte Performance durch skalierbares 3-Host vSAN
- VMware-Lizenz inklusive
- IONOS CLOUD ist Premium Pinnacle Partner für beste Preise und Support
Best Practices für GPU-Cluster
Verwenden Sie DeviceClasses als Schnittstelle zwischen Anwendungen und Hardware. So müssen Workloads keinen bestimmten Node kennen, sondern können beispielsweise eine B200-GPU oder eine GPU mit besonders viel Speicher anfordern. Filtern Sie außerdem nur dann nach einem konkreten Modell, wenn es technisch notwendig ist. Eine Anforderung wie „mindestens 80 GiB GPU-Speicher“ ist oft flexibler als die feste Auswahl eines bestimmten GPU-Modells.
Nutzen Sie ResourceClaimTemplates für Deployments und Jobs mit mehreren Pods. Direkte ResourceClaims eignen sich dagegen für einzelne Pods oder Ressourcen, die bewusst weiterverwendet werden sollen. Beachten Sie, dass Kubernetes reservierte Ressourcen bewertet, nicht die tatsächliche GPU-Auslastung. Für deren Überwachung benötigen Sie zusätzliches Monitoring, beispielsweise mit dem NVIDIA DCGM Exporter.
Fazit
Kubernetes GPU Scheduling entwickelt sich von einfachen, ganzzahligen GPU-Anforderungen zu einer deklarativen Geräteverwaltung. Das klassische NVIDIA Device Plugin bleibt für bestehende und homogene Cluster eine einfache Lösung. MIG verbessert die Auslastung großer GPUs, indem eine physische GPU in kleinere Instanzen aufgeteilt wird.
Für neue, heterogene GPU-Plattformen bietet DRA jedoch das flexiblere Modell. DeviceClasses abstrahieren die Hardware, ResourceClaims beschreiben den konkreten Bedarf und ResourceSlices liefern dem Scheduler die notwendigen Geräteinformationen. CDI sorgt anschließend dafür, dass die ausgewählte GPU zuverlässig im Container erscheint.
Besonders für NVIDIA-Blackwell-Systeme ist diese Trennung sinnvoll: Eine Anwendung kann gezielt eine B200 anfordern, ohne einen bestimmten Node festzulegen.