Ringkasan Utama
Volcano v1.15 membuat preemption sadar gang: action alpha gangPreempt dan gangReclaim memilih korban per job, mengevict replica surplus di atas minAvailable lebih dulu, dan mensimulasikan seluruh gang preemptor sebelum evict apa pun. Rilis ini juga menghitung DRA ResourceClaim di queue quota dan menyembunyikan Pod yang tertahan quota dari autoscaler lewat scheduling gates.
Bayangkan cluster GPU dengan tiga job training terdistribusi yang sedang berjalan, lalu sebuah gang berprioritas lebih tinggi datang. Scheduler butuh ruang, jadi ia mengevict satu Pod dari setiap job. Kapasitas memang bebas, tetapi ketiga job langsung macet karena kehilangan satu worker, dan gang baru tetap tidak bisa mengumpulkan cukup Pod untuk mulai. Kaskade itulah yang ingin dihilangkan oleh release post Volcano v1.15, dan itu alasan saya membacanya sampai tuntas.
Saya belum menjalankan v1.15 di cluster GPU, jadi post ini tidak mengklaim benchmark apa pun. Isinya pembacaan teliti atas release post Volcano v1.15.0, release note di GitHub, dan panduan scheduling gates, lalu dibandingkan dengan dokumentasi Kubernetes tentang gang scheduling native dan workload-aware preemption. Kalau sebuah kalimat menyebut alpha, berarti sumbernya menyebut alpha.
Kenapa preemption per Pod merusak job terdistribusi
Job gang hanya berguna selama jumlah minimum Pod-nya berjalan bersama. Release post menjelaskan perilaku lama dengan spesifik: preemption per Pod bisa mengevict satu Pod dari beberapa job training yang berjalan. Di atas kertas kapasitas bebas, tetapi semua job itu rusak, sementara preemptor tetap kekurangan Pod untuk mencapai minAvailable miliknya.
Plugin gang Volcano sebenarnya sudah memberi penempatan all-or-nothing untuk job yang belum mulai: dokumentasinya menyebut action scheduling dijalankan untuk Pod sebuah job hanya jika jumlah minimumnya bisa berjalan. Menurut release post, bagian yang kurang adalah sisi eviction, yang tidak memperlakukan gang korban sebagai satu kesatuan. Semua yang penting bagi cluster GPU di v1.15 adalah variasi dari satu tema: berhenti memutuskan per Pod saat yang penting adalah gang, queue, atau device class.
Gang-aware preemption: korban per job, preemptor sebagai satu kesatuan
Rilis ini membagi perubahan menjadi dua sisi. Di sisi korban, kandidat disusun per job atau gang, dan Pod setiap job diklasifikasikan sebagai replica surplus (di atas minAvailable) atau replica kritis. Replica surplus diutamakan karena mengevict-nya tidak merusak job korban. Di sisi preemptor, scheduler mengumpulkan resource yang bisa direklamasi sedikit demi sedikit; begitu totalnya mencukupi seluruh gang preemptor, ia menjalankan simulasi penempatan pada gambaran resource yang diproyeksikan dan hanya meng-commit eviction jika seluruh gang muat.
# Wrong: an illustration of what the upgrade notes advise against.
# Legacy per-Pod eviction and gang-aware eviction in one action list.
actions: "enqueue, allocate, backfill, preempt, reclaim, gangPreempt, gangReclaim"
# Right: the example from the v1.15 release post. gangPreempt and gangReclaim
# REPLACE preempt and reclaim; they do not sit beside them.
actions: "enqueue, allocate, backfill, gangPreempt, gangReclaim"
tiers:
- plugins:
- name: priority # orders gangPreempt victims (per the GitHub release note)
- name: gang
- name: drf
- name: predicates
- name: nodeorder
- name: binpackRelease note di GitHub menambahkan detail yang tidak ada di blog. Kedua action mengurutkan korban secara berbeda: gangPreempt berdasarkan priority, gangReclaim berdasarkan keadilan antar queue. Opsi allowWholeBundle, default true, mengatur apakah bundle korban satu job utuh boleh dipilih. Saat topologi HyperNode aktif, pencarian korban dibatasi pada cakupan topologi terpilih sehingga preemption tidak melintasi domain topologi. Release post juga menyebut tim akan mengevaluasi penggabungan mekanisme ini dengan action preempt dan reclaim lama.
Ada dua peringatan di upgrade notes. Fitur ini Alpha, dan mengonfigurasi gangPreempt serta gangReclaim bersama preempt dan reclaim lama dalam satu daftar action tidak direkomendasikan. Pilih satu set per scheduler, dan anggap blok konfigurasi di atas sebagai pengganti, bukan tambahan.
DRA queue quota: satu model kapasitas untuk CPU, memory, dan device
Versi Volcano sebelumnya sudah bisa menjadwalkan Pod yang memakai resource DRA, tetapi queue quota belum mencakup DRA ResourceClaim. Di v1.15 plugin capacity menghitungnya terhadap field capability, deserved, dan guarantee yang sudah ada di queue, sehingga tidak perlu API quota kedua. Ada dua jenis kontrol: jumlah device utuh per DeviceClass, dan dimensi yang bisa dikonsumsi seperti core atau memory vGPU.
# Scheduler config: the capacity plugin must own DRA accounting.
tiers:
- plugins:
- name: capacity
arguments:
capacity.DynamicResourceAllocationEnable: true
capacity.DRAConsumableCapacityEnable: true # vGPU cores / memory dimensions
---
# Queue from the release post. The keys are the part to learn:
# deviceclass/<DeviceClass> -> whole-device count
# <dimension>.deviceclass/<Class> -> consumable capacity (cores, memory)
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: ml-team
spec:
capability:
cpu: "100"
memory: "200Gi"
"deviceclass/gpu.nvidia.com": "8"
"cores.deviceclass/hami-core-gpu.project-hami.io": "800"
"memory.deviceclass/hami-core-gpu.project-hami.io": "320Gi"Bentuk key-nya yang perlu dihafal. Release note di GitHub menuliskannya sebagai deviceclass diikuti garis miring dan nama DeviceClass untuk jumlah device utuh, dan dimensi, titik, lalu key deviceclass yang sama untuk kapasitas yang bisa dikonsumsi. Pada contoh di post, queue ml-team mengizinkan 8 device utuh gpu.nvidia.com dan, untuk kelas vGPU HAMi, 800 core dan 320Gi memory. Angka itu hanya ilustrasi sintaks, bukan rekomendasi sizing.
Saat beberapa Pod merujuk satu ResourceClaim yang sama, Volcano melakukan deduplikasi agar device tidak dihitung satu kali per Pod; post menyebut kasus ini secara eksplisit. Prasyaratnya adalah dukungan DRA di Kubernetes dan DRA driver yang tersedia, dan catatan GitHub menyebut beberapa mode alokasi DRA berada di luar cakupan awal penghitungan quota, jadi uji mode yang Anda pakai. Terpisah dari itu, integrasi scheduling DRA kini aktif secara default agar selaras dengan Kubernetes 1.34 ke atas, dan predicate.DynamicResourceAllocationEnable diisi false untuk mematikannya.
Scheduling gates: jauhkan Pod yang tertahan quota dari autoscaler
Cluster Autoscaler atau Karpenter bisa membaca Pod yang menunggu kapasitas queue sebagai kekurangan node lalu scale up, sehingga membeli hardware yang tidak akan diizinkan dipakai oleh queue. v1.15 menambahkan Scheduling Gates for Queue Admission, Alpha. Untuk Pod yang ikut serta, webhook Volcano menyuntikkan scheduling gate saat Pod dibuat, scheduler menghapusnya setelah pengecekan kapasitas queue lolos, dan selama gate ada Pod tidak terlihat oleh autoscaler.
# 1. Enable the gate on BOTH the scheduler and the webhook-manager.
helm install volcano volcano/volcano --namespace volcano-system --create-namespace \
--set custom.scheduler_feature_gates="SchedulingGatesQueueAdmission=true" \
--set custom.admission_feature_gates="SchedulingGatesQueueAdmission=true"
# 2. Opt a Pod in. Without the annotation nothing changes for it.
apiVersion: v1
kind: Pod
metadata:
name: queue-gated-pod
annotations:
scheduling.volcano.sh/queue-allocation-gate: "true"
spec:
schedulerName: volcano
containers:
- name: worker
image: nginx
# 3. While the queue is full this prints the gate; once admitted it prints nothing.
kubectl get pod queue-gated-pod -o jsonpath='{.spec.schedulingGates}'Ini memakai ulang primitif Kubernetes yang sudah stable. Halaman Kubernetes tentang Pod scheduling readiness menyebutnya stable sejak v1.30 dan menjelaskan bahwa Pod yang terjebak dalam kondisi kekurangan resource membuat scheduler dan integrator seperti Cluster Autoscaler bekerja sia-sia. Gate hanya bisa ditetapkan saat pembuatan dan dihapus dalam urutan bebas setelahnya. Panduan Volcano menambahkan bahwa jika controller lain menambahkan gate sendiri, Volcano menunggu sampai hanya gate miliknya yang tersisa sebelum menghapusnya.
Setelah gate dilepas, Pod yang tidak cocok dengan node mana pun ditandai Unschedulable, yang memang benar memicu autoscaler. Jadi gate memisahkan dua pertanyaan yang dulu terlihat sama dari luar: apakah queue mau menerima Pod ini, dan apakah cluster punya node untuknya.
Uji gate pada satu Pod percobaan sebelum mempercayainya. Query jsonpath menampilkan gate selama Pod menunggu dan tidak mengembalikan apa-apa setelah Pod diterima. Pastikan juga plugin capacity aktif di konfigurasi scheduler, karena panduan menyebut hanya plugin itu yang mengimplementasikan fitur ini.
Volcano 1.15 dibanding gang scheduling native Kubernetes
Kubernetes kini punya jawaban sendiri untuk masalah yang sama: PodGroup, gang scheduling, dan workload-aware preemption, dengan gang scheduling berstatus Beta sejak v1.37. Tabel ini membandingkan keduanya memakai dokumentasi masing-masing proyek. Sel yang tipis di satu sisi adalah pernyataan tentang halaman yang saya baca, bukan klaim bahwa kemampuan itu tidak mungkin ada di tempat lain.
| Aspek | Volcano v1.15 | Kubernetes native (docs v1.37) |
|---|---|---|
| Ambang gang | minAvailable pada job; plugin gang menjalankan scheduling hanya jika jumlah minimum bisa berjalan | Policy gang PodGroup dengan minCount; Pod menunggu di PreEnqueue sampai group ada dan minCount Pod terbuat |
| Kematangan | Plugin gang adalah algoritma inti; gang-aware preemption masih Alpha | Gang scheduling Beta, mati secara default, butuh gate GenericWorkload dan scheduling.k8s.io/v1beta1 |
| Unit preemption | gangPreempt dan gangReclaim mengevaluasi korban per job atau gang | Workload-aware preemption memperlakukan PodGroup sebagai satu preemptor dan mencari di seluruh cluster |
| Perlindungan korban | Replica surplus di atas minAvailable dikorbankan lebih dulu; replica kritis dihindari | Urutan priority, lalu PodGroup di atas Pod tunggal, lalu group lebih besar, lalu yang lebih dulu mulai; disruptionMode Single atau All |
| Pengecekan sebelum evict | Mensimulasikan penempatan seluruh gang preemptor, commit eviction hanya jika muat | Mensimulasikan pelepasan semua kandidat korban, menjadwalkan sekali, lalu mengembalikan sebanyak mungkin korban; belum tentu preemption paling sedikit |
| Queue quota | Queue capability, deserved, dan guarantee lewat plugin capacity | Tidak ada objek queue atau quota di halaman yang saya baca; priority PodGroup mengurutkan antrean scheduling |
| Device DRA | ResourceClaim dihitung di queue quota per DeviceClass; claim bersama dideduplikasi | spec.resourceClaims pada PodGroup membuat semua Pod di group berbagi satu claim, di balik feature gate tersendiri |
| Antrean yang tenang bagi autoscaler | Scheduling gate queue-admission, opt-in per Pod, Alpha | Scheduling readiness gate stable sejak v1.30; saya tidak menemukan queue admission yang dibangun di atasnya |
Polanya: Kubernetes native memberi primitif di dalam kube-scheduler, sedangkan Volcano memberi queue di sekelilingnya. Native unggul karena in-tree dan Beta; Volcano unggul untuk urusan quota, keadilan antar tim, dan perilaku autoscaler. Tidak ada sumber yang membandingkan keduanya lewat benchmark, jadi saya tidak akan meranking soal kecepatan.
Trade-off dan titik yang bisa menggigit
Empat batasan ini langsung berasal dari sumber. Masing-masing jenis masalah yang muncul di minggu sibuk pertama, bukan saat demo.
- Alpha berarti antarmuka bisa berubah. Gang preemption, scheduling gates, dan multi-sharding policy semuanya Alpha di 1.15, dan post menyebut tim masih memutuskan apakah gang preemption akan digabung ke action lama.
- Kapasitas queue yang direservasi tidak punya timeout. Panduan menyebut Pod yang sudah dilepas gate-nya tetapi tetap unschedulable mempertahankan kapasitas queue yang direservasi, yang bisa memblokir Pod lain.
- Gate hanya bekerja dengan plugin capacity. Pengguna proportion mungkin masih melihat scale-up palsu sampai issue Volcano 5271 selesai.
- Upgrade mengubah default. Integrasi DRA menyala secara default, dan catatan GitHub menyebut callback gradient HyperNode kini menerima argumen SearchPurpose, sehingga plugin topologi kustom perlu diperbarui.
Perlakukan ketiadaan timeout sebagai kebutuhan monitoring, bukan catatan kaki. Jika Pod yang diterima lalu diam sebagai Unschedulable saat node diprovisi, penggunaan queue tampak penuh padahal GPU menganggur. Panduan tidak menyediakan masa berlaku bawaan, jadi buat alert untuk Pod yang tetap Unschedulable melebihi waktu provisioning node autoscaler Anda yang biasa.
Kubernetes native juga punya sisi tajam, menurut halaman lifecycle-nya. Semua Pod dalam PodGroup harus memakai schedulerName, priority, dan preemptionPolicy yang sama, atau scheduler menolak group itu, dan status PodGroup tidak diperbarui setelah penempatan awal. Perhatikan pula bentrok nama: kedua proyek kini punya objek bernama PodGroup, jadi tuliskan API group-nya, seperti podgroups.scheduling.k8s.io, saat debugging.
Cara saya memilih di antara keduanya
Jika Anda sudah menjalankan Volcano dengan queue, bawa 1.15 ke staging lebih dulu. DRA quota dan gate queue-admission menjawab masalah yang mungkin sudah Anda alami, dan keduanya tidak mengubah cara job ditulis. Simpan gang-aware preemption untuk scheduler uji terpisah sampai keluar dari Alpha.
Jika Anda hanya punya satu tim, satu cluster, dan tanpa hierarki queue, gang scheduling native dan workload-aware preemption mungkin sudah cukup. Keduanya butuh gate GenericWorkload dan API group v1beta1, dan semuanya tetap di dalam kube-scheduler, satu komponen lebih sedikit untuk dijalankan dan di-upgrade.
Jangan menjalankan keduanya pada Pod yang sama. PodGroup mewajibkan setiap Pod memakai satu schedulerName, jadi sebuah gang milik satu scheduler saja. Ini pembacaan saya atas dokumentasi, bukan jalur migrasi yang sudah diuji.
Yang dikerjakan hari Senin
Mulai dari langkah murah dan bisa dibatalkan, dan simpan saklar Alpha untuk yang terakhir.
- Jalankan benchmark framework Volcano di Kind plus KWOK untuk mencatat baseline sebelum mengubah apa pun.
- Upgrade cluster staging ke 1.15.0 dan periksa apakah default DRA mengubah penempatan workload yang ada; isi flag predicate dengan false jika berubah.
- Tambahkan satu key DRA ke queue uji, aktifkan dua argumen capacity, dan amati penggunaan queue dengan ResourceClaim bersama.
- Aktifkan gate queue-admission di kedua komponen dan beri anotasi pada Pod satu namespace, lalu pantau Pod ber-gate yang menjadi Unschedulable.
- Pada scheduler terpisah, ganti daftar action menjadi gangPreempt dan gangReclaim lalu reproduksi kaskadenya: dua gang berjalan dengan replica surplus dan satu gang berprioritas lebih tinggi datang.
# 1. Baseline first, on Kind + KWOK (run from the repo's benchmark directory).
cd benchmark
make setup VOLCANO_VERSION=v1.15.0
make test-gang-env JOBS=10 REPLICAS=100 MIN_AVAILABLE=100
make cleanup-all
# 2. Upgrade staging. DRA integration is ON by default from 1.15; to keep the
# old behaviour set predicate.DynamicResourceAllocationEnable: false.
helm repo update
helm upgrade volcano volcano-sh/volcano --version 1.15.0
# 3. Look at what the queue thinks it holds before and after adding a DRA key.
kubectl get queues.scheduling.volcano.sh ml-team -o yaml
# 4. Two objects are both called PodGroup. Spell out the API group when debugging.
kubectl get podgroups.scheduling.k8s.io -A # Kubernetes native (v1beta1 in 1.37)Langkah 5 paling akhir karena itu satu-satunya perubahan Alpha yang mengubah siapa yang di-evict. Jika reproduksi menunjukkan replica surplus dikorbankan lebih dulu dan tidak ada gang berjalan yang turun di bawah minAvailable, Anda punya bukti dari workload sendiri, bukan dari sebuah release post.
Aturan yang saya bawa dari v1.15: biarkan scheduler bernalar pada unit yang benar-benar gagal. Gang gagal sebagai gang, quota dihabiskan dalam device dan dimensi, dan autoscaler seharusnya hanya mendengar kekurangan node. Adopsi bagian yang bisa dibatalkan sekarang, dan perlakukan logika eviction Alpha sebagai sesuatu yang dibuktikan pada workload Anda sendiri.
Sumber dan bacaan lanjutan
- Blog Volcano: Volcano v1.15 dirilis
- GitHub Volcano: release note v1.15.0
- Docs Volcano: panduan scheduling gates queue admission
- Docs Volcano: plugin gang scheduler
- Docs Kubernetes: gang scheduling
- Docs Kubernetes: workload-aware preemption
- Docs Kubernetes: PodGroup API
- Docs Kubernetes: Pod scheduling readiness

