QoS Class #

Ketika node kehabisan memory — situasi yang disebut node pressure — Kubernetes perlu memutuskan Pod mana yang harus dikorbankan terlebih dahulu. Keputusan ini bukan acak: Kubernetes menggunakan sistem Quality of Service (QoS) class yang ditentukan secara otomatis berdasarkan cara kamu mendefinisikan resource request dan limit. Memahami QoS class berarti memahami bagaimana Kubernetes memprioritaskan kelangsungan Pod saat kondisi cluster di bawah tekanan.

Tiga QoS Class #

Kubernetes secara otomatis mengategorikan setiap Pod ke salah satu dari tiga QoS class berdasarkan resource request dan limit yang didefinisikan. Kamu tidak memilih class secara eksplisit — class ditentukan dari konfigurasi resource yang kamu tulis.

Guaranteed #

Pod mendapat class Guaranteed jika setiap container dalam Pod memiliki request dan limit yang identik untuk CPU dan memory, dan keduanya tidak boleh nol.

# Pod dengan QoS class: Guaranteed

spec:
  containers:
  - name: api
    resources:
      requests:
        cpu: "500m"
        memory: "256Mi"
      limits:
        cpu: "500m"       # harus sama dengan request
        memory: "256Mi"   # harus sama dengan request
  - name: sidecar
    resources:
      requests:
        cpu: "100m"
        memory: "64Mi"
      limits:
        cpu: "100m"       # setiap container harus Guaranteed
        memory: "64Mi"

Pod Guaranteed adalah yang paling terakhir dievict. Kubernetes hanya akan mengorbankan Pod ini jika tidak ada pilihan lain — misalnya jika Pod Guaranteed sendiri yang menyebabkan memory pressure.

Burstable #

Pod mendapat class Burstable jika setidaknya satu container memiliki request atau limit (tapi tidak keduanya identik untuk semua container), atau jika request ada tapi limit tidak ada.

# Pod dengan QoS class: Burstable

spec:
  containers:
  - name: api
    resources:
      requests:
        cpu: "250m"
        memory: "128Mi"
      limits:
        cpu: "500m"       # limit berbeda dari request → Burstable
        memory: "256Mi"

# Juga Burstable:
  - name: worker
    resources:
      requests:
        cpu: "100m"
        memory: "64Mi"
      # tidak ada limits → Burstable

Pod Burstable dievict setelah semua Pod BestEffort habis. Urutan eviction di antara Pod Burstable ditentukan oleh seberapa jauh penggunaan memory mereka melampaui request.

BestEffort #

Pod mendapat class BestEffort jika tidak ada container yang mendefinisikan request atau limit — keduanya harus kosong.

# Pod dengan QoS class: BestEffort

spec:
  containers:
  - name: batch-worker
    image: my-batch:v1
    # tidak ada resources field sama sekali

Pod BestEffort adalah yang pertama dievict saat node kehabisan resource. Mereka diperlakukan sebagai workload oportunistik yang menggunakan sisa resource yang tidak diklaim Pod lain.


Cara Kubernetes Menentukan QoS Class #

Algoritma penentuan QoS class:

Untuk setiap container dalam Pod:
  Apakah requests.cpu == limits.cpu != 0?
  DAN requests.memory == limits.memory != 0?

Jika SEMUA container memenuhi kondisi di atas → Guaranteed

Jika setidaknya SATU container punya requests atau limits
  (tapi tidak semua Guaranteed) → Burstable

Jika TIDAK ADA container yang punya requests atau limits → BestEffort
# Lihat QoS class sebuah Pod
kubectl get pod <pod-name> -o yaml | grep qosClass

# Atau
kubectl describe pod <pod-name> | grep QoS
# QoS Class: Guaranteed

Urutan Eviction #

Saat node mengalami memory pressure, kubelet mulai melakukan eviction Pod dengan urutan berikut:

Urutan eviction (dari pertama ke terakhir dikorbankan):

1. BestEffort (tidak ada request/limit)
   → Tidak ada jaminan resource sama sekali
   → Pertama dikorbankan

