Memisahkan workload ke beberapa NodePool dengan weight dan taints untuk general, GPU, spot-only, hingga zona spesifik; serta praktik terbaik menjalankan Karpenter di beberapa cluster dengan kebijakan per cluster yang konsisten dan dapat diaudit.

Di episode 9 kalian sudah mengoptimalkan biaya dengan prioritas Spot, filter instance, dan penanganan interupsi otomatis. Episode 10 ini membawa kalian ke skala yang lebih besar: bagaimana menata banyak NodePool dalam satu cluster, dan bagaimana memperlakukan Karpenter ketika cluster yang dikelola bukan satu, melainkan banyak.
Setelah episode ini, kalian akan paham cara memisahkan workload general, GPU, spot-only, dan zona spesifik menggunakan weight dan taints, serta praktik terbaik kebijakan per cluster untuk deployment multi-cluster.
NodePool tunggal yang melayani semua workload memang sederhana, tetapi cepat menjadi kaku. Workload database butuh on-demand dan volume besar, sementara worker batch lebih suka spot murah. Workload ML butuh instance GPU, dan layanan latency-sensitive butuh zona tertentu. Menggabungkan semuanya ke satu NodePool membuat setiap kelompok saling berkompromi.
Pemisahan yang umum digunakan:
Saat sebuah pod bisa dijadwalkan oleh lebih dari satu NodePool, Karpenter memilih NodePool mana yang dipakai. Field spec.weight menentukan preferensi: NodePool dengan weight lebih besar lebih diprioritaskan, dan nilai default-nya adalah nol. Sebagai contoh, sebuah NodePool general dengan weight 10 akan dipilih sebelum NodePool spot-only dengan weight 5.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: general
spec:
weight: 10
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
disruption:
consolidationPolicy: WhenUnderutilized
consolidateAfter: 1mTip
Weight hanya dipakai untuk memilih NodePool saat pod memang memenuhi syarat semua kandidat. Pod dengan nodeSelector atau toleration yang ketat akan tetap jatuh ke NodePool yang cocok, berapapun weight-nya.
Weight mengatur preferensi, tetapi taints mengatur izin. NodePool untuk GPU diberi taint agar pod biasa tidak bisa masuk, dan hanya pod yang memiliki toleration nvidia.com/gpu yang dijadwalkan ke sana.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: gpu-pool
spec:
weight: 20
template:
spec:
taints:
- key: nvidia.com/gpu
effect: NoSchedule
requirements:
- key: node.kubernetes.io/instance-type
operator: In
values: ["g5.xlarge", "g5.2xlarge"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: defaultDengan konfigurasi ini, workload web biasa tidak akan pernah berjalan di node GPU yang mahal.
Untuk workload yang membutuhkan lokasi tertentu, misalnya karena kedekatan dengan database atau regulasi data, NodePool bisa dibatasi pada zona spesifik melalui label topology.kubernetes.io/zone.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: az-a
spec:
template:
spec:
requirements:
- key: topology.kubernetes.io/zone
operator: In
values: ["us-east-1a"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: defaultImportant
Pastikan subnet untuk zona tersebut benar-benar tersedia pada EC2NodeClass yang dipakai. Requirement zona yang tidak didukung subnet membuat pod tetap Pending selamanya.
| NodePool | Kapasitas | Taint | Weight | Target workload |
|---|---|---|---|---|
| general | Spot + On-Demand | Tanpa taint | 10 | Aplikasi web biasa |
| spot-only | Spot saja | Tanpa taint | 5 | Batch job toleran |
| gpu-pool | GPU on-demand | nvidia.com/gpu | 20 | Training dan inference |
| az-a | Semua tipe | Tanpa taint | 0 | Layanan khusus zona |
Karpenter adalah controller yang hidup di dalam satu cluster dan mengelola node cluster tersebut. Tidak ada Karpenter pusat yang mengatur banyak cluster. Ketika kalian punya sepuluh cluster, berarti ada sepuluh instance Karpenter yang berjalan terpisah — masing-masing dengan NodePool, NodeClass, dan disruption policy sendiri.
Keuntungan isolasi ini adalah blast radius yang kecil. Kesalahan konfigurasi di satu cluster tidak menjalar ke cluster lain. Namun konsekuensinya, setiap cluster perlu dikelola dengan disiplin yang sama agar tidak terjadi penyimpangan konfigurasi antar lingkungan.
Best practice pertama untuk multi-cluster adalah konsistensi lewat kode. Definisikan NodePool dan NodeClass sebagai file yang dikelola lewat GitOps, misalnya dengan ArgoCD atau Flux, lalu terapkan ke semua cluster dari satu sumber. Dengan cara ini, perbedaan antar cluster bisa dikurangi hanya pada hal-hal yang memang harus berbeda.
kubectl apply -f clusters/staging/karpenter/
kubectl apply -f clusters/production/karpenter/Selain itu, perhatikan hal-hal berikut:
Cluster staging biasanya boleh berjalan agresif menghemat biaya, sedangkan production membutuhkan lebih banyak jaring pengaman. Konfigurasi berikut mencontohkan perbedaan tersebut.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: general
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"]
disruption:
consolidationPolicy: WhenEmpty
consolidateAfter: 15mWarning
Menjalankan banyak cluster juga berarti mengelola banyak antrian SQS dan kebijakan IAM untuk masing-masing. Jangan biarkan antrian terpakai oleh dua cluster sekaligus — kunci resource per cluster agar tidak saling menelan event.
Weight yang besar tidak mencegah workload salah tempat jika taint tidak dipasang. Gunakan kombinasi keduanya: weight untuk preferensi, taint untuk pembatasan keras.
Memaksa staging dan production memakai NodePool identik mengabaikan perbedaan kebutuhan biaya dan stabilitas. Sesuaikan kebijakan per lingkungan, tetapi pertahankan satu sumber kebenaran di Git.
Multi-NodePool dan multi-cluster adalah dua level organisasi yang harus dirancang, bukan dibiarkan tumbuh liar. Weight, taint, dan isolasi zona membuat satu cluster tertata; GitOps dan kebijakan per lingkungan menjaga banyak cluster tetap selaras.
Inti yang harus dibawa pulang:
Di episode 11, kalian akan belajar tentang drift detection — bagaimana Karpenter mendeteksi perbedaan antara template NodePool dan NodeClass dengan node aktual, serta fitur NodeOverlay untuk memperbarui node tanpa replasemen penuh. Sampai jumpa!