Belajar KEDA - Custom Scalers & External Metrics
Series/Belajar KEDA/Episode 10
Episode 10 of 23

Belajar KEDA - Custom Scalers & External Metrics

Membangun custom scaler gRPC dengan SDK KEDA, memahami jalur komunikasi KEDA dengan HPA lewat External Metrics API, dan meracik kombinasi multi-trigger AND/OR dalam satu ScaledObject dengan scalingModifiers.

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

Pendahuluan

Di episode 9 kita berkenalan dengan scaler untuk database dan HTTP. Meski KEDA punya lebih dari 70 scaler, dunia nyata selalu punya metrik yang belum tercover — misalnya backlog sistem internal, metrik SaaS milik sendiri, atau mainframe legacy. Di episode ini kalian belajar dua hal: cara KEDA berbicara dengan HPA melalui External Metrics API, dan cara membuat custom scaler gRPC untuk menghubungkan sistem internal ke KEDA. Terakhir kita racik multi-trigger dengan logika AND/OR yang presisi.

Komunikasi KEDA dengan HPA: External Metrics API

KEDA tidak menskalakan pod secara langsung. Alurnya berlapis: scaler membaca metrik dari sistem eksternal, lalu KEDA Metrics Server mengekspos nilainya melalui External Metrics API, dan HPA yang dibuat KEDA bertanya ke API itu setiap siklus sinkronisasi (biasanya 15 detik) untuk menetapkan jumlah replika.

KubernetesCek External Metrics API
kubectl get apiservice v1beta1.external.metrics.k8s.io
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1
kubectl get hpa -n production

Jalur inilah yang membuat KEDA kompatibel dengan HPA standar Kubernetes: KEDA hanya menjadi sumber metrik sekaligus pengelola siklus hidup HPA. Karena alasan yang sama, KEDA tidak bisa berbagi API server kustom dengan solusi lain di cluster yang sama.

Membuat Custom Scaler gRPC

Konsep Dasar

Jika 70+ scaler bawaan belum memenuhi kebutuhan, KEDA menyediakan antarmuka external scaler berbasis gRPC. Kalian menulis server gRPC yang mengimplementasikan protokol externalscaler dengan tiga method inti:

  • IsActive — menentukan apakah sistem memiliki event (dipakai untuk keputusan scale-to-zero).
  • GetMetricsSpec — memberitahu KEDA nama metrik dan ukuran target-nya.
  • GetMetricsAndReset — mengembalikan nilai metrik terkini untuk dihitung HPA.

Implementasi dengan SDK Go

Kerangka custom scaler gRPC
package main
 
import (
    "context"
    pb "github.com/kedacore/keda/v2/pkg/scalers/externalscaler"
)
 
type Scaler struct {
    pb.UnimplementedExternalScalerServer
}
 
func (s *Scaler) IsActive(ctx context.Context, req *pb.ScaledObjectRef) (*pb.IsActiveResponse, error) {
    n := countInternalBacklog()
    return &pb.IsActiveResponse{Result: n > 0}, nil
}
 
func (s *Scaler) GetMetricsSpec(ctx context.Context, req *pb.ScaledObjectRef) (*pb.GetMetricsSpecResponse, error) {
    return &pb.GetMetricsSpecResponse{
        MetricSpecs: []*pb.MetricSpec{{
            MetricName: "internal-backlog",
            TargetSize: 100,
        }},
    }, nil
}
 
func (s *Scaler) GetMetricsAndReset(ctx context.Context, req *pb.GetMetricsRequest) (*pb.GetMetricsResponse, error) {
    return &pb.GetMetricsResponse{
        MetricValues: []*pb.MetricValue{{
            MetricName:  "internal-backlog",
            MetricValue: countInternalBacklog(),
        }},
    }, nil
}

Server gRPC ini berjalan sebagai Deployment terpisah di dalam cluster, lalu dihubungkan ke KEDA lewat blok gRPCConfig. Perhatikan countInternalBacklog — ganti dengan logika nyata yang membaca sistem internal kalian.

Registrasi ke ScaledObject

KEDA menghubungi server gRPC tersebut lewat konfigurasi gRPCConfig, dan meneruskan metadata yang ditulis di ScaledObject sebagai parameter trigger.

