Kerangka Kerja Penjadwalan (Scheduling Framework)
Kubernetes 1.15 [alpha]
Kerangka kerja penjadwalan (Scheduling Framework) adalah arsitektur yang dapat dipasang (pluggable) pada penjadwal Kubernetes untuk membuat kustomisasi penjadwal lebih mudah. Hal itu dilakukan dengan menambahkan satu kumpulan "plugin" API ke penjadwal yang telah ada. Plugin dikompilasi ke dalam penjadwal. Beberapa API memungkinkan sebagian besar fitur penjadwalan diimplementasikan sebagai plugin, sambil tetap mempertahankan penjadwalan "inti" sederhana dan terpelihara. Silahkan merujuk pada [proposal desain dari kerangka penjadwalan] kep untuk informasi teknis lebih lanjut tentang desain kerangka kerja tersebut.
Alur kerja kerangka kerja
Kerangka kerja penjadwalan mendefinisikan beberapa titik ekstensi. Plugin penjadwal mendaftar untuk dipanggil di satu atau lebih titik ekstensi. Beberapa plugin ini dapat mengubah keputusan penjadwalan dan beberapa hanya bersifat informasi.
Setiap upaya untuk menjadwalkan satu Pod dibagi menjadi dua fase, Siklus Penjadwalan (Scheduling Cycle) dan Siklus Pengikatan (Binding Cycle).
Siklus Penjadwalan dan Siklus Pengikatan
Siklus penjadwalan memilih sebuah Node untuk Pod, dan siklus pengikatan menerapkan keputusan tersebut ke klaster. Secara bersama-sama, siklus penjadwalan dan siklus pengikatan diartikan sebagai sebuah "konteks penjadwalan (scheduling context)".
Siklus penjadwalan dijalankan secara serial, sementara siklus pengikatan dapat berjalan secara bersamaan.
Siklus penjadwalan atau pengikatan dapat dibatalkan jika Pod telah ditentukan untuk tidak terjadwalkan atau jika terdapat kesalahan internal. Pod akan dikembalikan ke antrian dan dicoba lagi.
Titik-titik ekstensi
Gambar berikut menunjukkan konteks penjadwalan Pod dan titik-titik ekstensi yang diperlihatkan oleh kerangka penjadwalan. Dalam gambar ini "Filter" setara dengan "Predicate" dan "Scoring" setara dengan "Priority Function".
Satu plugin dapat mendaftar di beberapa titik ekstensi untuk melakukan pekerjaan yang lebih kompleks atau stateful.
QueueSort
Plugin ini digunakan untuk mengurutkan Pod-Pod dalam antrian penjadwalan. Plugin
QueueSort pada dasarnya menyediakan fungsi Less (Pod1, Pod2)
. Hanya satu jenis
plugin QueueSort yang dapat diaktifkan dalam waktu yang bersamaan.
PreFilter
Plugin ini digunakan untuk melakukan pra-proses informasi tentang Pod, atau untuk memeriksa tertentu kondisi yang harus dipenuhi oleh klaster atau Pod. Jika plugin PreFilter menghasilkan hasil yang salah, siklus penjadwalan dibatalkan.
Filter
Plugin ini digunakan untuk menyaring Node yang tidak dapat menjalankan Pod. Untuk setiap Node, penjadwal akan memanggil plugin Filter sesuai dengan urutan mereka dikonfigurasi. Jika ada plugin Filter menandai Node menjadi infeasible, maka plugin yang lainnya tidak akan dipanggil untuk Node itu. Node-Node dapat dievaluasi secara bersamaan.
PostFilter
Plugin ini disebut setelah fase Filter, tetapi hanya ketika tidak ada node yang layak ditemukan untuk pod. Plugin dipanggil dalam urutan yang dikonfigurasi. Jika plugin postFilter menandai node sebagai 'Schedulable', plugin yang tersisa tidak akan dipanggil. Implementasi PostFilter yang khas adalah preemption, yang mencoba membuat pod dapat di menjadwalkan dengan mendahului Pod lain.
PreScore
Plugin ini digunakan untuk melakukan pekerjaan "pra-penilaian", yang menghasilkan keadaan yang dapat dibagi untuk digunakan oleh plugin-plugin Score. Jika plugin PreScore mengeluarkan hasil salah, maka siklus penjadwalan dibatalkan.
Score
Plugin ini digunakan untuk menentukan peringkat Node yang telah melewati fase penyaringan. Penjadwal akan memanggil setiap plugin Score untuk setiap Node. Akan ada kisaran bilangan bulat yang telah ditetapkan untuk mewakili skor minimum dan maksimum. Setelah fase NormalizeScore, penjadwal akan menggabungkan skor Node dari semua plugin sesuai dengan bobot plugin yang telah dikonfigurasi.
NormalizeScore
Plugin ini digunakan untuk memodifikasi skor sebelum penjadwal menghitung peringkat akhir Node-Node. Plugin yang mendaftar untuk titik ekstensi ini akan dipanggil dengan hasil Score dari plugin yang sama. Hal ini dilakukan sekali untuk setiap plugin dan setiap siklus penjadwalan.
Sebagai contoh, anggaplah sebuah plugin BlinkingLightScorer
memberi peringkat
pada Node-Node berdasarkan berapa banyak kedipan lampu yang mereka miliki.
func ScoreNode(_ *v1.pod, n *v1.Node) (int, error) {
return getBlinkingLightCount(n)
}
Namun, jumlah maksimum kedipan lampu mungkin kecil jika dibandingkan dengan
NodeScoreMax
. Untuk memperbaikinya, BlinkingLightScorer
juga harus mendaftar
untuk titik ekstensi ini.
func NormalizeScores(scores map[string]int) {
highest := 0
for _, score := range scores {
highest = max(highest, score)
}
for node, score := range scores {
scores[node] = score*NodeScoreMax/highest
}
}
Jika ada plugin NormalizeScore yang menghasilkan hasil yang salah, maka siklus penjadwalan dibatalkan.
Reserve
Ini adalah titik ekstensi yang bersifat informasi. Plugin yang mempertahankan keadaan runtime (alias "stateful plugins") harus menggunakan titik ekstensi ini untuk diberitahukan oleh penjadwal ketika sumber daya pada suatu Node dicadangkan untuk Pod yang telah disiapkan. Proses ini terjadi sebelum penjadwal benar-benar mengikat Pod ke Node, dan itu ada untuk mencegah kondisi balapan (race conditions) ketika penjadwal menunggu agar pengikatan berhasil.
Ini adalah langkah terakhir dalam siklus penjadwalan. Setelah Pod berada dalam status dicadangkan, maka itu akan memicu plugin Unreserve (apabila gagal) atau plugin PostBind (apabila sukses) di akhir siklus pengikatan.
Permit
Plugin Permit dipanggil pada akhir siklus penjadwalan untuk setiap Pod untuk mencegah atau menunda pengikatan ke Node kandidat. Plugin Permit dapat melakukan salah satu dari ketiga hal ini:
-
approve
Setelah semua plugin Permit menyetujui sebuah Pod, Pod tersebut akan dikirimkan untuk diikat. -
deny
Jika ada plugin Permit yang menolak sebuah Pod, Pod tersebut akan dikembalikan ke antrian penjadwalan. Hal ini akan memicu plugin Unreserve. -
wait (dengan batas waktu)
Jika plugin Permit menghasilkan "wait", maka Pod disimpan dalam daftar Pod "yang menunggu" internal, dan siklus pengikatan Pod ini dimulai tetapi akan langsung diblokir sampai mendapatkan approved. Jika waktu tunggu habis, ** wait ** menjadi ** deny ** dan Pod dikembalikan ke antrian penjadwalan, yang memicu plugin Unreserve.
FrameworkHandle
), kami hanya mengharapkan
plugin Permit untuk menyetujui pengikatan Pod dalam kondisi "menunggu" yang
telah dipesan. Setelah Pod disetujui, akan dikirim ke fase PreBind.
PreBind
Plugin ini digunakan untuk melakukan pekerjaan apa pun yang diperlukan sebelum Pod terikat. Sebagai contoh, plugin PreBind dapat menyediakan network volume dan melakukan mounting pada Node target sebelum mengizinkan Pod berjalan di sana.
Jika ada plugin PreBind yang menghasilkan kesalahan, maka Pod ditolak dan kembali ke antrian penjadwalan.
Bind
Plugin ini digunakan untuk mengikat Pod ke Node. Plugin-plugin Bind tidak akan dipanggil sampai semua plugin PreBind selesai. Setiap plugin Bind dipanggil sesuai urutan saat dikonfigurasi. Plugin Bind dapat memilih untuk menangani atau tidak Pod yang diberikan. Jika plugin Bind memilih untuk menangani Pod, ** plugin Bind yang tersisa dilewati **.
PostBind
Ini adalah titik ekstensi bersifat informasi. Plugin-plugin PostBind dipanggil setelah sebuah Pod berhasil diikat. Ini adalah akhir dari siklus pengikatan, dan dapat digunakan untuk membersihkan sumber daya terkait.
Unreserve
Ini adalah titik ekstensi bersifat informasi. Jika sebuah Pod telah dipesan dan kemudian ditolak di tahap selanjutnya, maka plugin-plugin Unreserve akan diberitahu. Plugin Unreserve harus membersihkan status yang terkait dengan Pod yang dipesan.
Plugin yang menggunakan titik ekstensi ini sebaiknya juga harus digunakan Reserve.
Plugin API
Ada dua langkah untuk plugin API. Pertama, plugin harus mendaftar dan mendapatkan konfigurasi, kemudian mereka menggunakan antarmuka titik ekstensi. Antarmuka (interface) titik ekstensi memiliki bentuk sebagai berikut.
type Plugin interface {
Name() string
}
type QueueSortPlugin interface {
Plugin
Less(*v1.pod, *v1.pod) bool
}
type PreFilterPlugin interface {
Plugin
PreFilter(context.Context, *framework.CycleState, *v1.pod) error
}
// ...
Konfigurasi plugin
Kamu dapat mengaktifkan atau menonaktifkan plugin dalam konfigurasi penjadwal. Jika kamu menggunakan Kubernetes v1.18 atau yang lebih baru, kebanyakan plugin-plugin penjadwalan sudah digunakan dan diaktifkan secara bawaan.
Selain plugin-plugin bawaan, kamu juga dapat mengimplementasikan plugin-plugin penjadwalan kamu sendiri dan mengonfigurasinya bersama-sama dengan plugin-plugin bawaan. Kamu bisa mengunjungi plugin-plugin penjadwalan untuk informasi lebih lanjut.
Jika kamu menggunakan Kubernetes v1.18 atau yang lebih baru, kamu dapat mengonfigurasi sekumpulan plugin sebagai profil penjadwal dan kemudian menetapkan beberapa profil agar sesuai dengan berbagai jenis beban kerja. Pelajari lebih lanjut di multi profil.