Autoskalowanie w Kubernetesie: HPA, VPA, KEDA i Karpenter
Jedną z głównych zalet Kubernetesa w środowisku produkcyjnym jest możliwość automatycznego skalowania obciążenia pracą w odpowiedzi na zapotrzebowanie. Jednak większość zespołów używa tylko ułamka dostępnych możliwości autoskalowania: konfigurują HPA ze skalowaniem procesora i tak to zostawiają. Wynik? Niedostatecznie obsługiwane pody, które spowalniają pod obciążeniem, lub nadmiernie udostępniane węzły, które bez powodu przepalają budżety.
Kubernetes oferuje cztery uzupełniające się poziomy autoskalowania: HPA skala poziomo Pody dotyczące wskaźników procesora/pamięci/niestandardowych, Umowa o partnerstwie naprawić żądania zasobów automatycznie, KEDA włącz skalowanie sterowane zdarzeniami dowolne źródło (kolejki, bazy danych, metryki Prometheus), e Stolarz Udostępnia węzły w mniej niż 30 sekund, 40% szybciej niż tradycyjny automatyczny skaler klastra zgodnie z benchmarkami CNCF 2025. W tym artykule pokazano, jak używać ich razem w produkcji.
Czego się nauczysz
- Jak automatyczne skalowanie podów poziomych (HPA) współpracuje z metrykami niestandardowymi i zewnętrznymi
- Skonfiguruj automatyczne skalowanie podów pionowych (VPA) w celu automatycznego dostosowania rozmiaru
- KEDA: automatyczne skalowanie sterowane zdarzeniami w kolejkach SQS, Kafka, Redis i Prometheus
- Karpenter: Dostarczanie węzłów na czas za pomocą NodePool i NodeClass
- Wzór kombinowany: Używaj HPA i KEDA razem bez konfliktów
- Rozwiązywanie problemów: dlaczego HPA nie skaluje się zgodnie z oczekiwaniami
- Najlepsze praktyki pozwalające uniknąć zapętlenia się klap i rozruchu na zimno
Poziomy autoskaler podów (HPA)
Komponent HPA i Kubernetes skalujący liczbę replik wdrożenia, StatefulSet o ReplicaSet na podstawie zaobserwowanych wskaźników. Kontroler HPA co jakiś czas sprawdza metryki 15 sekund (konfigurowalne) i oblicz żądaną liczbę replik ze wzoru:
desiredReplicas = ceil(currentReplicas * (currentMetricValue / desiredMetricValue))
Aby uniknąć trzepotania (ciągłego skalowania w górę i w dół), HPA ma okres stabilizacji: Domyślnie 5 minut na skalowanie w dół i 0 sekund na skalowanie w górę.
HPA na procesorze i pamięci
Podstawowa konfiguracja z procesorem i pamięcią. Należy pamiętać, że aby skalować do pamięci, plik application musi zwolnić pamięć, gdy obciążenie spada, w przeciwnym razie skalowanie w dół nigdy nie nastąpi:
# hpa-basic.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # scala quando CPU media > 60%
- type: Resource
resource:
name: memory
target:
type: AverageValue
averageValue: "512Mi" # scala quando memoria media > 512Mi
behavior:
scaleUp:
stabilizationWindowSeconds: 0 # scala su immediatamente
policies:
- type: Percent
value: 100
periodSeconds: 60 # max raddoppio delle repliche al minuto
- type: Pods
value: 4
periodSeconds: 60 # o max 4 pod al minuto
selectPolicy: Max # usa la policy piu aggressiva
scaleDown:
stabilizationWindowSeconds: 300 # 5 minuti prima di scalare giu
policies:
- type: Percent
value: 25
periodSeconds: 60 # riduce max 25% delle repliche al minuto
selectPolicy: Min
HPA z niestandardowymi metrykami za pośrednictwem adaptera Prometheus
Aby skalować w oparciu o metryki aplikacji (żądania na sekundę, długość kolejki itp.), potrzebujesz Adapter Prometheus udostępniający metryki Prometheus jako niestandardowe metryki Kubernetes API:
# Installa Prometheus Adapter
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
--set prometheus.url=http://kube-prometheus-stack-prometheus.monitoring.svc \
--set prometheus.port=9090
# prometheus-adapter-config.yaml - regola di mapping metrica
rules:
custom:
- seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)_total$"
as: "${1}_per_second"
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
---
# hpa-custom-metric.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-rps-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 2
maxReplicas: 50
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000" # 1000 req/s per Pod
HPA z metrykami zewnętrznymi
Metryki zewnętrzne umożliwiają skalowanie do źródeł spoza klastra, takich jak długość kolejki SQS lub ilość niewykorzystanych komunikatów Kafki:
# hpa-external-metric.yaml
# Scala in base alla lunghezza di una coda SQS
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker-queue-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-worker
minReplicas: 1
maxReplicas: 100
metrics:
- type: External
external:
metric:
name: sqs_approximate_number_of_messages_visible
selector:
matchLabels:
queue: "job-queue-prod"
target:
type: AverageValue
averageValue: "10" # 10 messaggi per worker
# Verifica stato HPA
kubectl get hpa -n production -w
kubectl describe hpa api-server-hpa -n production
Pionowe automatyczne skalowanie podów (VPA)
VPA monitoruje rzeczywiste wykorzystanie procesora i pamięci Twoich Podów i automatycznie je dostosowuje
ja resources.requests e limits. I rozwiązanie problemu
„śmieci, śmieci” żądań zasobów: jeśli nie wiesz, ile zasobów potrzebujesz
Pod, VPA dowie się o tym za Ciebie.
VPA i HPA: uważaj na konflikty
Nie używaj VPA w trybie Auto wraz ze skalowaniem HPA do procesora lub pamięci:
oba kontrolery będą w konflikcie. Prawidłowa kombinacja to: VPA w trybie
Off o Initial dla żądań zasobów i HPA dla replikacji
na metrykach niestandardowych. Lub użyj KEDA zamiast HPA, aby uniknąć problemu.
Instalacja i konfiguracja VPA
# Installa VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-install.sh
# oppure con Helm
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm install vpa fairwinds-stable/vpa --namespace vpa --create-namespace
---
# vpa-recommendation.yaml - modalita Off (solo raccomandazioni)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-server-vpa
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
updatePolicy:
updateMode: "Off" # Off|Initial|Recreate|Auto
resourcePolicy:
containerPolicies:
- containerName: api-server
minAllowed:
cpu: "100m"
memory: "128Mi"
maxAllowed:
cpu: "4"
memory: "4Gi"
controlledResources: ["cpu", "memory"]
controlledValues: RequestsAndLimits
# Leggi le raccomandazioni VPA
kubectl describe vpa api-server-vpa -n production
# Output tipico:
# Recommendation:
# Container Recommendations:
# Container Name: api-server
# Lower Bound: cpu: 100m, memory: 256Mi
# Target: cpu: 450m, memory: 512Mi
# Uncapped Target: cpu: 450m, memory: 512Mi
# Upper Bound: cpu: 2000m, memory: 2Gi
VPA w trybie automatycznym
# vpa-auto.yaml - aggiorna automaticamente i resource (riavvia i Pod)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: background-worker-vpa
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: background-worker
updatePolicy:
updateMode: "Auto" # Riavvia i Pod con i nuovi resource
minReplicas: 2 # Non aggiornare se le repliche sono meno di 2
resourcePolicy:
containerPolicies:
- containerName: worker
minAllowed:
cpu: "200m"
memory: "256Mi"
maxAllowed:
cpu: "2"
memory: "2Gi"
KEDA: automatyczne skalowanie sterowane zdarzeniami
KEDA (Kubernetes Event-Driven Autoscaling) to operator CNCF, który rozszerza HPA o Ponad 60 gotowych skalerów: AWS SQS, Azure Service Bus, Kafka, RabbitMQ, Redis, Prometheus, Datadog i wiele innych. KEDA może skalować wdrożenie do 0 replik, gdy nie ma żadnych zdarzeń i ustaw go z powrotem na 1, gdy nadejdzie pierwsze zdarzenie.
Instalacja KEDA
# Installa KEDA via Helm
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda \
--namespace keda \
--create-namespace \
--version 2.14.0
# Verifica
kubectl get pods -n keda
ScaledObject dla Kafki
Pracownik korzystający z tematu Kafki skaluje się w oparciu o opóźnienie grupy konsumentów:
# keda-kafka-scaledobject.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-consumer-scaler
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: kafka-consumer
pollingInterval: 15 # controlla ogni 15 secondi
cooldownPeriod: 30 # aspetta 30s prima di scalare a 0
minReplicaCount: 0 # scala a zero se non ci sono messaggi
maxReplicaCount: 50
advanced:
restoreToOriginalReplicaCount: true
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 30
triggers:
- type: kafka
metadata:
bootstrapServers: kafka-broker.kafka.svc:9092
consumerGroup: my-consumer-group
topic: orders-topic
lagThreshold: "100" # 100 messaggi per replica
offsetResetPolicy: latest
allowIdleConsumers: "false"
scaleToZeroOnInvalidOffset: "false"
authenticationRef:
name: kafka-auth # TriggerAuthentication con credenziali Kafka
ScaledObject dla AWS SQS
# keda-sqs-scaledobject.yaml
apiVersion: v1
kind: Secret
metadata:
name: aws-credentials
namespace: production
data:
AWS_ACCESS_KEY_ID: BASE64_KEY
AWS_SECRET_ACCESS_KEY: BASE64_SECRET
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: aws-trigger-auth
namespace: production
spec:
secretTargetRef:
- parameter: awsAccessKeyID
name: aws-credentials
key: AWS_ACCESS_KEY_ID
- parameter: awsSecretAccessKey
name: aws-credentials
key: AWS_SECRET_ACCESS_KEY
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sqs-worker-scaler
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sqs-worker
minReplicaCount: 0
maxReplicaCount: 100
triggers:
- type: aws-sqs-queue
authenticationRef:
name: aws-trigger-auth
metadata:
queueURL: https://sqs.eu-west-1.amazonaws.com/123456789/job-queue
queueLength: "5" # 5 messaggi per replica
awsRegion: eu-west-1
identityOwner: pod # usa IRSA se disponibile
ScaledObject na Prometeuszu
# keda-prometheus-scaledobject.yaml
# Scala in base a una query Prometheus personalizzata
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: api-latency-scaler
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicaCount: 2
maxReplicaCount: 30
triggers:
- type: prometheus
metadata:
serverAddress: http://kube-prometheus-stack-prometheus.monitoring.svc:9090
metricName: http_request_duration_p99
threshold: "0.5" # scala se P99 latency > 500ms
query: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{job="api-server"}[2m])) by (le))
# Verifica stato KEDA
kubectl get scaledobject -n production
kubectl describe scaledobject kafka-consumer-scaler -n production
Karpenter: Dostarczanie węzłów na czas
Karpenter to dostawca węzłów nowej generacji stworzony przez AWS, a obecnie projekt CNCF. W przeciwieństwie do Cluster Autoscaler, który działa z predefiniowanymi grupami węzłów, Karpenter węzły zaopatrzenia o dokładne cechy wymagane przez oczekujące Pody: typ instancji, obszar, pojemność na żądanie lub miejsce, procesor/GPU. Wynik: udostępnienie w 30–60 sekund w porównaniu do 3–5 minut w przypadku automatycznego skalowania klastrów.
Architektura Karpentera
Karpenter całkowicie zastępuje Cluster Autoscaler. Zawiera dwa główne CRD:
- Pula węzłów: definiuje wymagania węzłów, które Karpenter może utworzyć (typy instancji, strefy, skażenia, etykiety, limity)
- NodeClass (EC2NodeClass na AWS): konfiguracja specyficzna dla dostawcy chmury (AMI, podsieć, grupy zabezpieczeń, dane użytkownika)
Instalacja stolarska na EKS-ie
# Prerequisiti: IRSA configurata per Karpenter
export CLUSTER_NAME="my-production-cluster"
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export AWS_REGION=eu-west-1
# Installa Karpenter con Helm
helm repo add karpenter https://charts.karpenter.sh/
helm repo update
helm upgrade --install karpenter karpenter/karpenter \
--namespace karpenter \
--create-namespace \
--version 1.0.0 \
--set serviceAccount.annotations."eks.amazonaws.com/role-arn"=arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterControllerRole \
--set settings.clusterName=${CLUSTER_NAME} \
--set settings.interruptionQueue=${CLUSTER_NAME} \
--set controller.resources.requests.cpu=1 \
--set controller.resources.requests.memory=1Gi
NodePool i EC2NodeClass dla produkcji
# karpenter-nodepool.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: general-purpose
spec:
template:
metadata:
labels:
node-type: general-purpose
spec:
nodeClassRef:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand", "spot"] # preferisce spot, fallback on-demand
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"] # compute, memory, general
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ["2"] # solo istanze di generazione 3+
- key: karpenter.k8s.aws/instance-cpu
operator: In
values: ["4", "8", "16", "32"]
taints: []
expireAfter: 720h # ricicla nodi ogni 30 giorni
terminationGracePeriod: 48h
limits:
cpu: "500" # max 500 vCPU in questo NodePool
memory: 2000Gi
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 1m # consolida nodi vuoti dopo 1 minuto
budgets:
- nodes: "20%" # non drainare piu del 20% dei nodi alla volta
---
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2023
amiSelectorTerms:
- alias: al2023@latest # usa sempre la AMI piu recente
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "my-production-cluster"
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: "my-production-cluster"
instanceProfile: KarpenterNodeInstanceProfile
blockDeviceMappings:
- deviceName: /dev/xvda
ebs:
volumeSize: 100Gi
volumeType: gp3
iops: 3000
encrypted: true
metadataOptions:
httpEndpoint: enabled
httpProtocolIPv6: disabled
httpPutResponseHopLimit: 1 # sicurezza: blocca access IMDSv1 da container
httpTokens: required # richiede IMDSv2
NodePool dla obciążeń GPU
# karpenter-gpu-nodepool.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: gpu-nodes
spec:
template:
metadata:
labels:
node-type: gpu
spec:
nodeClassRef:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
name: gpu-nodeclass
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"] # GPU spot non disponibile in tutte le zone
- key: karpenter.k8s.aws/instance-family
operator: In
values: ["g5", "p3", "p4d"] # GPU instance families
taints:
- key: nvidia.com/gpu
effect: NoSchedule # solo Pod che tollerano questo taint
limits:
cpu: "128"
memory: 1024Gi
nvidia.com/gpu: "32" # max 32 GPU in questo NodePool
Konsolidacja i optymalizacja kosztów
# Forza la consolidazione immediata (utile per test)
kubectl annotate node karpenter.sh/do-not-disrupt-
# Vedi i nodi creati da Karpenter
kubectl get nodes -l karpenter.sh/nodepool=general-purpose -o wide
# Vedi le decisioni di Karpenter in tempo reale
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter -f | grep -E "launched|terminated|consolidated"
# Vedi quanto sta costando ogni nodo (con Kubecost)
kubectl get nodeclaims -o json | jq '.items[] | {name: .metadata.name, type: .status.providerID, price: .metadata.annotations["karpenter.sh/nodepool"]}'
Połącz HPA, KEDA i Karpenter
W dojrzałym klastrze produkcyjnym te trzy elementy działają synergicznie:
- KEDA skaluj Pody od 0 do N w oparciu o zdarzenia (opóźnienie Kafki, głębokość SQS, zapytanie Prometheus)
- Stolarz wykrywa oczekujące kapsuły i udostępnia węzły o dokładnie wymaganej charakterystyce w ciągu 30–60 sekund
- Umowa o partnerstwie (w trybie wyłączonym) udostępnia rekomendacje dotyczące żądań zasobów, które można zastosować ręcznie lub za pośrednictwem potoku CI/CD
Zalecany wzór do produkcji
- Bezstanowy interfejs API serwera: KEDA na Prometheusie (opóźnienie P99) + NodePool ogólnego przeznaczenia Karpenter
- Pracownik kolejki: KEDA na SQS/Kafka z minReplicas=0 + Karpenter z miksem na żądanie/spot
- Baza danych/StatefulSet: VPA w trybie Auto z minReplicas >= 2, brak HPA w pamięci
- Zadania wsadowe: KEDA ScaledJob (nie ScaledObject) do wykańczania zadań K8s
- Nie używaj HPA na procesorze razem z KEDA - prowadzi to do konfliktów w targetMetrics
Skalowane zadanie KEDA dla partii
# keda-scaledjob.yaml - per batch job che terminano
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: ml-training-job
namespace: production
spec:
jobTargetRef:
template:
spec:
containers:
- name: trainer
image: my-registry/ml-trainer:latest
resources:
requests:
cpu: "2"
memory: "4Gi"
nvidia.com/gpu: "1"
limits:
nvidia.com/gpu: "1"
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
restartPolicy: Never
pollingInterval: 30
maxReplicaCount: 20
successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 3
triggers:
- type: aws-sqs-queue
authenticationRef:
name: aws-trigger-auth
metadata:
queueURL: https://sqs.eu-west-1.amazonaws.com/123456789/ml-jobs
queueLength: "1" # 1 job per task
awsRegion: eu-west-1
Rozwiązywanie problemów z HPA i KEDA
# HPA non scala? Controlla lo stato
kubectl describe hpa api-server-hpa -n production
# Cerca: "AbleToScale", "ScalingActive", "DesiredReplicas"
# Errore comune: "failed to get cpu utilization" = metrics-server non installato
# Verifica che metrics-server funzioni
kubectl top pods -n production
kubectl top nodes
# KEDA non scala a zero? Controlla il cooldownPeriod
kubectl get scaledobject kafka-consumer-scaler -n production -o yaml | grep -A5 "conditions"
# Karpenter non provisiona?
kubectl get pods --field-selector=status.phase=Pending -A
kubectl describe pod | grep "Events" -A20
# Cerca: "0/N nodes are available" + il motivo del pending
# Vedi log Karpenter
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter --tail=50 | grep -i "error\|warning\|launched"
# Simula provisioning senza applicare
kubectl annotate pods karpenter.sh/do-not-disrupt=true
Najlepsze praktyki i anty-wzorce
Najlepsze praktyki dotyczące automatycznego skalowania
- Zawsze ustawiaj minReplicas >= 2 dla usług krytycznych: skalowanie od 0 wymaga zimnego startu; w przypadku interfejsów API w fazie produkcyjnej należy utrzymywać co najmniej 2 repliki
- Użyj PodDisruptionBudget: zapobiegają wysysaniu przez Karpenter/HPA zbyt wielu strąków podczas konsolidacji
- Skonfiguruj dokładne żądania zasobów: HPA oblicza procentowe wykorzystanie zasobów.requests; jeśli są zbyt niskie, nigdy się nie skaluje
- Ścisła sonda gotowości: Kubernetes czeka, aż kapsuła będzie gotowa, zanim wyśle ruch; Bez sond gotowości nowo skalowane kapsuły odbierają ruch, zanim będą gotowe
- Klapy monitora: jeśli HPA skaluje się w górę i w dół co kilka minut, zwiększ
stabilizationWindowSecondszmniejszania skali - Użyj ograniczeń rozproszenia topologii w Karpenterze: dystrybuuj Pody w różnych strefach, aby zapewnić wysoką dostępność nawet podczas udostępniania
Anty-wzorce, których należy unikać
- HPA bez zdefiniowanych żądań zasobów: HPA nie może obliczyć procentowego wykorzystania bez żądań w specyfikacji kontenera
- VPA Auto + HPA na procesorze/pamięci: obaj kontrolerzy konkurują o zasoby i powodują niespójne skalowanie; użyj KEDA na niestandardowych metrykach, jeśli chcesz obu
- maxRepliki za niskie: jeśli Twój szczytowy ruch wymaga 100 Podów, ale maxReplicas i 20, automatyczne skalowanie nie wystarczy i usługa ulega pogorszeniu
- Budżet Karpentera bez zakłóceń: bez
disruption.budgets, Karpenter może opróżnić 100% węzłów podczas nocnej konsolidacji - Interwał odpytywania za niski w KEDA: un
pollingInterval5 sekund na źródłach zewnętrznych (SQS, zewnętrzne API) generuje zbyt wiele wywołań API i możliwe dławienie
Wnioski i dalsze kroki
Efektywne autoskalowanie w Kubernetesie nie jest pojedynczym rozwiązaniem, ale wielokrotną strategią poziomy: KEDA do skalowania Podów sterowanego zdarzeniami, HPA do skalowania opartego na użyciu zasobów, VPA do optymalizacji żądań zasobów i Karpenter do udostępniania szybki w węzłach. Stosowane razem narzędzia te mogą obniżyć koszty o 30-50% w porównaniu do klastrów udostępnianych statycznie, przy zachowaniu wysokich umów SLA.
Kluczem do sukcesu jest dokładna konfiguracja żądań zasobów (pomaga tu VPA), wybór odpowiednich metryk do skalowania (nie zawsze procesora i odpowiedzi) oraz konfiguracja zachowania skalowania (okresy stabilizacji, ograniczenie szybkości) aby uniknąć oscylacji, które mogą pogorszyć wydajność, zamiast ją poprawić.







