Ringkasan Utama
Kubernetes 1.37 meluluskan dukungan DRA Extended Resource ke GA, sehingga Pod yang meminta example.com/gpu: 1 bisa dipenuhi DRA driver tanpa device plugin dan tanpa ResourceClaim di workload. Admin memetakan nama itu sekali lewat extendedResourceName pada DeviceClass, dan node bisa dimigrasi satu per satu.
Pertanyaan yang ingin saya jawab sebelum ada yang menyentuh cluster GPU itu membosankan: kalau vendor merilis DRA driver besok, manifest kita mana yang harus berubah? Selama bertahun-tahun jawaban jujur untuk apa pun yang menyangkut Dynamic Resource Allocation adalah semuanya, karena device plugin membagikan example.com/gpu sebagai counter di level node, sedangkan DRA membagikan device lewat objek ResourceClaim yang harus disebut oleh workload.
Kubernetes 1.37 mengubah jawaban itu. Post ini membaca post rilis DRA v1.37 tanggal 3 September 2026, dokumen desain KEP-5004, halaman konsep, API dan features DRA, halaman device taints, serta KEP-5055 dan KEP-6132, lalu mengubahnya menjadi rencana migrasi. Saya belum menjalankannya di cluster GPU, jadi setiap perilaku di bawah adalah klaim dokumentasi atau KEP dan disebut demikian, dan apa pun yang tidak dipastikan sumbernya saya tandai belum terkonfirmasi.
Apa yang dirilis 1.37 untuk DRA, per stage
Intinya, dukungan DRA Extended Resource sudah GA. Post rilis menyebut tim membangunnya selama tiga rilis berturut-turut, dan halaman task di docs menandainya Stable sejak Kubernetes v1.37 serta aktif secara default. Riwayat implementasi di KEP berbunyi: diterima di 1.34, alpha di 1.35, beta di 1.36, GA di 1.37. Halaman docs menyebut first available di v1.34, jadi sumber-sumber berbeda satu rilis soal alpha-nya. Anggap 1.37 sebagai rilis yang penting.
Tiga fitur lain juga stable di rilis yang sama, dan beberapa lagi berpindah stage. Tabel mencantumkannya dengan nama gate dari post rilis dan halaman DRA; kalau sumber tidak memberi gate, selnya menyatakan itu.
| Fitur | Stage di 1.37 | Gate atau catatan |
|---|---|---|
| DRA Extended Resource (KEP-5004) | Stable | Gate DRAExtendedResource, aktif secara default. Diset di kube-apiserver, kube-scheduler, kube-controller-manager dan kubelet |
| Device taints dan tolerations (KEP-5055) | Stable | Gate DRADeviceTaints dan DRADeviceTaintRules kini terkunci. Admin memberi taint pada device lewat DeviceTaintRule |
| Status ResourceClaim dengan data device (KEP-4817) | Stable | Menambah field devices di status ResourceClaim, termasuk nama interface, MAC address dan IP untuk network device |
| Atribut standar numaNode (KEP-6072) | Stable | resource.kubernetes.io/numaNode sebagai nama bersama. Perubahan penamaan tanpa feature gate |
| ResourceClaim untuk Workload dan PodGroup | Beta | Gate DRAWorkloadResourceClaims, nonaktif secara default. Menghapus batas reservasi 256 Pod per claim |
| CapacityRequestPolicyRange fraksional | Beta | Gate DRAFractionalCapacityRange. Permintaan kapasitas lebih halus untuk device fraksional |
| Device compatibility groups | Alpha | Gate DRADeviceCompatibilityGroups, nonaktif secara default. Juga butuh DRAPartitionableDevices |
| PreQueueingHint (KEP-6132) | Alpha | Gate SchedulerPreQueueingHints. KEP menyebut default-nya false |
Post rilis juga mencantumkan alpha baru atau alpha putaran kedua: derived attributes (ekspresi CEL yang menjembatani atribut berbeda nama antar driver), atribut bertipe list, request node allocatable resource, snapshot ketersediaan resource lewat ResourcePoolStatusRequest, dan optional node operations. Semuanya saya lewati di bawah karena tidak menyentuh migrasi extended resource.
Mengapa manifest yang tidak berubah kini berjalan
Sisi workload tidak berubah sama sekali, dan itulah tujuan desainnya. KEP-5004 memberi tiga motivasi: aplikasi yang ada berjalan tanpa modifikasi, developer aplikasi pindah ke DRA dengan kecepatan sendiri, dan cluster admin pindah dengan kecepatan sendiri, mungkin satu node per satu. Satu-satunya objek baru adalah DeviceClass yang cluster-scoped dan dibuat admin. Di bawah ini Pod dan class-nya, dengan class diambil dari halaman DRA API.
# Workload side: unchanged. This is the request a device plugin satisfies today.
# Extended resources need requests and limits to match, as in the docs' dongle example.
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name: demo
image: registry.example.com/gpu-app:1.0
resources:
requests:
example.com/gpu: 1
limits:
example.com/gpu: 1
---
# Admin side: one cluster-scoped object, taken from the DRA API page in the docs.
# extendedResourceName is the whole migration surface.
apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
name: gpu.example.com
spec:
selectors:
- cel:
expression: device.driver == 'gpu.example.com' && device.attributes['gpu.example.com'].type
== 'gpu'
extendedResourceName: example.com/gpuTidak ada yang menyebut DRA di dalam Pod. Langkah admin adalah seluruh permukaan migrasinya: extendedResourceName memberi tahu scheduler bahwa device yang cocok dengan selector CEL milik class bisa memenuhi request untuk nama itu. API reference menyebut nama itu seharusnya unik di antara class. Jika dua class memakai satu nama, yang dibuat lebih belakangan menang, dan jika waktunya sama, nama pertama secara leksikografis yang menang. KEP menyajikannya sebagai cara non-disruptif memindahkan nama antar class: buat class baru, lalu kosongkan field di class lama.
Ada rute kedua tanpa pemetaan admin sama sekali. Setiap DeviceClass bisa diminta sebagai extended resource bernama deviceclass.resource.kubernetes.io/ diikuti nama class, dan docs menyebut ResourceClaim yang dihasilkan berisi request ExactCount untuk jumlah device itu. Jebakannya, menurut KEP, adalah ketidakcocokan penamaan: nama DeviceClass boleh berupa DNS subdomain hingga 253 karakter, sedangkan bagian nama extended resource dibatasi 63, jadi class hanya bisa jadi implicit name kalau memenuhi kedua aturan. Kalau tidak, isi extendedResourceName secara eksplisit.
# Implicit form: no extendedResourceName on the class and no ResourceClaim in the Pod.
# The name is the fixed prefix plus the DeviceClass name (here gpu.example.com).
resources:
limits:
deviceclass.resource.kubernetes.io/gpu.example.com: 2| Aspek | Device plugin | Extended resource berbasis DRA |
|---|---|---|
| Di mana kapasitas dicatat | status.capacity milik Node, diiklankan oleh device plugin | Objek ResourceSlice yang dipublikasikan DRA driver dan dipetakan oleh DeviceClass |
| Cara Pod meminta | resources.requests dan limits pada example.com/gpu | Field yang sama, tidak berubah |
| Siapa yang memetakan nama | Device plugin yang mendaftarkannya | Cluster admin mengisi extendedResourceName pada DeviceClass yang cluster-scoped |
| Memilih device | Hanya jumlah. Docs menyebut device plugin tidak mendukung filtering berbasis ekspresi | Selector CEL pada DeviceClass menentukan device mana yang memenuhi syarat |
| Siapa yang membuat claim | Tidak ada, memang tidak ada claim | kube-scheduler menulis satu ResourceClaim khusus per Pod, dimiliki oleh Pod itu |
| Nama sama di satu node | Boleh jika sendirian | Tidak boleh dua-duanya: node mengiklankan nama itu lewat ResourceSlice atau lewat status.capacity, tidak keduanya |
| Quota | Extended resource quota seperti requests.example.com/gpu | KEP menyesuaikan perhitungan agar extended resource quota dan claim quota menghitung device yang sama |
Baca dua baris terakhir dua kali. Nama yang sama di dua node berbeda boleh, dan nama yang sama di satu node tidak boleh, dan itulah yang memungkinkan migrasi bertahap. Soal quota, KEP menetapkan perhitungan yang disesuaikan agar ResourceQuota yang ditulis untuk dunia lama tetap bermakna. Saya tidak memverifikasi bagaimana itu akhirnya dirilis.
Apa yang dikerjakan scheduler di belakang layar
Ketika Pod meminta extended resource berbasis DRA, scheduler membuat ResourceClaim yang tidak pernah ditulis penulis Pod. KEP menjelaskannya dengan presisi. Claim itu namespaced dan dimiliki Pod, dibuat oleh plugin dynamicresources milik scheduler pada fase PreBind (salinan in-memory sudah ada sejak Reserve), dan paling banyak ada satu per Pod berapa pun jumlah extended resource yang diminta. Claim membawa annotation resource.kubernetes.io/extended-resource-claim yang menyebut nama Pod, dan tiap request dinamai berdasarkan container dan resource-nya, misalnya container-0-request-2 untuk resource DRA ketiga di container pertama. KEP menyatakan penamaan itu hanya informasional dan kubelet tidak boleh bergantung padanya.
Kubelet menemukan claim lewat field status Pod baru, extendedResourceClaimStatus, yang requestMapping-nya mengikat tiap container dan nama extended resource ke sebuah request di claim. Setelah itu kubelet meminta DRA driver menyiapkan device dan meneruskannya ke container yang sesuai lewat CDI. KEP menyebut container boleh init atau reguler tetapi tidak boleh ephemeral, hal yang patut diingat sebelum Anda memakai debug container pada Pod GPU.
# 1. Did the scheduler create a claim for this Pod? The mapping is in Pod status.
kubectl get pod demo -n default -o jsonpath='{.status.extendedResourceClaimStatus}'
# Shape the KEP gives for that field (claim name will differ on your cluster):
# status:
# extendedResourceClaimStatus:
# resourceClaimName: ccc-gpu-57999b9c4c-vpq68-gpu-8s27z
# requestMapping:
# - containerName: container-name
# extendedResourceName: foo.domain/bar
# requestName: container-0-request-2
# 2. Read the claim itself. The annotation resource.kubernetes.io/extended-resource-claim
# marks a claim the scheduler wrote, as opposed to one a human wrote.
kubectl get resourceclaim ccc-gpu-57999b9c4c-vpq68-gpu-8s27z -n default -o yaml
# 3. Signals the KEP names. Confirm each exists on YOUR /metrics before alerting on it.
# scheduler_resourceclaim_creates_total{status="failure"}
# resourceclaim_controller_resource_claims{source="extended-resource"}
# scheduler_pending_pods{queue="unschedulable"}Field-field itu tempat pertama untuk melihat saat ada masalah. KEP juga menyebut sinyalnya: scheduler_pending_pods yang naik, kubelet_started_containers_errors_total, label source baru pada resourceclaim_controller_resource_claims, dan counter baru scheduler_resourceclaim_creates_total dengan label status. KEP menyebutnya SLI, jadi pastikan tiap metrik memang ada di /metrics cluster Anda sebelum membuat alert.
Migrasi cluster satu node per satu
KEP tegas bahwa inilah jalur yang dimaksud: device plugin driver bisa diganti DRA driver per node. KEP juga menyebut sinyal bahwa penggantian belum selesai. Jika node.status.capacity untuk extended resource tidak turun ke nol, device plugin belum tergantikan dengan benar. Batasan yang menentukan urutannya adalah yang ada di tabel perbandingan, yaitu satu node tidak boleh mengiklankan satu nama dari kedua backend.
# One node at a time. Steps 2 and 3 are the vendor's procedure, not Kubernetes'.
NODE=gpu-worker-01
# 1. Stop new Pods landing here. Draining is my choice, not a KEP requirement:
# it avoids a Pod holding a device-plugin allocation while the backend swaps.
kubectl cordon "$NODE"
kubectl drain "$NODE" --ignore-daemonsets --delete-emptydir-data
# 2. Remove the device plugin from this node (vendor-specific).
# 3. Install the DRA driver on this node (vendor-specific).
# 4. The KEP's signal that the old backend is really gone: capacity must fall to zero.
# Expect <none> in the GPU column. Anything else means the plugin is still advertising.
kubectl get node "$NODE" \
-o custom-columns='NAME:.metadata.name,GPU:.status.capacity.example\.com/gpu'
# 5. The new backend must be advertising instead: ResourceSlices for this node.
kubectl get resourceslices \
-o custom-columns='NAME:.metadata.name,NODE:.spec.nodeName,DRIVER:.spec.driver'
# 6. The DeviceClass from earlier must exist BEFORE a Pod can use DRA here
# (an application can only request devices from DRA after the class is created).
kubectl get deviceclass gpu.example.com
# 7. Only now let Pods back in, and run the unchanged workload as the test.
kubectl uncordon "$NODE"Biaya tersembunyi ada di paragraf rollback KEP. Menonaktifkan gate aman untuk Pod yang sedang berjalan, yang tetap bekerja dan selamat dari restart karena device CDI yang sudah disiapkan untuknya tidak berubah. Mengaktifkan lagi tidak simetris, seperti kata peringatan di bawah.
Jika Anda me-rollback gate DRAExtendedResource lalu mengaktifkannya lagi, KEP menyebut scheduler mungkin kehilangan jejak device mana dialokasikan ke Pod mana. Setiap Pod yang memegang device yang dialokasikan saat fitur aktif harus dihapus, agar driver membebaskannya dan pencatatan diperbaiki. Rencanakan rollback sebagai drain workload GPU, bukan sekadar membalik flag.
Samakan gate sebelum Pod pertama bergantung padanya. Risiko rollout di KEP adalah Pod memakai fitur sebelum kube-apiserver, scheduler, controller-manager dan kubelet semuanya mendukungnya, yang bisa menggagalkan scheduling atau menggagalkan start Pod. Di 1.37 gate aktif secara default, jadi bentuk praktis risiko itu adalah version skew saat upgrade: selesaikan control plane dan semua kubelet sebelum membuat DeviceClass pertama dengan extendedResourceName. Urutan itu adalah inferensi saya dari KEP, bukan kalimat di dalamnya.
Device taints sudah stable, jadi maintenance bisa dry run
Device taints dan tolerations Stable sejak 1.37 dan pertama tersedia di 1.33. Sebuah taint punya key, value dan effect, dan effect-nya berlaku pada ResourceClaim yang memakai device serta setiap Pod yang merujuknya. NoSchedule menghentikan alokasi baru. NoExecute mencakup NoSchedule dan meng-evict Pod yang sudah terjadwal, lewat device taint eviction controller di kube-controller-manager. None diabaikan oleh scheduler maupun eviction controller, jadi driver bisa menandai device yang menurun kualitasnya tanpa konsekuensi.
Admin bisa memberi taint tanpa menyentuh driver lewat DeviceTaintRule, stable sejak 1.37 dan pertama tersedia di 1.35. Setiap rule menambahkan satu taint ke device yang cocok dengan deviceSelector-nya, dan rule tanpa selector tidak mencocokkan apa pun, yang digambarkan docs sebagai perlindungan agar tidak meng-evict semua Pod karena selector terlewat. Selector bisa menyebut DeviceClass, driver, pool dan device. Driver untuk device node-local dianjurkan memakai nama node sebagai nama pool, jadi selector pool memberi taint pada seluruh device satu node. Halaman itu juga mendokumentasikan prosedur aman, dan blok di bawah mengikutinya.
# Step 1: a DRY RUN. effect None is ignored by the scheduler and the eviction controller.
# Adapted from the device taints page; dra.example.com is the docs' fictional driver.
apiVersion: resource.k8s.io/v1
kind: DeviceTaintRule
metadata:
name: example
spec:
deviceSelector:
driver: dra.example.com # no selector at all would match NO devices, by design
taint:
key: dra.example.com/unhealthy
value: Broken
effect: None
# Step 2: read what the rule WOULD do. For effect None the message reports published
# devices selected, allocated devices selected and Pods that would be evicted.
# kubectl describe devicetaintrule example
# That message is written once. Delete and recreate the rule to refresh it.
# Step 3: when the numbers are what you expected, switch to real eviction.
# kubectl patch devicetaintrule example --type merge \
# -p '{"spec":{"taint":{"effect":"NoExecute"}}}'
# Step 4: wait for the eviction controller to finish.
# kubectl wait --for=condition=EvictionInProgress=false DeviceTaintRule/exampleSelalu mulai dengan effect None. Eviction controller lalu melaporkan berapa device terpublikasi dan teralokasi yang dipilih rule serta berapa Pod yang akan di-evict. Docs menyebut pesan itu ditulis sekali dan tidak diperbarui, jadi hapus dan buat ulang rule untuk mendapat hitungan baru.
Tolerations berada di request ResourceClaim, bukan di Pod, sehingga setiap Pod yang berbagi claim mentoleransi hal yang sama, dan KEP menolak toleration tingkat Pod karena alasan itu. Itu menyisakan celah yang tidak bisa saya tutup dari sumber. Pod yang hanya memakai extended resource tidak punya ResourceClaim sendiri, karena claim ditulis scheduler. Di halaman yang saya baca, baik halaman device taints maupun KEP-5004 tidak menyebut bagaimana Pod seperti itu mentoleransi taint, jadi uji kasus taint yang ditoleransi sebelum mengandalkannya. KEP-5055 juga menyebut taint bukan mekanisme access control, dan menambah taint di cluster live itu racy karena scheduler harus melihatnya dulu.
Fitur throughput scheduler yang diturunkan stage-nya
Angka utama di post rilis adalah PreQueueingHint memangkas jalur requeue dari O(N kuadrat) menjadi O(1) dan menggandakan throughput scheduling dalam benchmark awal. KEP-6132 memberi mekanisme dan pengukurannya. Dulu setiap event ResourceClaim memicu evaluasi seluruh Pod unschedulable, jadi N Pod dan N event claim berbiaya O(N kuadrat). Kini Pod informer index mempersempit tiap event ke Pod yang merujuk claim itu. Pada benchmark SchedulingWithResourceClaimTemplate di test/integration/scheduler_perf, KEP mencatat sekitar 297 Pod per detik sebelum dan sekitar 711 sesudah, kira-kira 2,4 kali.
Ini juga contoh bersih tentang arti alpha. KEP menyebut fitur ini awalnya ditargetkan beta di 1.37, lalu diturunkan ke alpha dengan default nonaktif di akhir siklus setelah review menemukan bug correctness pada logika penyempitannya. Kegagalan yang dijaga adalah hint yang keliru menyatakan tidak ada Pod terdampak, yang membuat Pod tak terjadwal sampai flush berkala. Riwayat implementasi KEP mencatat perbaikan dan promosi ke beta untuk v1.38. Saran saya, jangan aktifkan SchedulerPreQueueingHints di scheduler produksi pada 1.37 demi keuntungan yang hanya terukur di benchmark burst. Jika Anda men-scale ribuan Pod terhadap ResourceClaimTemplate, uji di staging dulu.
Apa yang bisa rusak, dan di mana melihatnya
Setiap baris di bawah adalah failure mode atau batasan yang dinyatakan KEP atau docs. Kolom ketiga adalah tempat saya akan melihat lebih dulu.
| Gejala atau jebakan | Penyebab, menurut sumber | Di mana melihat |
|---|---|---|
| Device yang terpilih salah | Dua DeviceClass memakai satu extendedResourceName. Yang dibuat lebih belakangan menang, dan jika waktunya sama, nama pertama secara leksikografis yang menang | kubectl get deviceclasses lalu bandingkan creationTimestamp |
| Implicit name ditolak | Nama DeviceClass memenuhi aturan DNS subdomain tetapi tidak memenuhi aturan nama extended resource yang lebih pendek | Isi extendedResourceName secara eksplisit pada class |
| Pod tetap Pending pada request besar | KEP mencantumkan batas sistem 128 device untuk satu request extended resource berbasis DRA | Log scheduler di level 5, lalu pecah request-nya |
| Pod gagal dijadwalkan saat burst | API server priority and fairness membatasi scheduler yang membuat claim | scheduler_resourceclaim_creates_total dengan status failure, lalu limit priority and fairness |
| Pod gagal dijadwalkan atau start setelah fitur diaktifkan | Fitur dipakai sebelum kube-apiserver, scheduler, controller-manager dan kubelet semuanya mendukungnya | Status gate di keempatnya, scheduler_pending_pods dan kubelet_started_containers_errors_total |
| Pencatatan device salah setelah rollback | Mengaktifkan gate lagi bisa membuat scheduler kehilangan jejak alokasi | Hapus Pod yang memegang device DRA, lalu cek ulang claim |
| Pod dijadwalkan lalu di-evict | Taint NoExecute ditambahkan sebelum scheduler melihatnya | Condition EvictionInProgress pada DeviceTaintRule |
Dua di antaranya senyap. Kasus class duplikat tidak menghasilkan error secara desain, karena KEP menyebutnya cara non-disruptif tanpa error untuk berpindah nama antar class, jadi class kedua yang nyasar dipatuhi tanpa suara. Dan bagian drawbacks KEP hanya satu baris: menambah kompleksitas di scheduler. Cluster autoscaler adalah sisi yang masih terbuka. KEP menyebut autoscaler mungkin perlu mengisi field DynamicResources yang baru di state node-nya sendiri dan mungkin butuh method publik untuk itu, jadi baca release notes autoscaler Anda sebelum men-scale node group GPU pada nama berbasis DRA.
Yang dikerjakan hari Senin
Tidak ada yang butuh GPU untuk memulai. Langkah awalnya hanya membaca atau berjalan di cluster uji, dan menentukan apakah migrasi layak dijadwalkan.
- Pastikan control plane dan semua kubelet sudah 1.37, lalu baca halaman task Assign Extended Resources untuk versi Anda.
- Daftar nama extended resource yang diminta Pod Anda dan device plugin di balik masing-masing. Tiap nama adalah kandidat extendedResourceName.
- Tanyakan ke tiap vendor driver apakah ada DRA driver untuk hardware itu dan selector apa yang diharapkan DeviceClass-nya. Saya tidak memverifikasi driver vendor mana pun.
- Pilih satu node non-kritis, migrasikan dengan urutan di atas, jalankan workload yang tidak berubah di sana, dan baca status.extendedResourceClaimStatus pada Pod.
- Tulis rollback sebagai drain, dan tambahkan DeviceTaintRule dry-run ke runbook maintenance.
# Which extended resources do Pods in this cluster actually request? (read-only)
# Each name with a slash and a vendor-style domain is a candidate extendedResourceName.
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .spec.containers[*]}{.resources.requests}{"\n"}{end}{end}' \
| grep -E '"[a-z0-9.-]+/[a-z0-9.-]+"' | sort | uniq -c | sort -rn
# Is the resource.k8s.io API served, and has any DRA driver published devices yet?
kubectl api-resources --api-group=resource.k8s.io
kubectl get deviceclasses
kubectl get resourceslices
# Any DeviceClass already claiming an extended resource name? (spot duplicates now)
kubectl get deviceclasses \
-o custom-columns='NAME:.metadata.name,EXT:.spec.extendedResourceName,CREATED:.metadata.creationTimestamp'Kalau semua itu ternyata membosankan, Anda selesai, dan itulah maksud fiturnya: manifest tetap seperti adanya dan backend bergeser di bawahnya.
Aturan yang saya bawa dari rilis ini: migrasikan lapisan alokasi sebelum menulis ulang satu manifest pun. Extended Resource support mengubah adopsi DRA dari penulisan ulang aplikasi menjadi perubahan infrastruktur per node dengan rollback terdokumentasi, dan bagian yang masih alpha, terutama PreQueueingHint, bukan yang pantas jadi dasar rencana.
Sumber dan bacaan lanjutan
- Blog Kubernetes: Kubernetes v1.37, DRA Updates (3 September 2026)
- KEP-5004: DRA Extended Resource, dokumen desain
- Docs Kubernetes: DRA API, extended resource allocation by DRA
- Docs Kubernetes: Assign Extended Resources to a Container
- Docs Kubernetes: Device Taints and Tolerations
- KEP-5055: DRA device taints and tolerations
- KEP-6132: PreQueueingHint extension point untuk pemrosesan event scheduler
- Docs Kubernetes: DRA Features

