Scheduler Workflow #
Di dalam kluster Kubernetes, menempatkan beban kerja (workloads) pada perangkat keras yang paling tepat merupakan faktor penentu utama dari kestabilan, performa, dan efisiensi biaya infrastruktur kita. Komponen yang memikul tanggung jawab besar ini adalah kube-scheduler. Kube-scheduler bertindak sebagai otak penentu keputusan yang secara konstan memantau Pod baru yang belum memiliki node, mengevaluasi seluruh kapasitas fisik kluster, dan menunjuk node worker terbaik untuk menjalankan beban kerja tersebut.
Namun, bagaimana sebenarnya keputusan penjadwalan ini diambil dari balik layar? Bagaimana kube-scheduler memilah ratusan node hanya dalam hitungan milidetik? Dan yang terpenting, apa yang harus kita lakukan ketika Pod kita tertahan dengan status Pending di lingkungan produksi? Artikel ini akan mengupas tuntas alur kerja kube-scheduler secara end-to-end, arsitektur antrean internalnya, detail fase filter dan scoring, mekanisme penyingkiran (preemption), hingga panduan taktis untuk mendiagnosis masalah penjadwalan.
Alur Kerja End-to-End: Dari YAML Hingga Kontainer Aktif #
Proses penjadwalan sebuah Pod bukanlah operasi tunggal yang instan, melainkan rangkaian interaksi terdistribusi yang melibatkan berbagai komponen di dalam kluster. Kita perlu memahami siklus hidup ini agar dapat mengidentifikasi titik kegagalan (bottleneck) dengan presisi.
Berikut adalah urutan proses yang dilalui sejak kita mengirimkan manifes YAML hingga kontainer berjalan di node worker:
flowchart TD
PodArrival["Pod Baru Dideteksi (status: Pending, nodeName: '')"] --> Queue["Scheduling Queue (activeQ)"]
Queue --> Dequeue["Ambil Pod dengan Prioritas Tertinggi"]
subgraph FilteringPhase ["Fase 1: Filtering (Predicates)"]
Dequeue --> FilterStart["Evaluasi Semua Node Kluster Secara Paralel"]
FilterStart --> Filter1["NodeUnschedulable: Cek status cordon node"]
FilterStart --> Filter2["PodFitsResources: Cek CPU & RAM request"]
FilterStart --> Filter3["NodePorts: Cek tabrakan port kontainer"]
FilterStart --> Filter4["NodeAffinity & Taints: Cocokkan label & tolerasi"]
Filter1 --> FilterMerge["Gabungkan Hasil Filter"]
Filter2 --> FilterMerge
Filter3 --> FilterMerge
Filter4 --> FilterMerge
end
FilterMerge --> CheckCandidates{"Apakah ada node\nyang lolos?"}
CheckCandidates -- "Tidak" --> Unscheduled["Masukkan ke unschedulableQ (Gagal Jadwal)"]
CheckCandidates -- "Ya" --> ScoringPhase
subgraph ScoringPhase ["Fase 2: Scoring (Priorities)"]
ScoreStart["Beri Nilai 0-100 pada Semua Node yang Lolos"]
ScoreStart --> Score1["LeastAllocated: Prioritaskan node yang sepi"]
ScoreStart --> Score2["ImageLocality: Prioritaskan node yang punya image"]
ScoreStart --> Score3["NodeAffinityPriority: Hitung bobot afinitas opsional"]
Score1 --> ScoreMerge["Hitung Weighted Sum (Skor Akhir)"]
Score2 --> ScoreMerge
Score3 --> ScoreMerge
end
CheckCandidates -- "Ya" --> ScoreStart
ScoreMerge --> SelectWinner["Pilih Node dengan Skor Tertinggi"]
subgraph BindingPhase ["Fase 3: Binding"]
SelectWinner --> BindCreate["Buat Objek Binding di API Server"]
BindCreate --> BindWrite["Tulis nodeName ke Objek Pod di Etcd"]
BindWrite --> KubeletWatch["Kubelet Node Terpilih Mendeteksi Watch Event"]
KubeletWatch --> ContainerStart["Mulai Jalankan Kontainer Aplikasi"]
end
Penjelasan 7 Tahap Pemrosesan Utama: #
- Pengiriman Manifes dan Validasi: Kita menjalankan perintah
kubectl apply -f deployment.yaml. API Server menerima request tersebut, melakukan autentikasi, otorisasi, dan melewatkannya ke Admission Controller. Jika lolos, objek Deployment akan disimpan ke dalam database etcd. - Pembuatan Objek Pod: Kontroler Deployment mendeteksi objek baru tersebut dan membuat objek ReplicaSet. Replicaset Controller kemudian membuat replika Pod sesuai jumlah yang kita inginkan (misalnya 3). Pod yang baru dibuat ini disimpan di etcd dengan status awal
Pendingdan tanpa memiliki propertispec.nodeName(bernilai string kosong""). - Watch API Detection: Kube-scheduler memiliki koneksi persisten ke API Server menggunakan mekanisme Watch API. Begitu kube-scheduler mendeteksi adanya Pod baru yang belum memiliki
nodeName, ia akan langsung memasukkan Pod tersebut ke dalam antrean penjadwalannya sendiri. - Fase Filtering (Predicates): Kube-scheduler memindai seluruh node di kluster dan mengeliminasi node-node yang tidak memenuhi syarat minimal (misalnya karena kekurangan CPU/RAM, memiliki taint yang tidak ditoleransi, atau melanggar aturan afinitas).
- Fase Scoring (Priorities): Node-node yang lolos fase filtering akan dinilai menggunakan serangkaian fungsi penilaian. Setiap kriteria (seperti efisiensi pemakaian memori, keberadaan image kontainer lokal, dll.) memiliki skor dari 0 hingga 100 yang kemudian dikalikan dengan bobot masing-masing plugin untuk menghasilkan skor akhir global per node.
- Optimistic Binding: Kube-scheduler memilih node dengan skor tertinggi. Sebelum menulis data ke etcd, ia akan melakukan optimistic binding secara lokal di memori cache scheduler guna menghindari tabrakan jika ada Pod lain yang sedang dijadwalkan secara paralel. Setelah aman, ia mengirimkan objek
Bindingke API Server untuk menulisspec.nodeNamedari Pod tersebut di etcd. - Eksekusi Kubelet: Kubelet yang berjalan di node worker terpilih secara berkala memonitor API Server untuk mencari Pod yang ditugaskan ke namanya. Begitu mendeteksi adanya Pod baru dengan
nodeNamemiliknya, Kubelet akan menginstruksikan container runtime (seperti containerd) untuk mengunduh image, menyiapkan network, me-mount storage volume, dan mulai menjalankan kontainer.
Arsitektur Antrean Internal (Scheduling Queue) #
Kube-scheduler tidak memproses Pod secara acak. Ia mengelola antrean internal yang sangat efisien untuk memastikan Pod yang siap dijadwalkan diproses terlebih dahulu, sementara Pod yang gagal dijadwalkan tidak membuang-buang siklus CPU kluster secara sia-sia.
Antrean ini terbagi menjadi tiga struktur data utama:
[Antrean Kube-Scheduler]
│
├──► activeQ (Antrean Aktif)
│ Pod yang siap dijadwalkan sekarang. Diurutkan berdasarkan prioritas.
│
├──► backoffQ (Antrean Penangguhan Sementara)
│ Pod yang baru saja gagal dijadwalkan karena keterbatasan resource.
│ Menunggu durasi penangguhan sebelum dicoba kembali.
│
└──► unschedulableQ (Antrean Gagal / Tidak Layak)
Pod yang sudah dicoba namun terbukti tidak memiliki node yang cocok.
Menunggu perubahan status kluster untuk dicoba kembali.
1. activeQ (Active Queue)
#
Ini adalah antrean utama tempat kube-scheduler mengambil Pod berikutnya untuk dijadwalkan. Antrean ini diimplementasikan sebagai heap prioritas. Pod dengan nilai prioritas tertinggi (berdasarkan PriorityClass yang kita tetapkan) akan otomatis melompat ke urutan terdepan antrean untuk diproses terlebih dahulu.
2. backoffQ (Backoff Queue)
#
Ketika sebuah Pod gagal dijadwalkan (misalnya karena tidak ada node yang cukup memori saat itu), Pod tidak boleh langsung kembali ke antrean aktif. Jika langsung kembali, ia akan memicu perulangan tak berujung (busy loop) yang membebani CPU.
Sebaliknya, Pod dipindahkan ke backoffQ. Di sini, Pod harus menunggu durasi tertentu (backoff period) yang meningkat secara eksponensial setelah setiap kegagalan beruntun. Setelah masa tunggu selesai, Pod akan dipindahkan kembali ke activeQ.
3. unschedulableQ (Unschedulable Queue)
#
Jika setelah beberapa kali percobaan Pod tetap tidak dapat menemukan node yang cocok, ia dipindahkan ke unschedulableQ. Di sini, Pod akan tinggal secara pasif tanpa mengonsumsi siklus CPU scheduler.
Pod di dalam unschedulableQ hanya akan dipindahkan kembali ke activeQ jika terjadi peristiwa perubahan pada kluster yang berpotensi menyelesaikan masalah mereka. Peristiwa pemicu ini meliputi:
- Bergabungnya node worker baru ke dalam kluster.
- Pembaruan atau penghapusan Pod lain yang membebaskan resource CPU/RAM.
- Perubahan label pada node worker.
- Penghapusan taints dari node.
Filtering Pipeline (Predicates) Secara Mendalam #
Fase filtering bertujuan untuk mengeliminasi semua node worker yang secara fisik atau logis tidak dapat menjalankan Pod kita. Kube-scheduler menjalankan filter-filter ini secara paralel untuk meningkatkan kecepatan proses.
Berikut adalah daftar filter inti yang wajib kita pahami karena sering kali menjadi penyebab Pod stuck di status Pending:
1. PodFitsResources
#
Filter ini memeriksa apakah kapasitas sisa yang dapat dialokasikan (allocatable resource) pada node mencukupi untuk memenuhi nilai resource requests (CPU, RAM, dan Ephemeral Storage) yang dideklarasikan oleh kontainer-kontainer di dalam Pod kita.
[!IMPORTANT] Filter ini hanya menghitung nilai
request, bukanlimit. Jika sebuah node memiliki sisa memori allocatable sebesar 2GiB, dan Pod kita memintarequests: 4GiBnamun memilikilimits: 8GiB, node tersebut akan langsung dieliminasi karena sisa memori fisik tidak cukup untuk menampung batas minimal request.
2. NodeUnschedulable
#
Filter ini mendeteksi apakah node worker sedang berada dalam kondisi cordon (spec.unschedulable: true). Jika kita menjalankan pemeliharaan node dan menandainya dengan perintah kubectl cordon node-1, filter ini secara otomatis mengeliminasi node-1 dari proses penjadwalan Pod baru.
3. NodePorts
#
Jika kontainer kita mendefinisikan port host secara eksplisit menggunakan hostPort (misalnya memetakan port kontainer 80 langsung ke port 80 pada node fisik), filter ini akan menyaring node worker. Jika port 80 pada sebuah node sudah digunakan oleh Pod lain, node tersebut akan dieliminasi guna menghindari tabrakan port jaringan.
4. NodeAffinity & PodSelector
#
Filter ini mencocokkan ekspresi aturan afinitas node (nodeSelector atau nodeAffinity) yang kita tulis pada spesifikasi Pod dengan label-label yang melekat pada node worker fisik. Node yang tidak memiliki label yang sesuai akan langsung disingkirkan.
5. TaintToleration
#
Filter ini mengevaluasi apakah node worker memiliki taint (misalnya key=value:NoSchedule). Node yang di-taint hanya dapat menerima Pod yang memiliki deklarasi toleration yang cocok. Jika Pod kita tidak memilikinya, filter ini akan mengeliminasi node tersebut.
Scoring Pipeline (Priorities) Secara Mendalam #
Setelah fase filtering selesai, kube-scheduler akan mendapatkan daftar node kandidat yang layak. Untuk memilih node terbaik di antara yang layak, scheduler akan menilai masing-masing node tersebut di fase scoring.
Setiap fungsi penilaian (Scoring Plugin) akan menghasilkan nilai dari 0 hingga 100. Skor total dihitung menggunakan rumus penjumlahan berbobot (weighted sum):
$$\text{Skor Akhir Node} = \sum_{i=1}^{n} (\text{Skor Plugin}_i \times \text{Bobot Plugin}_i)$$
Berikut adalah beberapa fungsi scoring default yang memainkan peran penting dalam menentukan lokasi penempatan Pod kita:
1. LeastAllocated (Bobot Default: 1)
#
Plugin ini memprioritaskan node yang memiliki sisa resource CPU/RAM paling besar setelah dikurangi total request seluruh Pod yang berjalan di atasnya. Rumus internalnya adalah:
$$\text{Skor} = \frac{(\text{Kapasitas} - \text{Total Requests}) \times 100}{\text{Kapasitas}}$$
Tujuan utama dari LeastAllocated adalah untuk menyebarkan beban kerja secara merata ke seluruh node worker yang tersedia (resource spreading), sehingga mencegah satu node menjadi sangat panas sementara node lain menganggur.
2. ImageLocality (Bobot Default: 1)
#
Plugin ini memberikan skor lebih tinggi pada node worker yang sudah mengunduh (cache) image kontainer yang dibutuhkan oleh Pod kita secara lokal.
- Jika image berukuran 2GiB sudah ada di
node-1tetapi belum ada dinode-2, makanode-1akan mendapatkan skorImageLocalityyang jauh lebih tinggi. - Hal ini dirancang untuk mempercepat startup Pod dengan menghindari waktu tunggu penarikan (pulling) image dari container registry eksternal.
3. BalancedResourceAllocation (Bobot Default: 1)
#
Plugin ini menilai seberapa seimbang pemakaian CPU dan RAM di dalam node. Ia mencari node yang memiliki rasio pemakaian CPU dan memori yang setara setelah Pod ditempatkan.
- Jika kita menempatkan Pod yang boros memori pada node yang sudah kekurangan memori namun melimpah CPU-nya, rasio ini menjadi tidak seimbang.
- Plugin ini berusaha menghindari fragmentasi resource di mana sebuah node worker kehabisan RAM total namun menyisakan 90% CPU yang akhirnya tidak bisa digunakan oleh siapa pun.
4. NodeAffinityPriority (Bobot Default: 2)
#
Plugin ini mengevaluasi aturan afinitas pilihan (soft affinity atau preferredDuringSchedulingIgnoredDuringExecution). Jika sebuah node memenuhi kriteria label pilihan yang kita inginkan, plugin ini memberikan skor tambahan yang tinggi. Karena ini adalah instruksi dari developer, bobotnya diset lebih tinggi daripada fungsi balancing default.
Pod Priority dan Preemption (Penyingkiran Workload) #
Di lingkungan produksi dengan tingkat kepadatan tinggi (high-density clusters), kita sering kali dihadapkan pada situasi di mana kluster kehabisan resource fisik sepenuhnya. Ketika hal ini terjadi dan kita perlu mendeploy Pod yang sangat penting (misalnya API gateway utama), bagaimana caranya agar Pod tersebut tetap dapat berjalan?
Kubernetes menyediakan fitur Pod Priority and Preemption yang memungkinkan Pod dengan prioritas tinggi untuk menyingkirkan (evict) Pod dengan prioritas rendah demi mendapatkan resource.
1. Mendefinisikan Objek PriorityClass
#
Pertama, kita harus membuat objek PriorityClass yang menentukan nilai bobot prioritas secara administratif:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-api-priority
value: 1000000 # Nilai integer (maksimal 1.000.000.000)
globalDefault: false # Jika true, semua Pod tanpa priority akan mendapatkan nilai ini
description: "Prioritas tinggi untuk API Gateway utama produksi."
2. Menerapkan PriorityClass pada Spesifikasi Pod #
Kita menghubungkan prioritas ini pada manifes spesifikasi Pod kita menggunakan properti priorityClassName:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
namespace: production
spec:
replicas: 2
template:
spec:
priorityClassName: critical-api-priority # Menghubungkan ke PriorityClass
containers:
- name: gateway-app
image: company/gateway:v1.1
resources:
requests:
cpu: "2"
memory: "4Gi"
Mekanisme Kerja Preemption (Penyingkiran): #
Ketika Pod api-gateway yang memiliki prioritas tinggi masuk ke antrean activeQ, kube-scheduler mencoba mencari node yang layak di fase filtering. Jika tidak ditemukan node yang memiliki sisa CPU 2 Core dan RAM 4GiB, preemption loop akan aktif:
flowchart TD
NoResource["Pod Prioritas Tinggi Stuck (Tidak Ada Resource)"] --> PreemptActive["Aktifkan Mekanisme Preemption"]
PreemptActive --> FindVictims["Cari Node Yang Memiliki Pod Prioritas Lebih Rendah"]
FindVictims --> EvaluateNode{"Apakah Menyingkirkan Pod\nTersebut Membebaskan Resource?"}
EvaluateNode -- "Tidak" --> TryNextNode["Evaluasi Node Worker Berikutnya"]
EvaluateNode -- "Ya" --> EvictTarget["Kirim Sinyal Terminasi (Evict) ke Pod Prioritas Rendah"]
EvictTarget --> WaitGrace["Tunggu Grace Period Selesai (SIGKILL)"]
WaitGrace --> ScheduleWinner["Jadwalkan Pod Prioritas Tinggi di Node Tersebut"]
- Evaluasi Calon Korban: Kube-scheduler mencari node worker yang jika Pod dengan prioritas lebih rendah di dalamnya dihentikan, akan membebaskan resource yang cukup untuk Pod prioritas tinggi kita.
- Pemilihan Node Korban Terkecil: Scheduler mencoba meminimalkan dampak pengusiran. Ia akan memilih node yang memiliki total prioritas Pod terkecil agar tidak mengganggu aplikasi penting lainnya.
- Terminasi Pod Korban: Scheduler menandai properti
preemptorpada Pod prioritas tinggi dan mengirimkan sinyal terminasi (eviction) ke Pod prioritas rendah. Pod prioritas rendah mendapatkan masa tenggang (grace period) normal untuk shutdown bersih. - Penjadwalan Ulang: Setelah Pod prioritas rendah mati dan membebaskan memori, scheduler menempatkan Pod prioritas tinggi kita ke node tersebut. Pod prioritas rendah yang terusir akan dikirim kembali ke scheduling queue untuk dicarikan node lain (jika ada).
Panduan Praktis Mendiagnosis Masalah Scheduling #
Sebagai administrator kluster, kita harus dapat membedakan dengan cepat apakah kegagalan startup Pod disebabkan oleh masalah jaringan, penyimpanan, bug kode aplikasi, atau murni masalah keputusan penjadwalan oleh kube-scheduler.
Berikut adalah langkah-langkah sistematis untuk mendiagnosis masalah scheduling:
1. Memeriksa Kejadian (Events) Pod #
Langkah pertama yang wajib kita lakukan adalah memeriksa riwayat kejadian yang dicatat oleh API Server pada objek Pod kita:
kubectl describe pod <nama-pod> -n <namespace>
Gulir ke bagian paling bawah manifest output untuk melihat bagian Events. Jika masalahnya berada di kube-scheduler, kita akan melihat peringatan FailedScheduling:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 45s default-scheduler 0/3 nodes are available: 1 node(s) were unschedulable, 2 Insufficient cpu.
2. Membaca Status Alokasi Resource Node Worker #
Jika kita mendapatkan pesan Insufficient cpu atau Insufficient memory, kita harus memeriksa kapasitas sisa yang tersisa di seluruh node fisik kluster:
kubectl describe nodes | grep -A 8 "Allocated resources"
Output ini menunjukkan persentase alokasi resource yang telah diklaim oleh seluruh Pod yang aktif berjalan:
Allocated resources:
Resource Requests Limits
-------- -------- ------
cpu 3650m (91%) 8000m (200%)
memory 6920Mi (86%) 12200Mi (152%)
[!NOTE] Perhatikan bahwa persentase alokasi dihitung berdasarkan nilai
Requests. Jika alokasi CPU request sudah mencapai 91%, maka kube-scheduler tidak akan mengizinkan Pod baru yang meminta CPU request besar untuk masuk ke node tersebut, meskipun pemakaian CPU riil saat itu mungkin masih sangat rendah (misalnya hanya 10%).
3. Mengidentifikasi Taint dan Label Node #
Jika pesan error menyatakan node(s) had untolerated taint, periksa taint apa saja yang terpasang pada node kita:
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
Pastikan spesifikasi Pod kita memiliki deklarasi tolerations yang cocok untuk melewati batasan taint tersebut.
4. Membaca Log Internal Kube-Scheduler #
Untuk kasus-kasus pelacakan tingkat lanjut, kita dapat membaca log internal dari proses kube-scheduler itu sendiri. Jika kita menggunakan kluster self-managed (di mana scheduler berjalan sebagai static pod di node control plane), kita bisa membacanya dengan perintah:
kubectl logs -n kube-system -l component=kube-scheduler
Anti-Pattern dalam Manajemen Penjadwalan #
Berikut adalah dua kesalahan fatal yang sering kali melumpuhkan kluster produksi akibat salah konfigurasi penjadwalan:
Anti-Pattern 1: Melakukan Modifikasi Berkas Konfigurasi Scheduler Manual pada Kluster Managed #
Mencoba mengubah perilaku algoritma scoring dengan memodifikasi konfigurasi biner di master node pada layanan managed cloud.
ANTI-PATTERN: Mengubah Kube-Scheduler Policy Config secara Manual di GKE/EKS Control Plane
// KITA MELAKUKAN:
- Kita masuk lewat SSH ke VM control plane (master node) pada kluster managed cloud (GKE/EKS).
- Kita memodifikasi berkas konfigurasi `kube-scheduler.yaml` secara manual untuk mengubah bobot plugin scoring.
// KONSEKUENSI DI PRODUKSI:
- Kehilangan Support: Provider cloud akan mendeteksi adanya modifikasi tidak sah pada control plane.
- Siklus Update Rusak: Saat provider melakukan auto-upgrade kluster (misalnya dari versi 1.28 ke 1.29),
konfigurasi manual kita akan tertimpa atau bahkan menyebabkan proses instalasi upgrade macet total.
- Ketidakstabilan Kluster: Modifikasi konfigurasi scheduler secara mentah tanpa dukungan replikasi
yang baik dapat memicu split-decision pada leader election kube-scheduler.
✓ SOLUSI YANG BENAR:
- Di lingkungan cloud managed, jangan pernah menyentuh berkas konfigurasi biner di control plane.
- Jika kita membutuhkan pengaturan penjadwalan khusus, buat objek Kube-Scheduler Profiles baru
melalui manifest KubeSchedulerConfiguration, lalu deploy sebagai custom scheduler pendamping (Multiple Schedulers).
- Tentukan `schedulerName: custom-scheduler-kita` pada spesifikasi Pod yang ingin menggunakan aturan tersebut.
Anti-Pattern 2: Menyetel Resource Requests Terlalu Rendah demi Meloloskan Fase Filtering #
Menipu filter PodFitsResources dengan menurunkan nilai requests secara ekstrem, sementara limits dibiarkan sangat tinggi.
ANTI-PATTERN: Menulis CPU Requests: 10m (0.01 Core) tetapi Limits: 4000m (4 Cores) untuk Aplikasi Web Java
// KITA MELAKUKAN:
- Karena kluster kita padat dan kita ingin Pod web Java kita cepat berjalan tanpa terhambat
status Pending, kita memanipulasi spesifikasi Pod dengan menyetel request CPU yang sangat kecil (10m).
- Namun, kita tahu Java membutuhkan banyak CPU saat startup, sehingga kita menyetel limits setinggi 4 Cores.
// KONSEKUENSI DI PRODUKSI:
- Overcommitment Ekstrem: Kube-scheduler akan mempercayai angka 10m tersebut dan menumpuk puluhan Pod Java
pada satu node worker yang sama karena menduga beban kerjanya sangat ringan.
- CPU Throttling Massal: Saat seluruh Pod Java tersebut melakukan startup secara bersamaan, mereka akan berebut
kapasitas CPU fisik node. Akibatnya, latensi aplikasi melonjak drastis, liveness probe hang, dan kluster menjadi tidak responsif.
- OOMKilled Berantai: Perilaku yang sama pada memori akan memicu Kubelet di node tersebut untuk membunuh
kontainer-kontainer kita secara acak akibat kehabisan memori fisik (Out of Memory).
✓ SOLUSI YANG BENAR:
- Selalu setel nilai `resource requests` sedekat mungkin dengan profil pemakaian CPU/RAM riil aplikasi saat berjalan.
- Gunakan bantuan Vertical Pod Autoscaler (VPA) di lingkungan staging untuk merekomendasikan angka request yang akurat.
- Gunakan LimitRange untuk membatasi rasio maksimal antara request dan limit agar developer tidak menulis deviasi yang terlalu jauh.
Ringkasan #
- Pipeline Penjadwalan Dua Fase — Kube-scheduler menentukan node worker melalui dua fase utama: Filtering (mengeliminasi node yang tidak layak) dan Scoring (memberi nilai node yang lolos untuk mencari yang terbaik).
- Proses Berbasis Request — Ingat bahwa keputusan penyaringan resource (
PodFitsResources) hanya memperhitungkan nilairequests, bukanlimitspada kontainer.- Pembersihan Antrean Cerdas — Penjadwal membagi antrean menjadi
activeQ(siap diproses),backoffQ(tunda sementara), danunschedulableQ(gagal terparkir) guna menghemat pemakaian CPU master node.- Image Locality Priority — Kube-scheduler memprioritaskan node worker yang sudah memiliki cache image kontainer lokal untuk menghemat waktu penarikan image dari registry.
- Downward API untuk Indeks — Manfaatkan fitur
JOB_COMPLETION_INDEXuntuk memisahkan pengerjaan rentang data secara efisien antar-Pod yang berjalan secara paralel.- Preemption untuk Workload Kritis — Konfigurasikan
PriorityClassagar Pod produksi yang kritis dapat menyingkirkan Pod non-kritis saat kluster mengalami kelangkaan resource fisik.- Investigasi Via Events — Gunakan perintah
kubectl describe poduntuk membaca pesan kegagalan scheduling yang dicatat oleh scheduler di bagian Events.
← Sebelumnya: Job & CronJob Berikutnya: Resource Request & Limit →