Blue plastic wires with white tips connected to server and provide access to information

Geçen yıl bir e-ticaret müşterisinde Kara Cuma sabahı 06:30, telefon çaldı: “Site yavaşladı, sepet sayfası 504 dönüyor.” AKS cluster’ında HPA tanımlıydı, sayı 4’ten 12’ye çıkmıştı, ama node havuzu maksimum 8 node’da kilitliydi. Yeni pod’lar saatlerce Pending bekledi çünkü cluster autoscaler limite takılmıştı. O sabah öğrendiğim şey hâlâ çoğu ekipte tekrarlanıyor: HPA’yı yapılandırmak yetmez, üç katmanı (pod-yatay, pod-dikey, node) birlikte düşünmediğin gün karşına çıkar. Bu yazıda saha notlarımla üç mekanizmayı ve aralarındaki incelikleri anlatıyorum.

Horizontal Pod Autoscaler — en yaygın, en yanlış yapılandırılan

HPA, metrik değerine göre pod sayısını artırır/azaltır. Formül basit:

desiredReplicas = ceil( currentReplicas × ( currentMetric / targetMetric ) )

3 pod, ortalama CPU %80, hedef %50 → ceil(3 × 80/50) = 5. Sahada en sık gördüğüm üç hata:

  1. resources.requests yok. CPU bazlı HPA için requests.cpu şart. Yoksa kullanım oranı hesaplanamaz, HPA yalnızca “Unknown” döner.
  2. min=1. Tek pod restart yerken servis kesintisi yaşıyorsunuz. Production’da minReplicas: 2 taban kuralım.
  3. Memory ile ölçeklemek. Çoğu uygulama belleği bırakmaz, HPA artırır artırır asla azaltmaz. Memory bazlı HPA’yı yalnızca davranışını iyi bildiğin uygulamalarda kullan.

Tipik HPA örneği

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 3
  maxReplicas: 30
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 50
          periodSeconds: 60

stabilizationWindowSeconds: 300 flapping’i (sürekli artıp azalma) engelliyor — HPA ezbere ayar yapılırsa ölçek dakikada 4-5 kez değişebilir. Pod restart maliyetini hesaba katmadan agresif scale-down yazmak banka kasası açar.

Custom metrik ve KEDA

CPU çoğu zaman doğru sinyal değildir. Bir worker pod için anlamlı sinyal kuyruktaki mesaj sayısıdır. KEDA tam burada devreye giriyor — hem custom metrik adapter olarak çalışır hem de sıfıra ölçekleme yeteneğini getirir (HPA min=1’in altına inemez, KEDA inebilir).

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: order-worker-scaler
spec:
  scaleTargetRef:
    name: order-worker
  minReplicaCount: 0
  maxReplicaCount: 50
  pollingInterval: 15
  cooldownPeriod: 120
  triggers:
    - type: azure-servicebus
      metadata:
        queueName: orders
        messageCount: "5"
      authenticationRef:
        name: keda-msi-auth

Bir müşterimde gece batch işleri 03:00–05:00 arası çalışıyordu. KEDA ile sıfıra inince, sabit 4 worker’ın aylık maliyeti $620’dan $90’a düştü. AKS’te KEDA artık add-on, az aks update --enable-keda yeter.

Vertical Pod Autoscaler — dikkat edilmesi gereken katman

VPA, pod sayısını değil pod’un requests/limits değerlerini ayarlar. Üç modu var:

  • Off: Sadece öneri üretir, pod’lara dokunmaz. Sahada %90 oranında bu modu öneriyorum.
  • Initial: Yalnızca pod ilk oluşturulurken önerilen değerleri uygular.
  • Auto: Çalışan pod’ları yeniden başlatarak günceller. Production’da PodDisruptionBudget olmadan asla.

Önemli kural: HPA ve VPA aynı metrik üzerinde çakışmaz. CPU bazlı HPA + CPU bazlı VPA Auto = pod sayısı sürekli oynayan, request değeri sürekli değişen kaos. Tipik kombinasyon şu: HPA custom metrik (queue depth) ile yatay, VPA CPU/memory ile dikey ayar.

VPA’nın bence en değerli kullanımı şu: yeni bir uygulama production’a alırken bir hafta Off modda çalıştır, önerileri al, manuel olarak deployment’a yansıt. Üç müşterimde bu pratik %30-40 oranında over-provisioning’i ortaya çıkardı.

Cluster Autoscaler — node katmanı

HPA pod sayısını artırdı ama node kapasitesi yetmiyorsa pod Pending kalır. Cluster Autoscaler bu noktada devreye girer: Pending pod varsa yeni node ekler, boş node 10 dakika boş kalırsa kaldırır. Karar mekanizması:

kubectl get pods --field-selector=status.phase=Pending
kubectl describe pod <pending-pod> | grep -A3 Events
# "0/4 nodes are available: insufficient cpu" → CA yeni node istiyor

kubectl logs -n kube-system -l app=cluster-autoscaler --tail=50

AKS node pool stratejim

