Przejdź do treści
Kubernetes HPA: Horizontal Pod Autoscaler dla CPU i pamięciAleksander Roszig 8 sierpnia 2026 | 6 min czytania

Kubernetes HPA: Horizontal Pod Autoscaler dla CPU i pamięci

Spis treści

Autoskalowanie to jeden z głównych powodów, dla których firmy przechodzą na Kubernetesa lub w ogóle chcą korzystać z chmury. Mimo to w wielu klastrach, które audytujemy, Horizontal Pod Autoscaler albo w ogóle nie jest używany, albo jest skonfigurowany w sposób, który aktywnie szkodzi aplikacji. Liczba replik jest ustalana raz, na sztywno wpisana w manifest, a klaster płaci za szczytową pojemność 24/7. To dokładne przeciwieństwo tego, jak powinno wyglądać środowisko cloud native.

W tym artykule chciałbym wyjaśnić, jak działa Kubernetes Horizontal Pod Autoscaler oraz pokazać działające przykłady skalowania na CPU, na pamięci i na obu metrykach jednocześnie. HPA działa bezpośrednio na resource requests, więc jeśli nie wiesz, jak działają requesty w Kubernetesie, polecam przeczytać wcześniejsze części o CPU request i limit oraz memory request i limit.

Czym jest HPA w Kubernetesie?

HPA (Horizontal Pod Autoscaler) to wbudowany kontroler Kubernetesa, który dostosowuje liczbę replik podów do obserwowanego obciążenia CPU lub pamięci.

  • Horyzontalnie oznacza więcej lub mniej podów z tą samą ilością zasobów. HPA nigdy nie zmienia CPU ani pamięci przypisanej do pojedynczego poda. Zmiana zasóbów bez zmiany liczby replik to skalowanie wertykalne, obsługiwane przez VPA (Vertical Pod Autoscaler).
  • HPA to obiekt API (autoscaling/v2) plus pętla kontrolna działająca wewnątrz kube-controller-manager, która śledzi ten obiekt. Deklarujesz stan docelowy, a kontroler reguluje stan systemu.

Jak działa Horizontal Pod Autoscaler

Kontroler domyślnie sprawdza co 15 sekund (--horizontal-pod-autoscaler-sync-period) dla każdego obiektu HPA:

  1. pobiera bieżącą wartość każdej skonfigurowanej metryki,
  2. oblicza pożądaną liczbę replik,
  3. aktualizuje pole replicas w zasobie docelowym, jeśli to konieczne.

Sercem mechanizmu jest jeden wzór:

desiredReplicas = ceil( currentReplicas × currentMetricValue / desiredMetricValue )

Pytanie brzmi: jeśli liniowo przeskalujemy liczbę replik, żeby sprowadzić średnie wykorzystanie do wartości docelowej, ile podów potrzebujemy? ceil zaokrągla w górę, bo liczba replik nie może być ułamkowa.

Zanim kontroler zadziała zgodnie ze wzorem, sprawdza stosunek currentUtilization / targetUtilization. Jeśli ten stosunek mieści się w przedziale 0,9-1,1 (czyli w granicach 10% od wartości docelowej), HPA nic nie robi — niezależnie od tego, co sugerowałby wzór. Ma to zapobiegać ciągłemu, nerwowemu przeskalowywaniu, gdy wykorzystanie jest już blisko wartości docelowej.

Załóżmy 3 repliki, docelowe wykorzystanie CPU 70%, bieżące średnie wykorzystanie 90%:

desiredReplicas = ceil(3 × 90% / 70%) = ceil(3,86)  = 4
currentReplicasbieżące wykorzystaniecelstosunekceildesiredReplicas
390%70%1,283,864 (skalowanie w górę)
435%70%0,52,002 (skalowanie w dół)
253%70%0,751,512 (bez zmian)
273%70%1,042,082 (bez zmian)

Ostatni wiersz pokazuje istotny szczegół: kontroler ma domyślnie tolerancję 0,1 (10%). Jeśli stosunek wartości bieżącej do docelowej mieści się w przedziale 0,9-1,1, nic się nie dzieje. Zapobiega to ciągłemu skalowaniu przy niewielkich wahaniach. Dlatego nie mamy tej aplikacji przeskalowanej do 3 podów, nawet jeśli wynik ceil jest odrobinę powyżej 2.

Nawet gdy desiredReplicas różni się od bieżącej wartości, skalowanie w dół nie nastąpi natychmiast: okno stabilizacji (domyślnie 300 sekund) sprawia, że kontroler wybiera najwyższą rekomendację z ostatniego okresu. Skalowanie w górę ma domyślnie okno stabilizacji równe 0, więc uruchamia się natychmiast po przekroczeniu progu przez metrykę (przy kolejnej synchronizacji, co ~15 sekund).

Wykorzystanie zawsze jest obliczane względem requestu kontenera, a nie limitu. Cel averageUtilization: 70 dla CPU oznacza 70% requestu CPU. Dlatego HPA na metrykach zasobowych po prostu nie działa bez requestów — kontroler zgłasza <unknown> oraz zdarzenie FailedGetResourceMetric.

Metryki Kubernetes HPA: Resource, Pods, Object, External

HPA może korzystać z czterech typów metryk:

  • Resource - CPU i pamięć kontenerów, dostarczane przez metrics-server poprzez API metrics.k8s.io.

Metryki niestandardowe przy użyciu API custom.metrics.k8s.io, na przykład z Prometheus adapterem:

  • Pods - niestandardowe metryki na poda (np. liczba requestów na sekundę), uśredniane po Podach.
  • Object - metryka opisująca inny obiekt Kubernetesa, na przykład liczba requestów na sekundę na Ingressie.

Metryki spoza klastra poprzez external.metrics.k8s.io:

  • External - metryki spoza klastra, na przykład długość kolejki SQS.

Niestandardowe metryki Kubernetes HPA

CPU to proxy dla obciążenia, a nie samo obciążenie. Dla wielu systemów uczciwym sygnałem do skalowania są requesty na sekundę, długość kolejki albo opóźnienie konsumenta (consumer lag). HPA wspiera to poprzez API custom.metrics.k8s.io i external.metrics.k8s.io, zwykle udostępniane przez jedno z poniższych rozwiązań:

  • Prometheus Adapter - udostępnia dowolne zapytanie Prometheusa jako metrykę HPA,
  • KEDA - operator przeznaczony do autoskalowania z gotowymi scalerami dla Kafki, SQS, RabbitMQ, CloudWatch i dziesiątek innych źródeł. Pod spodem KEDA nadal tworzy obiekt HPA, więc wszystko z tego artykułu ma tu zastosowanie.

Jeśli zauważasz, że dostrajasz cele CPU, żeby pośrednio przybliżyć “requesty na poda”, to znak, że pora przejść na metrykę niestandardową.

HPA vs VPA w Kubernetesie

Oba autoskalery odpowiadają na różne pytania:

HPAVPA
co się zmienialiczba replikrequesty CPU/pamięci poda
kierunekhoryzontalnywertykalny
dobre dlausług bezstanowych, obciążeniowychwłaściwego doboru requestów, batch jobów, baz danych

Nie uruchamiaj HPA i VPA na tej samej metryce. VPA zmienia requesty, których HPA używa jako mianownika przy obliczaniu wykorzystania — oba kontrolery zaczynają się “gonić”, a liczba replik staje się nieprzewidywalna. Bezpieczne wzorce: VPA w trybie updateMode: Off jako silnik rekomendacji do ręcznego ustawiania requestów albo VPA zarządzające requestami przy jednoczesnym skalowaniu HPA na metrykach niestandardowych/zewnętrznych.

Najlepsze praktyki Kubernetes HPA

  • Zawsze ustawiaj request CPU i memory Bez nich HPA nie może działać. To, jak requesty przekładają się na rzeczywisty czas CPU, opisujemy w CPU request i limit w praktyce.
  • Zostaw zapas w wartości docelowej. Cel CPU na poziomie 70% oznacza, że pody regularnie działają powyżej tej wartości między okresami synchronizacji. Jeśli ustawisz zbyt niskie limity CPU to może to spowodować throttling CPU.
  • Ustaw realistyczne minReplicas i maxReplicas. minReplicas: 1 na produkcyjnym API oznacza pojedynczego poda, który redukuje koszty, gdy nikt nie korzysta z aplikacji. maxReplicas powinno mieścić się w rzeczywistej pojemności klastra — HPA skaluje pody, nie node’y. Żeby klaster miał wystarczająco miejsca, skorzystaj z Cluster Autoscalera lub Karpentera.
  • Usuń pole replicas z manifestów zarządzanych przez HPA. W konfiguracji GitOps to klasyczny konflikt: Argo CD w kółko resetuje repliki do wartości z Gita. Usuń to pole lub skonfiguruj ignoreDifferences w definicji aplikacji ArgoCD, żeby tylko HPA nim zarządzało.
  • Weryfikuj zdarzenia skalowania za pomocą: kubectl describe hpa <nazwa> pokazuje decyzje kontrolera i każdy powód, dla którego nie mógł skalować.

Podsumowanie

HPA to jeden z tych mechanizmów Kubernetesa, które w demo wyglądają trywialnie, a w produkcji dopasowanie wszystkich parametrów okazują się bardziej skomplikowane. Wzór to jedna linijka, ale to, czy zadziała u Ciebie, zależy od danych wejściowych: poprawnych requestów, metryki faktycznie odzwierciedlającej obciążenie, sensownych celów i dopasowania tego do wzorca Twojego ruchu. Jeśli chcesz zweryfikować swoją konfigurację autoskalowania, właściwie dobrać requesty i limity albo zaprojektować pełną ścieżkę od HPA przez Cluster Autoscaler aż po kontrolę kosztów, nasz zespół oferuje konsulting Kubernetes oparty na danych i metrykach.