2. Burstable (melebihi request-nya)
   → Di antara Pod Burstable, yang paling banyak melampaui request-nya
     dievict lebih dulu
   → Pod yang masih dalam batas request-nya dikorbankan lebih belakangan

3. Guaranteed (atau Burstable yang masih dalam batas request)
   → Paling terakhir dikorbankan
   → Hanya jika tidak ada pilihan lain

Lebih spesifik untuk Burstable: jika ada dua Pod Burstable dengan memory request 100Mi, tapi Pod A menggunakan 200Mi dan Pod B menggunakan 110Mi, Pod A dievict lebih dulu karena ia melebihi request-nya dua kali lipat sementara Pod B hanya sedikit.


Memory QoS (cgroups v2) #

Di cluster yang menggunakan cgroups v2 (Linux kernel modern), Kubernetes 1.22+ mendukung Memory QoS — fitur yang memberikan jaminan memory lebih tepat:

Dengan Memory QoS aktif:

Guaranteed Pod:
  memory.min = request = limit (jaminan penuh)

Burstable Pod:
  memory.min = request (dijamin tersedia)
  memory.high = limit * 0.8 (mulai throttle sebelum OOMKill)
  memory.max = limit (batas keras)

BestEffort Pod:
  memory.min = 0 (tidak ada jaminan)

Ini membuat eviction lebih gradual — container Burstable di-throttle terlebih dahulu sebelum di-kill, memberikan kesempatan untuk menurunkan penggunaan memory sendiri.


Implikasi Desain untuk Produksi #

Pemilihan QoS class harus disengaja berdasarkan kritikalitas workload:

Panduan memilih QoS class untuk produksi:

Workload kritikal (database, payment service, auth):
  → Tujuan: Guaranteed
  → Pastikan request == limit untuk CPU dan memory
  → Trade-off: utilisasi node lebih rendah, resource di-reserve sepenuhnya

Workload penting tapi bisa toleransi brief slowdown (API biasa, background job):
  → Tujuan: Burstable
  → Request 50-70% dari penggunaan rata-rata, limit 2-3x request
  → Trade-off: utilisasi lebih tinggi, tapi bisa terkena eviction saat node stress

Workload oportunistik (batch job, development environment, scraper):
  → Bisa BestEffort jika ada mekanisme retry dan tidak ada SLA
  → Trade-off: tidak ada jaminan sama sekali, pertama dikorbankan
  → Gunakan dengan hati-hati di cluster shared dengan workload produksi

Namespace-level Protection dengan ResourceQuota #

Di multi-tenant cluster, namespace produksi bisa dilindungi dengan memastikan semua Pod di namespace tersebut minimal Burstable:

apiVersion: v1
kind: LimitRange
metadata:
  name: require-requests
  namespace: production
spec:
  limits:
  - type: Container
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    default:
      cpu: "500m"
      memory: "256Mi"
# Dengan LimitRange ini, tidak ada Pod yang bisa menjadi BestEffort
# karena semua Pod yang tidak punya request akan mendapat default dari LimitRange

Ringkasan #

  • QoS class ditentukan otomatis — Kubernetes menentukannya dari konfigurasi resource yang kamu tulis; tidak ada field eksplisit untuk memilih class.
  • Guaranteed: request == limit — untuk semua container di Pod; paling aman dari eviction tapi paling konservatif dalam penggunaan resource.
  • Burstable: punya request atau limit — dievict setelah BestEffort; urutan eviction di antara Burstable berdasarkan seberapa jauh melampaui request-nya.
  • BestEffort: tanpa request dan limit — pertama dievict; cocok hanya untuk workload yang bisa di-restart kapan saja dan tidak punya SLA.
  • Urutan eviction = BestEffort → Burstable → Guaranteed — Kubernetes melindungi Pod yang lebih terjamin saat node kehabisan resource.
  • LimitRange mencegah Pod BestEffort di namespace produksi — dengan menetapkan default request, tidak ada Pod yang bisa masuk ke class BestEffort secara tidak sengaja.

← Sebelumnya: Resource Request & Limit   Berikutnya: Ephemeral vs Persistent Storage →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact