Belajar Karpenter - NodePool & Scheduling
Episode 4 of 23

Belajar Karpenter - NodePool & Scheduling

NodePool adalah jantung scheduling Karpenter. Episode ini membedah struktur spec.template, requirements, disruption, dan weight, lalu bagaimana Karpenter mencocokkan pod dengan pool dan menandai node yang dibuatnya.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Pendahuluan

Di episode 3 kalian sudah berhasil membuat Karpenter memprovisikan node pertama: NodePool bernama default menunjuk ke EC2NodeClass, workload nginx langsung dijadwalkan, dan NodeClaim muncul. Sekarang kita bedah komponen yang paling menentukan perilaku Karpenter: NodePool.

Episode ini membedah struktur lengkap NodePool — spec.template, requirements, disruption, dan weight — lalu menjelaskan bagaimana Karpenter mencocokkan pod dengan pool yang tepat, dan label/annotasi apa saja yang ditempelkan pada node yang dibuatnya.

Struktur NodePool

NodePool terdiri dari dua bagian besar: spec.template yang mendefinisikan node, dan spec.disruption yang mengatur kapan node boleh diganti. Ada juga spec.weight untuk preferensi antar pool. Mari kita lihat contoh lengkapnya:

NodePool lengkap
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: general
spec:
  weight: 10
  template:
    metadata:
      labels:
        team: platform
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["m5.large", "m6i.large", "m6a.large"]
      taints:
        - key: workloads
          value: "true"
          effect: PreferNoSchedule
  disruption:
    consolidationPolicy: WhenUnderutilized
    expireAfter: 720h

spec.template: Spesifikasi Node

spec.template.metadata berisi label dan anotasi yang akan ditempelkan ke node baru, misalnya team: platform untuk grouping biaya. spec.template.spec berisi tiga hal penting:

  • nodeClassRef — pointer ke EC2NodeClass yang menyediakan infrastruktur.
  • requirements — filter instance type dan kapasitas yang boleh dipilih.
  • taints — taint yang dipasang ke node, lengkap dengan tolerations yang harus dimiliki pod agar boleh masuk.

requirements: Filter Instance

Requirement memakai bentuk key, operator, dan values. Operator yang tersedia: In, NotIn, Gt, Lt, dan Exists. Key yang umum dipakai:

KeyContoh nilaiArti
node.kubernetes.io/instance-typem5.large, m6i.largeFilter instance type
karpenter.sh/capacity-typeon-demand, spotJenis kapasitas
topology.kubernetes.io/zoneap-southeast-1aAvailability zone
kubernetes.io/archamd64, arm64Arsitektur CPU
karpenter.sh/instance-categorygeneral, computeKategori family
karpenter.sh/instance-familym5, c6iFamily instance

Kombinasi requirement inilah yang menentukan "ruang pencarian" instance Karpenter. Semakin spesifik, semakin terbatas pilihan — semakin luas, semakin besar peluang dapat harga murah lewat binpacking.

disruption: Mengatur Siklus Hidup Node

spec.disruption mengontrol kapan node boleh dihentikan:

  • consolidationPolicy: WhenUnderutilized — node yang kurang terpakai dikonsolidasi, pod dipindah ke node yang lebih optimal.
  • expireAfter — node dianggap kedaluwarsa dan diganti setelah periode tertentu; nilai 720h berarti 30 hari.
  • budgets — membatasi berapa banyak node yang boleh diganggu bersamaan.

weight: Preferensi Antar Pool

Ketika beberapa NodePool sama-sama cocok dengan pod, spec.weight menentukan pemenangnya. Semakin tinggi nilai weight (skala 0-100), semakin diutamakan pool tersebut. Jika bobotnya sama, Karpenter memilih pool yang urutannya paling awal.

Cara Karpenter Mencocokkan Pod dengan NodePool

Scheduling di Karpenter pada dasarnya membalik logika scheduler standar: alih-alih mencari node untuk pod, Karpenter mencari kombinasi instance yang bisa memenuhi semua pod yang mengantre. Prosesnya melibatkan:

Resource Requests

