Belajar KEDA - Integrasi dengan Karpenter
Series/Belajar KEDA/Episode 16
Episode 16 of 23

Belajar KEDA - Integrasi dengan Karpenter

Gabungkan dua lapis scaling: KEDA menskalakan pod 0 ke N berdasarkan event, Karpenter menyediakan node dalam hitungan detik. Pola queue consumer, provisioning node, dan optimasi biaya dengan spot plus consolidation.

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

Pendahuluan

Di episode 15 kita menekan biaya dengan scale-to-zero dan tuning activation — tetapi ada satu pertanyaan tersisa: saat antrean membanjir dan replika naik dari 0 ke 50, dari mana node-nya? HPA/Cluster Autoscaler tradisional menunggu pod Pending hingga node ditambahkan, dan itu bisa butuh 5-10 menit. Episode ini membahas Integrasi dengan Karpenter — penyedia node otomatis dari AWS yang melengkapi KEDA secara sempurna: KEDA menskalakan pod, Karpenter menskalakan node.

Kita anggap kalian sudah punya cluster EKS dengan KEDA v2.20.2 terpasang. Karpenter berjalan sebagai Deployment di namespace karpenter, mendengarkan pod Pending, lalu meluncurkan instance secara langsung melalui API EC2 — tanpa harus membeli node group di muka.

Layered Scaling: Dua Lapis yang Berbeda

Ini konsep paling penting di episode ini — jangan mencampur peran. Ada dua sumbu scaling yang independen:

LapisToolUnitFokus
Pod scaleKEDA (via HPA)Replica podJumlah event/backlog
Node scaleKarpenterNode/instanceKapasitas CPU/memory/GPU

KEDA membaca keda_scaler_metrics_value (misal panjang SQS), mengubah HPA, dan HPA menambah replica Deployment. Replica baru itu mungkin Pending karena node penuh. Karpenter melihat pod Pending, menghitung kebutuhan resource, dan menerbangkan instance EC2 baru dalam hitungan detik — bukan menit.

KedaScaledObject queue consumer
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: queue-consumer
  namespace: orders
spec:
  scaleTargetRef:
    name: queue-consumer
  pollingInterval: 10
  cooldownPeriod: 120
  minReplicaCount: 0
  maxReplicaCount: 200
  triggers:
    - type: aws-sqs-queue
      metadata:
        queueURL: https://sqs.ap-southeast-1.amazonaws.com/1234/orders
        queueLength: "50"
      authenticationRef:
        name: sqs-auth

Rentang 0 sampai 200 replika itu aman justru karena Karpenter menjamin kapasitasnya ada. Tanpa Karpenter, maxReplicaCount besar berarti menunggu Cluster Autoscaler menambah node — dan HPA menyerah jika pod tak kunjung schedable.

Arsitektur Karpenter

Karpenter bekerja dengan NodePool (dulu Provisioner). NodePool mendefinisikan jenis instance, zone, dan perilaku yang diizinkan. Berikut contoh untuk workload queue consumer dengan kombinasi spot dan on-demand:

nodepool-orders.yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: orders-pool
spec:
  disruption:
    consolidationPolicy: WhenUnderutilized
    expireAfter: 720h
  limits:
    cpu: "200"
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
      nodeClassRef:
        name: orders-ec2
      taints:
        - key: workload.keda/orders
          effect: NoSchedule

Taint NoSchedule memastikan hanya pod dengan toleransi yang masuk ke node pool ini — memisahkan resource worker batch dari workload lain. karpenter.sh/capacity-type dengan nilai ["spot", "on-demand"] membuat Karpenter bebas memilih instance spot untuk menghemat biaya, lalu pindah ke on-demand saat spot tidak tersedia.

NodeClass EC2

Resource kelas EC2 pendamping NodePool:

nodeclass-orders.yaml
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
  name: orders-ec2
spec:
  amiFamily: AL2
  role: "KarpenterNodeRole-orders"
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: orders-cluster
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: orders-cluster
  userData: |
    #!/bin/bash
    echo "bootstrap worker node untuk queue consumer"

Pola ini (NodePool + EC2NodeClass) adalah standar Karpenter modern — bukan lagi migrasi node group manual.

Siklus Lengkap: Event ke Pod Ready

Berikut alur lengkapnya saat antrean penuh:

  1. SQS menumpuk pesan — panjang antrean melewati activationThreshold.
  2. KEDA mempolling tiap pollingInterval, scaler SQS melaporkan nilai metrik.
  3. KEDA memperbarui HPA; HPA menaikkan replica Deployment.
  4. Pod baru Pending — node penuh.
  5. Karpenter mendeteksi pod Pending, memprovisi instance baru (dalam detik).
  6. Node Ready, pod dijadwalkan, container mulai — HPA menambah lagi hingga maxReplicaCount.
  7. Antrean kosong; cooldownPeriod berakhir; KEDA menurunkan replika ke 0; Karpenter mengkonsolidasi node yang kosong.

Urutan ini membuat scale-up end-to-end dalam 1-3 menit untuk tumpukan normal (image kecil), dibanding 5-10 menit dengan Cluster Autoscaler yang harus melewati langkah node group.

Optimasi Biaya: Spot + Consolidation

Karpenter membawa dua penghematan utama yang bekerja baik dengan KEDA:

  • Spot capacity: Karpenter memilih instance spot saat tersedia — hingga 60-90% lebih murah dari on-demand. Kombinasikan dengan karpenter.sh/capacity-type: ["spot", "on-demand"]; workload scale-to-zero adalah kandidat spot ideal karena tidak pernah menyimpan state di node.
  • Consolidation: consolidationPolicy: WhenUnderutilized membuat Karpenter menggabungkan beban beberapa node ke lebih sedikit node, lalu melepaskan node yang kosong — persis saat KEDA menurunkan replika ke nol setelah antrean habis.

Keduanya saling menguatkan: KEDA mematikan pod, Karpenter melepas node. Tanpa konsolidasi, node bekas scale-up menetap dan tagihan tetap membengkak.

Pantau provisioning
kubectl get nodes -l karpenter.sh/nodepool=orders-pool
kubectl logs -n karpenter deploy/karpenter -f
karpenter nodes list

karpenter nodes list menampilkan node yang dikelola Karpenter, termasuk usia, kapasitas, dan alasan disruption — sangat berguna untuk memvalidasi apakah node benar-benar lepas setelah scale-down.

Tip

Atur pollingInterval lebih cepat (10 detik) dan cooldownPeriod moderat saat berpasangan dengan Karpenter. Karpenter menyediakan node cepat, tapi provisioning tetap butuh beberapa puluh detik — polling yang lambat memperpanjang total latency scale-up.

Kesalahan Umum

  1. Tanpa limits di NodePool. Tanpa spec.limits, satu antrean banjir bisa meluncurkan puluhan instance termahal. Batasi dengan limits.cpu/memory.
  2. Lupa toleransi. Taint NodePool tanpa toleransi di Deployment = pod Pending selamanya, replika tidak pernah ready, HPA terus menaikkan.
  3. Mengandalkan spot tanpa on-demand fallback. Jika hanya ["spot"], di region yang kehabisan spot antrean tidak pernah terproses.
  4. maxReplicaCount kecil karena takut kapasitas. Tujuan KEDA + Karpenter justru memutus rasa takut itu — biarkan KEDA menaikkan replika dan Karpenter menyediakan node.
  5. Melewatkan disruption budget. Workload yang bisa di-restart tiba-tiba (interruptible) aman untuk consolidation; stateful workload perlu karpenter.sh/do-not-disrupt.

Penutup

Episode ini menyatukan dua lapis autoscaling: KEDA menskalakan pod dari 0 ke N berdasarkan event melalui ScaledObject SQS, dan Karpenter menyediakan node dalam hitungan detik lewat NodePool serta EC2NodeClass. Kombinasi spot + consolidation memotong biaya, sementara siklus event → pod ready menutup gap latency yang biasa mengganggu.

Poin yang harus kalian bawa:

  • KEDA skala pod; Karpenter skala node — dua sumbu yang independen.
  • NodePool + taint memisahkan resource worker batch dari workload lain.
  • Consolidation melepas node saat KEDA menurunkan replika ke nol.
  • Spot + on-demand fallback memberi penghematan tanpa mengorbankan throughput.
  • limits di NodePool adalah pengaman biaya pertama.

Dengan fondasi KEDA + Karpenter, saatnya memperluas wawasan ekosistem. Di episode 17 selanjutnya kita membahas Advanced Scalers & Ekosistem: scaler lanjutan seperti GitHub API, Azure Storage Queue, GCP Cloud Storage, external-push, hingga integrasi dengan Argo Rollouts, Knative, dan service mesh. Sampai jumpa di episode 17!

Belajar KEDA - Integrasi dengan Karpenter | Belajar KEDA