KedaScaledObject external scaler
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: internal-scaledobject
spec:
  scaleTargetRef:
    name: internal-worker
  minReplicaCount: 0
  maxReplicaCount: 10
  triggers:
    - type: external
      metadata:
        scalerAddress: internal-scaler.prod.svc:6000
        metricName: internal-backlog
        targetValue: "100"
      gRPCConfig:
        host: internal-scaler.prod.svc
        port: "6000"
        useCachedClients: "true"

Tip

Aktifkan useCachedClients: true agar operator tidak membuat koneksi gRPC baru untuk tiap polling — koneksi dibuka sekali lalu dipakai ulang. Kalau scaler internal kalian butuh TLS, tambahkan sertifikat di blok gRPCConfig.

Multi-Trigger dalam Satu ScaledObject

KEDA menggabungkan beberapa trigger dalam satu ScaledObject dengan dua aturan penting.

  • Nilai metrik dijumlahkan: nilai yang dilaporkan ke HPA adalah penjumlahan seluruh trigger. Efeknya seperti "OR" — salah satu trigger besar saja sudah mendorong scale-up.
  • Scale-to-zero butuh semua non-aktif: seperti "AND" — pod baru turun ke nol jika seluruh trigger tidak aktif. Satu trigger yang aktif cukup mempertahankan minimal satu replika.
KedaKombinasi trigger CPU + Prometheus
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: hybrid
spec:
  scaleTargetRef:
    name: hybrid-api
  minReplicaCount: 1
  maxReplicaCount: 20
  triggers:
    - type: cpu
      metricType: Utilization
      metadata:
        type: Utilization
        value: "60"
    - type: prometheus
      metricType: AverageValue
      metadata:
        serverAddress: http://prometheus.monitoring.svc:9090
        query: sum(rate(http_requests_total[2m]))
        threshold: "100"

Logika AND/OR yang Presisi: scalingModifiers

Karena penjumlahan tidak selalu sesuai kebutuhan, KEDA v2.20 menyediakan scalingModifiers dengan formula ekspresi — termasuk operator ternary untuk logika AND/OR yang presisi.

KedaFormula OR via scalingModifiers
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: or-logic
spec:
  scaleTargetRef:
    name: worker
  minReplicaCount: 0
  maxReplicaCount: 10
  advanced:
    scalingModifiers:
      formula: "max(trig_a, trig_b)"
      target: "10"
      metricType: "AverageValue"
  triggers:
    - type: prometheus
      name: trig_a
      metadata:
        serverAddress: http://prometheus.monitoring.svc:9090
        query: sum(rate(errors_total[1m]))
        threshold: "5"
    - type: metrics-api
      name: trig_b
      metadata:
        url: "http://internal-api.prod.svc:8080/backlog"
        valueLocation: "backlog"
        targetValue: "10"

Formula max(trig_a, trig_b) membuat KEDA memakai nilai tertinggi dari kedua trigger — logika OR murni. Untuk AND, gunakan min(...). Kombinasi lain seperti trig_a + trig_b atau ternary trig_a > 2 ? trig_a + trig_b : 1 juga bisa ditulis langsung.

Warning

Saat menggabungkan trigger, perhatikan skala metrik. Menggabungkan trigger bernilai ribuan dengan trigger bernilai satuan lewat penjumlahan akan membuat trigger kecil tidak pernah terlihat. Normalisasi nilai atau gunakan max/min lewat scalingModifiers.

Penutup

  • KEDA berbicara ke HPA lewat External Metrics API: kubectl get --raw /apis/external.metrics.k8s.io/v1beta1.
  • Custom scaler = server gRPC yang mengimplementasikan IsActive, GetMetricsSpec, dan GetMetricsAndReset.
  • Daftarkan scaler kustom lewat gRPCConfig dan metadata di ScaledObject.
  • Multi-trigger default: nilai dijumlahkan (efek OR), scale-to-zero butuh semua trigger non-aktif (efek AND).
  • scalingModifiers dengan formula memberi kontrol AND/OR yang presisi untuk kebutuhan kompleks.

Scaler kalian sekarang bisa apa saja, tapi apa jadinya kalau scaler itu gagal membaca metrik? Di episode 11 kita membahas fallback dan advanced config: menjaga ketersediaan minimum saat scaler error, menyetel pollingInterval, cooldownPeriod, restoreToOriginalReplicaCount, behavior HPA, dan scalingStrategy. Sampai jumpa!

Belajar KEDA - Custom Scalers & External Metrics | Belajar KEDA