Docker & DevOps

    Kubernetes HPA ile Otomatik Ölçekleme

    Kubernetes HPA'nın çalışma mantığı, kurulumu ve ölçek davranışını ayarlama yöntemleri.

    11 dk okuma Güncellendi: 25 Ağustos 2026

    Kampanya günü geliyor, trafiğin dört katına çıkacağını biliyorsun ve gece yarısı elle kubectl scale yazmak istemiyorsun. Ya da tam tersi: gecenin üçünde sekiz replika boşa CPU yakıyor ve faturayı sen ödüyorsun. Kubernetes HPA (Horizontal Pod Autoscaler) tam olarak bu iki problemi çözmek için var — bir Deployment'ın replika sayısını, ölçtüğü metriğe bakarak kendisi artırıp azaltıyor.

    Ama HPA, dokümantasyondaki üç satırlık örneği kopyalayıp yapıştırınca çalışan bir şey değil. Metrik kaynağı kurulu değilse hiçbir şey yapmaz, container'a resources.requests yazmadıysan hedef yüzdeyi hesaplayamaz, behavior bloğunu dokunmadan bırakırsan trafik dalgalandığında replikalar yukarı aşağı zıplar. Bu rehberde HPA'nın replika sayısını hangi formülle bulduğunu, metrics-server'ı nasıl doğru kurduğunu, CPU dışındaki metriklerle nasıl ölçekleneceğini ve üretimde en sık karşılaştığım tuzakları gerçek komutlarla anlatacağım.

    HPA Ne Yapar, Ne Yapmaz#

    HPA bir kontrol döngüsüdür. Varsayılan olarak 15 saniyede bir uyanır, hedef aldığı iş yükünün (Deployment, StatefulSet, ReplicaSet) hazır durumdaki pod'larının metriklerini okur, bunları senin belirlediğin hedefle karşılaştırır ve gerekiyorsa spec.replicas alanını günceller. Yani HPA pod sayısını değiştirir; pod'un içindeki container'a daha fazla CPU veya bellek vermez. Container'ın kendi limitlerini büyütmek isteyen mekanizma VPA'dır (Vertical Pod Autoscaler) ve HPA ile aynı metrik üzerinde birlikte kullanılması önerilmez, çünkü ikisi birbirinin kararını sürekli bozar.

    HPA'nın yapamadığı ikinci şey de düğüm eklemektir. On beş replika istedin ama kümede o kadar CPU yok ise, fazladan pod'lar Pending durumunda bekler ve HPA bu konuda hiçbir şey yapamaz. Düğüm eklemek Cluster Autoscaler'ın (veya bulut sağlayıcının yönettiği eşdeğerinin) işidir. Üçünün rollerini karıştırmamak, "HPA çalışmıyor" diye saatlerce yanlış yerde arama yapmanı engeller:

    BileşenNeyi değiştirirTetikleyicisiTipik kullanım
    HPAPod sayısıCPU / bellek / özel metrikWeb ve API katmanı
    VPAPod'un request/limit değerleriGeçmiş kullanımTek replikalı iş yükleri
    Cluster AutoscalerDüğüm sayısıPending pod'larKümenin kendisi

    Bu ayrım oturmadan HPA yazmak, Docker'ın temel kavramlarını bilmeden Compose dosyası yazmaya benziyor: çalışıyor gibi görünür, sonra ilk gerçek yükte dağılır.

    Ön Koşul: metrics-server Kurulumu#

    HPA metrikleri kendisi toplamaz; metrics.k8s.io API'sini sorgular ve bu API'yi kümene metrics-server sağlar. Managed bir Kubernetes hizmeti kullanıyorsan büyük ihtimalle kuruludur, kendi kurduğun bir kümede ise neredeyse kesinlikle değildir. Önce kontrol et:

    # metrics API kayıtlı mı?
    kubectl get apiservices | grep metrics
    # Beklenen çıktı:
    # v1beta1.metrics.k8s.io   kube-system/metrics-server   True
    
    # Pod metrikleri geliyor mu?
    kubectl top pods -n default
    

    kubectl top komutu "error: Metrics API not available" diyorsa kurulum yapman gerekiyor:

    # Resmi bileşen manifestini uygula
    kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
    
    # Dağıtımın ayağa kalkmasını bekle
    kubectl -n kube-system rollout status deployment/metrics-server
    

    Kendi kurduğun kümelerde metrics-server'ın pod'u çoğu zaman CrashLoopBackOff ya da 0/1 Running durumunda takılır. Sebebi neredeyse her seferinde aynıdır: kubelet kendi kendine imzaladığı bir sertifika sunar, metrics-server de bunu doğrulayamaz. Log'a bakınca x509: cannot validate certificate satırını görürsün. Test ve iç ağ kümelerinde çözüm, doğrulamayı kapatan argümanı eklemektir:

    # metrics-server dağıtımına doğrulama bayrağını ekle
    kubectl -n kube-system patch deployment metrics-server --type=json \
      -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
    

    Container'ın neden çöktüğünü anlamak için log okuma alışkanlığı burada da işe yarar; yöntem Docker container loglarını okuma yazısındakiyle aynı mantıkta, sadece komut kubectl logs oluyor.

    İlk HPA'yı Oluşturmak#

    HPA'nın çalışması için hedef container'da mutlaka resources.requests tanımlı olmalı. Bunun sebebi basit: HPA "CPU yüzde 60'a ulaşınca ölçekle" derken yüzdeyi request değerine göre hesaplar. Request yoksa payda yoktur, hesap yapılamaz. Önce Deployment'ını düzelt:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web
    spec:
      replicas: 2
      selector:
        matchLabels: { app: web }
      template:
        metadata:
          labels: { app: web }
        spec:
          containers:
            - name: web
              image: nginx:stable
              resources:
                requests:          # HPA yüzdeyi BU değere göre hesaplar
                  cpu: 200m
                  memory: 128Mi
                limits:
                  cpu: 500m
                  memory: 256Mi
    

    Ardından HPA'yı tanımla. Tek satırlık hızlı yöntem kubectl autoscale komutudur, ama üretimde manifest dosyası tutmanı öneririm:

    # Hızlı yöntem (deneme için)
    kubectl autoscale deployment web --cpu-percent=60 --min=2 --max=10
    
    # hpa-web.yaml — sürüm kontrolüne girecek hâli
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: web
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: web
      minReplicas: 2
      maxReplicas: 10
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 60
    

    Uygulayıp durumu izle:

    kubectl apply -f hpa-web.yaml
    kubectl get hpa web --watch
    # NAME  REFERENCE        TARGETS         MINPODS  MAXPODS  REPLICAS
    # web   Deployment/web   cpu: 18%/60%    2        10       2
    

    TARGETS sütununda cpu: <unknown>/60% görüyorsan iki şeyden biri eksiktir: ya metrics-server veri döndürmüyordur ya da request tanımlamamışsındır. kubectl describe hpa web çıktısının Events bölümü ikisini birbirinden ayırır.

    Replika Sayısı Hangi Formülle Bulunur#

    HPA'nın kararı sihirli değil, tek satırlık bir aritmetik. İstenen replika sayısı şu şekilde hesaplanır: mevcut replika sayısı, ölçülen ortalama metriğin hedef metriğe oranıyla çarpılır ve yukarı yuvarlanır. Yani dört replikayla çalışıyorsun, ortalama CPU kullanımı yüzde 90, hedefin yüzde 60 ise: 4 × (90 / 60) = 6 replika.

    Bu formülün pratikte iki önemli ayrıntısı var. Birincisi tolerans: oran 1'e çok yakınsa (varsayılan olarak yüzde 10 bant içindeyse) HPA hiçbir şey yapmaz. Hedefin yüzde 60 iken ölçüm yüzde 63'e çıktı diye replika eklenmez; bu, küçük dalgalanmalarda sürekli ölçeklenmeyi engelleyen bilinçli bir frendir. İkincisi hazır olmayan pod'lar hesaba katılmaz: Ready olmayan veya metriği henüz gelmemiş pod'lar ortalamaya dahil edilmez, böylece yeni açılan ve ısınma sırasında CPU yakan bir pod ölçek kararını bozmaz.

    Mevcut replikaÖlçülenHedefOranYeni replika
    2%90%601.503
    4%90%601.506
    6%63%601.056 (tolerans içinde)
    6%20%600.332
    10%5%600.082 (minReplicas)

    Son satır önemli: hesap minReplicas altına inse bile HPA asla o sınırın altına düşmez. Aynı şekilde maxReplicas da mutlak tavandır — kümede kaynak olsa dahi HPA o sayının üstüne çıkmaz. Bu iki değeri, "en kötü gün" ve "boşta gece" senaryolarını düşünerek seç.

    CPU Dışındaki Metriklerle Ölçeklemek#

    CPU her iş yükü için doğru sinyal değildir. Bir kuyruk tüketicisi CPU'yu neredeyse hiç kullanmadan saatlerce mesaj bekleyebilir; onun için doğru metrik bekleyen mesaj sayısıdır. autoscaling/v2 API'si dört metrik tipini destekler ve bunları tek bir HPA içinde birleştirebilirsin:

    TipKaynağıÖrnek
    Resourcemetrics-serverCPU / bellek yüzdesi
    PodsÖzel metrik API'siPod başına saniyedeki istek
    ObjectÖzel metrik API'siIngress üzerindeki toplam istek
    ExternalHarici metrik API'siKuyruk uzunluğu, bulut metriği

    Bellekle ölçekleme, Resource tipiyle tek satır fark eder:

      metrics:
        - type: Resource
          resource:
            name: cpu
            target: { type: Utilization, averageUtilization: 60 }
        - type: Resource
          resource:
            name: memory
            target: { type: AverageValue, averageValue: 512Mi }
    

    Birden fazla metrik tanımladığında HPA her biri için ayrı ayrı replika sayısı hesaplar ve en büyüğünü seçer. Yani metrikler yarışmaz, en talepkâr olan kazanır. Bellekle ölçeklemede dikkat etmen gereken nokta şudur: çoğu uygulama belleği bırakmaz, sadece alır. JVM veya Node.js tabanlı bir servis belleği bir kez şişirdikten sonra kullanım grafiği aşağı inmez, dolayısıyla HPA da hiçbir zaman küçülmez. Bellek metriğini, gerçekten bellekle orantılı büyüyen iş yükleri için kullan; onun dışında CPU ya da uygulama seviyesinde bir sayaç daha dürüst bir sinyaldir.

    Pods ve External tipleri için kümene bir metrik adaptörü (yaygın olarak Prometheus Adapter veya KEDA) kurman gerekir; metrics-server bu API'leri sağlamaz. Kurulum yükünü göze alamayacaksan, uygulamanın kendi istek sayacını CPU'ya bağlı hâle getirmek çoğu zaman yeterince iyi bir yaklaşımdır.

    Ölçek Davranışını Ayarlamak#

    Varsayılan HPA yukarı doğru çok hızlı, aşağı doğru ise nispeten yavaştır. Trafiği dalgalı bir serviste bu, replika sayısının sürekli zıplamasına (flapping) yol açar: her zıplama yeni pod açılması, imaj çekilmesi ve bağlantıların kopması demektir. behavior bloğu tam da bunu dizginlemek için var.

    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0      # yukarı çıkarken bekleme yok
          policies:
            - type: Percent                  # her 60 sn'de en fazla %100 büyü
              value: 100
              periodSeconds: 60
            - type: Pods                     # ya da en fazla 4 pod ekle
              value: 4
              periodSeconds: 60
          selectPolicy: Max                  # ikisinden büyüğünü uygula
        scaleDown:
          stabilizationWindowSeconds: 300    # 5 dk boyunca en yüksek öneriyi kullan
          policies:
            - type: Percent                  # her 60 sn'de en fazla %20 küçül
              value: 20
              periodSeconds: 60
    

    stabilizationWindowSeconds en kritik alandır: HPA, o pencere içindeki tüm önerilerin en yükseğini uygular. Aşağı yönde 300 saniye vermek, "son beş dakikada bir kez bile yük gördüysen küçülme" demektir ve ani düşüşlerde servisin çıplak kalmasını engeller. Yukarı yönde ise 0 bırakmak doğrudur; trafik geldiğinde beklemek istemezsin.

    selectPolicy: Max yukarıda agresif, selectPolicy: Min aşağıda muhafazakâr davranmanı sağlar. Ayrıca selectPolicy: Disabled ile bir yönü tamamen kapatabilirsin — örneğin kritik bir kuyruk tüketicisinin asla otomatik küçülmemesini istiyorsan scaleDown için bunu kullan. Ölçek kararlarını sonradan incelemek için kubectl describe hpa web çıktısındaki Events listesi en iyi kaynaktır; hangi metrikle, hangi anda kaç replikaya çıkıldığı orada satır satır yazar. Kümeyi terminal üzerinden canlı izlemeyi seviyorsan k9s ve Lens gibi Kubernetes yönetim araçları bu olayları çok daha okunabilir hâlde gösteriyor.

    Sık Yapılan Hatalar ve Tuzaklar#

    Deployment manifestinde replicas alanını bırakmak. HPA replika sayısını yönetiyorsa, aynı alanı senin manifestin de yönetmeye çalışıyor demektir. GitOps ya da bir CI hattı her deploy'da manifesti yeniden uyguluyorsa, HPA'nın on'a çıkardığı replikayı deploy iki'ye geri düşürür ve dakikalar içinde tekrar on'a çıkar. Çözüm: HPA yönetimindeki iş yüklerinde replicas alanını manifestten tamamen kaldırmak ya da CI'da bu alanı yamalamamaktır. GitHub Actions ile kurduğun CI/CD hattında bu ayrıntıyı atlamak, "otomatik ölçekleme neden çalışmıyor" sorusunun en sık cevabıdır.

    Request'i gerçekçi olmayan bir değere koymak. Request'i çok düşük yazarsan (örneğin gerçekte 300m harcayan bir servise 50m vermek) HPA sürekli yüzde 600 kullanım görür ve tavan replikaya yapışır. Çok yüksek yazarsan hiçbir zaman ölçeklenmez. Doğru yöntem, birkaç gün kubectl top pods çıktısını izleyip tipik kullanımın biraz üstünü request olarak vermektir.

    Hedef yüzdeyi 90'a koymak. "Kaynağı sonuna kadar kullanayım" diye hedefi çok yükseğe çekmek, ölçekleme tetiklendiğinde yeni pod'un ayağa kalkması için gereken sürede servisin zaten boğulmuş olması demektir. Uygulamanın açılış süresi ne kadar uzunsa hedefi o kadar düşük tut; 60-70 bandı çoğu web servisi için makul bir başlangıçtır.

    PodDisruptionBudget'i unutmak. HPA aşağı ölçeklerken pod'ları kapatır. Aynı anda bir düğüm bakımı da devrede ise, iki mekanizma birlikte servisi sıfır replikaya kadar götürebilir. Kritik servislere minAvailable tanımlı bir PDB koymak bu senaryoyu engeller.

    Ölçeklenen pod'un başlangıç sağlığını yanlış tanımlamak. readinessProbe yoksa Kubernetes yeni pod'u hemen trafik almaya uygun sayar; henüz hazır olmayan pod'a istek gider ve kullanıcı hata görür. HPA'yı devreye almadan önce her iş yükünde doğru bir readinessProbe olduğundan emin ol.

    Sıkça Sorulan Sorular#

    HPA çalışması için metrics-server şart mı#

    CPU veya bellek gibi Resource tipi metriklerle ölçekleme yapacaksan evet, metrics-server (ya da metrics.k8s.io API'sini sağlayan başka bir bileşen) zorunludur. HPA metrikleri kendisi toplamaz, bu API'yi sorgular. Yalnızca özel veya harici metriklerle çalışacaksan metrics-server yerine Prometheus Adapter ya da KEDA gibi bir adaptör yeterli olur, ama pratikte çoğu küme her ikisini birden barındırır.

    HPA neden unknown gösteriyor#

    TARGETS sütununda <unknown> görmenin iki klasik sebebi vardır. Birincisi metrik kaynağının veri döndürmemesidir; kubectl top pods komutu da hata veriyorsa sorun metrics-server'dadır. İkincisi ve daha yaygını, hedef container'da resources.requests tanımının eksik olmasıdır — HPA yüzde hesabını request değerine bölerek yaptığı için payda olmadan sonuç üretemez. kubectl describe hpa çıktısındaki olay satırları hangisi olduğunu net söyler.

    HPA ile replika sayısı ne kadar sürede değişir#

    Kontrol döngüsü varsayılan olarak 15 saniyede bir çalışır, dolayısıyla karar birkaç on saniye içinde verilir. Ancak kararın etkisini görmen pod'un ayağa kalkma süresine bağlıdır: imaj çekme, başlatma ve readinessProbe beklemesi toplamda dakikaları bulabilir. Aşağı yönde ise scaleDown.stabilizationWindowSeconds değeri kadar (varsayılan 5 dakika) ek bekleme vardır, bu yüzden küçülme her zaman büyümekten yavaştır.

    minReplicas değerini 1 yapabilir miyim#

    Yapabilirsin ama üretimde önermem. Tek replikayla çalışırken o pod yeniden başlatıldığı, düğümü boşaltıldığı veya güncellendiği anda servis tamamen kesilir. İki replika, sıradan bakım işlemlerinde bile kesintisiz kalmanı sağlar. Yalnızca geliştirme ortamlarında veya kesinti toleransı yüksek toplu iş süreçlerinde minReplicas: 1 mantıklı bir tercihtir.

    HPA ve VPA aynı anda kullanılır mı#

    Aynı metrik üzerinde kullanılmamalıdır. HPA CPU'ya bakarak pod ekler, VPA aynı CPU'ya bakarak request'i büyütür; request büyüyünce HPA'nın gördüğü yüzde düşer ve pod'ları kapatır, ardından yüzde tekrar yükselir. Bu döngü hiç oturmaz. İkisini birlikte kullanmak istiyorsan VPA'yı yalnızca bellek için, HPA'yı yalnızca CPU veya özel bir metrik için yapılandır.

    HPA maliyeti gerçekten düşürür mü#

    Doğru yapılandırıldığında evet, çünkü boşta kalan replikaları kapatır. Ancak kazanç, kümenin kendisinin de küçülebilmesine bağlıdır: pod'lar kapansa bile düğümler ayakta kalıyorsa fatura değişmez. Gerçek tasarruf için HPA'yı bir Cluster Autoscaler ile birlikte kullanmak veya sabit kaynaklı bir sunucu üzerinde çalışıyorsan aynı düğüme daha fazla iş yükü sığdırmak gerekir.

    Kapanış#

    HPA'yı üretimde sorunsuz kullanmanın özeti dört alışkanlıkta toplanıyor: her container'a gerçekçi bir resources.requests yaz, metrics-server'ın veri döndürdüğünü kubectl top ile doğrula, behavior bloğuyla aşağı yönde en az beş dakikalık bir sabitleme penceresi tanımla ve HPA yönetimindeki Deployment'lardan replicas alanını kaldır. Bu dördü yerinde olduğunda HPA'nın kararlarını kubectl describe hpa çıktısından okumak, "neden ölçeklenmedi" sorusunu dakikalar içinde cevaplamana yeter.

    Kubernetes kümesini ayağa kaldırmak için altında güvenilir ve kaynağı öngörülebilir bir makine gerekiyor. Kontrol düzlemi ve düğümler için tam root erişimli VDS ya da esnek büyüyebilen bulut sunucu paketlerimizi kullanabilir, kümenin kurulumu ve güncellemeleriyle uğraşmak istemiyorsan sunucu yönetimi hizmetimizle bu yükü bize bırakabilirsin. Ölçekleyeceğin trafiğin ne kadar bant genişliği tutacağını önceden görmek istersen bant genişliği hesaplayıcı aracımız işini kolaylaştırır.

    KubernetesHPAÖlçekleme

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.