Tek bir homojen node pool, hem maliyet hem güvenilirlik açısından zayıf. Saha pratiği:

  • system pool: 2-3 küçük node (D2s_v5), CriticalAddonsOnly=true taint, sadece kube-system pod’ları.
  • workload pool (regular): D4s_v5 veya D8s_v5, on-demand, autoscale 2-20.
  • spot pool: Spot fiyatlı, autoscale 0-30. Kesintiye toleransli batch/worker’lar için. kubernetes.azure.com/scalesetpriority=spot taint ile sadece toleration’ı olan pod’lar gelir.
az aks nodepool add 
  --cluster-name prod-aks --resource-group prod-rg 
  --name spotpool 
  --priority Spot 
  --eviction-policy Delete 
  --spot-max-price -1 
  --enable-cluster-autoscaler 
  --min-count 0 --max-count 30 
  --node-vm-size Standard_D8s_v5

Bir müşterimde gece batch ETL spot pool’a taşınınca aylık compute maliyeti $4.200’den $1.350’ye indi. Spot kapasitesi geri çağrıldığında pod’lar evict olur, KEDA cooldown’dan sonra yeni node’da yeniden başlar.

Reaksiyon süresi ve buffer kapasitesi

Otomatik ölçekleme anlık değil. Tipik gecikme zinciri:

  • HPA metrik toplama → 15-30 sn
  • Pod oluşturma + image pull → 5-60 sn (büyük imaj için 90+)
  • Cluster Autoscaler node ekleme → 3-5 dk (Azure VM provisioning)

Yani ani spike geldiğinde ilk 3-5 dakika kullanıcı yavaşlık hisseder. Üç pratik tampon stratejisi:

  1. Overprovisioning: İhtiyacın %20-30 üzerinde başlangıç pod sayısı.
  2. Pause pod (placeholder): Düşük öncelikli boş pod’larla node’u önceden tut. Gerçek pod geldiğinde yer açılır.
  3. Image pre-pull: DaemonSet ile sık kullanılan imajları her node’a önceden çek, yeni node’da pull süresi sıfır.

Sahada en sık karşılaştığım üç sorun

1. HPA flapping

Pod sayısı dakikada bir 5 → 12 → 6 → 14… Çözüm: behavior.scaleDown.stabilizationWindowSeconds: 300, scaleUp.stabilizationWindowSeconds: 60. Hedef metrik değerini de gerçekçi tut — %50 yerine %60-70 daha az hassas.

2. Pending pod tsunami

Trafik patladı, HPA pod istedi, node yok, CA daha node ekleyemedi. Önlem: node pool max’ı gerçek peak’ten %30 fazla, CA scan-interval düşür (--scan-interval=10s), pause pod ile buffer.

3. Memory HPA “yapışkan” davranış

Java/Node uygulamaları bellek bırakmaz, HPA artırır azaltmaz. Çözüm: memory yerine RPS/queue depth gibi anlamlı sinyale geç.

İzleme — Prometheus + Grafana setim

Her AKS müşterimde aşağıdaki dashboard’lar standart:

  • HPA current vs desired replica zaman serisi
  • Pod startup süresi (image pull + readiness)
  • Cluster Autoscaler scale-up/scale-down olayları
  • Pending pod sayısı (her zaman 0 olmalı; >0 ise alarm)
  • Spot eviction sayacı (KEDA + spot pool kombinasyonu için)
sum(kube_horizontalpodautoscaler_status_current_replicas) by (horizontalpodautoscaler)
sum(kube_pod_status_phase{phase="Pending"})
rate(cluster_autoscaler_scaled_up_nodes_total[5m])

Sıkça Sorulan Sorular

HPA, VPA ve Cluster Autoscaler aynı anda çalışabilir mi?
Evet, doğru tasarlandığında zorunludur bile. Kural: HPA ve VPA aynı metrik üzerinde değil. Tipik: HPA custom metrik (RPS, queue), VPA CPU/memory önerileri (Off mod), CA node katmanı.

Spot node prod’da kullanılır mı?
Stateless, idempotent ve kesintiye toleranslı iş yükleri için evet. Veritabanı, ingress controller, kritik sync API için hayır. Toleration + taint ile karışmamalarını sağla.

KEDA ile HPA arasında seçim nasıl yapılır?
CPU/memory yetiyorsa HPA. Event-driven (kuyruk, stream, cron, custom DB query) veya sıfıra ölçekleme istiyorsan KEDA. KEDA aslında arkada HPA üretiyor, çakışma yok.

Sonuç

Kubernetes ölçeklemesi tek mekanizma değil bir orkestra. HPA pod sayısını, VPA pod boyutunu, Cluster Autoscaler node sayısını ayarlar; KEDA event-driven dünyaya köprü kurar. Üçünü uyumlu çalıştırmak için resource request’leri doğru tanımla, behavior alanı ile flapping’i engelle, node pool’u iş yüküne göre ayrıştır, izleme ve alarmı kurmadan production’a açma. Saha tecrübesi: bu disiplinle bir AKS cluster’ı hem servis seviyesini koruyor hem aylık compute maliyetini %25-50 düşürüyor.

CloudSpark Kubernetes ve AKS danışmanlığı ile cluster ölçekleme stratejinizi tasarlıyor, KEDA/spot mimarisini kuruyor ve maliyet optimizasyonunu sürdürülebilir hale getiriyoruz.

🇹🇷 Türkçe🇬🇧 English🇩🇪 Deutsch🇫🇷 Français🇸🇦 العربية🇷🇺 Русский🇪🇸 Español