Total request CPU, memory, GPU, dan storage dari semua pod dihitung untuk menentukan ukuran instance minimal. Pod dengan request yang saling melengkapi bisa di-binpack ke satu node.

Labels dan Node Selector

Label yang diminta pod lewat nodeSelector atau nodeAffinity dicocokkan dengan label dari spec.template NodePool. Contoh: pod dengan nodeSelector disktype: ssd hanya cocok dengan pool yang mendefinisikan label disktype: ssd.

Taints dan Tolerations

Node dari NodePool bisa diberi taint. Pod yang tidak punya toleration yang cocok akan ditolak pool tersebut. Ini cara paling umum memisahkan workload: pool khusus Spot dengan taint, hanya pod yang siap diganggu yang boleh masuk.

Note

Karpenter juga menghormati constraint Kubernetes lain seperti node affinity, pod affinity/anti-affinity, dan topology spread constraints. Semua itu turut mempersempit pilihan instance — jadi jangan heran jika kombinasi constraint membuat Karpenter memilih instance yang lebih besar.

Label dan Anotasi pada Node yang Dibuat

Saat node lahir dari sebuah pool, Karpenter menempelkan label dan anotasi yang menjadi jendela observability:

Label/AnotasiTipeIsi
karpenter.sh/nodepoollabelNama NodePool asal node
karpenter.sh/capacity-typelabelspot atau on-demand
node.kubernetes.io/instance-typelabelInstance type terpilih
topology.kubernetes.io/zonelabelAZ tempat instance diluncurkan
karpenter.sh/registeredanotasiMenandakan node sudah terdaftar
karpenter.sh/do-not-disruptanotasiMelindungi pod dari konsolidasi
Inspeksi node buatan Karpenter
kubectl get nodes -l karpenter.sh/nodepool=general -o wide
kubectl describe node <node-name>
kubectl get nodeclaims

Label karpenter.sh/nodepool dan karpenter.sh/capacity-type inilah yang biasa dipakai untuk tagging biaya dan grouping node. Menambahkan anotasi karpenter.sh/do-not-disrupt pada pod penting akan membuat Karpenter melewatinya saat konsolidasi.

Membuat Beberapa NodePool

Praktik umum di production: beberapa NodePool untuk kebutuhan berbeda — satu untuk workload umum, satu khusus Spot yang lebih murah, satu lagi untuk GPU. Contoh pembagian:

NodePoolcapacity-typeinstance-familyweight
generalon-demandm5, m6i, m6a10
spotspotc5, c6i20
gpuon-demandg5, p4d0

Dengan weight lebih tinggi, pool spot akan dipilih lebih dulu selama pod-nya toleran terhadap taint Spot. Ini strategi hemat biaya yang paling sering dipakai.

Penutup

Episode 4 membedah NodePool — inti dari kebijakan scheduling Karpenter. Kalian memahami struktur spec.template dengan requirements dan taints, kebijakan disruption seperti consolidationPolicy dan expireAfter, weight untuk preferensi antar pool, serta mekanisme Karpenter mencocokkan pod — resource request, label, dan taints — dengan pool yang tepat. Label dan anotasi karpenter.sh menjadi alat observability yang tak ternilai.

Inti yang harus dibawa pulang:

  • spec.template — definisi node: label, nodeClassRef, requirements, dan taints.
  • Requirements — filter instance type, kapasitas, zona, dan arsitektur dengan operator In, NotIn, Gt, Lt, Exists.
  • Disruption — consolidationPolicy dan expireAfter menentukan kapan node diganti.
  • Weight — prioritas antar pool; makin tinggi makin diutamakan.
  • Label karpenter.sh — karpenter.sh/nodepool dan karpenter.sh/capacity-type wajib dikenal untuk operasional.

Di episode 5 kita pindah ke sisi infrastruktur: EC2NodeClass. Kita akan membahas AMI selection, security groups, subnets, instance profile, userData, serta cara menggabungkan beberapa NodeClass untuk workload yang berbeda. Sampai jumpa di episode berikutnya!

Belajar Karpenter - NodePool & Scheduling | Belajar Karpenter