Powrót do strony głównej

Jak Kubernetes zarządza skalowaniem kontenerów i równoważeniem obciążenia

Ten artykuł zawiera kompleksowy przewodnik techniczny dotyczący mechanizmów skalowania i równoważenia obciążenia w Kubernetes. Obejmuje Horizontal Pod Autoscaler z niestandardowymi metrykami, Cluster Autoscaler, kube-proxy, Ingress oraz implementacje siatki usług, aby pomóc inżynierom projektować odporne, zoptymalizowane kosztowo wdrożenia kontenerów.

Skalowanie Kubernetes i równoważenie obciążenia: kompletny przewodnik
Advertisement 728x90

Opanowanie skalowania i równoważenia obciążenia w Kubernetes

Podczas wdrażania konteneryzowanych aplikacji w środowisku produkcyjnym dwie najbardziej krytyczne operacyjne zadania to zapewnienie zdolności systemu do radzenia sobie z wahaniami ruchu oraz utrzymanie wysokiej dostępności bez ręcznej interwencji. Kubernetes, faktyczny standard orkiestracji kontenerów, rozwiązuje te zadania za pomocą zaawansowanego zestawu narzędzi zarządzania, automatyzujących zarówno skalowanie, jak i dystrybucję ruchu, ale wiele zespołów ma trudności z wyjściem poza podstawowe konfiguracje. Zrozumienie wewnętrznych mechanizmów działania Kubernetes w zakresie skalowania kontenerów i równoważenia obciążenia pozwoli Ci projektować odporne na awarie systemy, które dostosowują się do obciążenia w czasie rzeczywistym, optymalizując koszty zasobów i eliminując pojedyncze punkty awarii.

Czego się nauczysz

Zrozumiesz pętle sterowania, potoki metryk i proxy sieciowe, które zapewniają automatyczne skalowanie i wykrywanie usług w Kubernetes, a pod koniec będziesz w stanie diagnozować wąskie gardła skalowania, wybierać odpowiednią strategię równoważenia obciążenia dla swojego obciążenia oraz wdrażać konfiguracje gotowe do produkcji, które wytrzymują nagłe skoki ruchu bez przestojów. Najważniejszy wniosek jest taki, że efektywne skalowanie w Kubernetes wymaga holistycznego podejścia, w którym Horizontal Pod Autoscaler, cluster autoscaler i komponenty service mesh działają spójnie, a nie jako izolowane funkcje.

Dwa filary: skalowanie horyzontalne i równoważenie obciążenia usług

Kubernetes zapewnia elastyczność za pomocą dwóch uzupełniających się mechanizmów: skalowania liczby replik aplikacji (podów) oraz dystrybucji ruchu sieciowego między tymi replikami. Płaszczyzna sterowania nieprzerwanie ocenia metryki zasobów i niestandardowe wskaźniki, aby zdecydować, kiedy dodać lub usunąć pody, podczas gdy płaszczyzna danych używa abstrakcji usługi opartej na wirtualnym IP do kierowania zapytań do działających punktów końcowych. To rozdzielenie odpowiedzialności – decyzje o skalowaniu podejmowane są przez kontrolery, a routing ruchu zarządzany jest przez kube-proxy lub sidecar-proxy service mesh – pozwala każdej podsystemowi rozwijać się niezależnie, choć w praktyce są one głęboko współzależne.

Google AdInline article slot

Jak działa Horizontal Pod Autoscaler

Horizontal Pod Autoscaler (HPA) to podstawowy mechanizm, w jaki Kubernetes zarządza skalowaniem kontenerów i równoważeniem obciążenia na poziomie podów. HPA działa jako pętla sterowania, która okresowo odpytuje serwer metryk (zazwyczaj Kubernetes Metrics Server dla metryk zasobów lub niestandardowy adapter metryk dla sygnałów specyficznych dla aplikacji) i porównuje obserwowane wartości z docelowymi. Dla skalowania opartego na CPU algorytm oblicza pożądaną liczbę replik według wzoru:

desiredReplicas = ceil(currentReplicas * (currentMetricValue / desiredMetricValue))

To proste sterowanie proporcjonalne działa dobrze dla stabilnych obciążeń, ale może powodować oscylacje, jeśli metryka szybko się zmienia. Aby to złagodzić, HPA zawiera funkcje stabilizacji – domyślnie unika skalowania w dół przez pięć minut i skaluje w górę dopiero po oknie 3-15 sekund w zależności od konfiguracji – aby zapobiec „trzepotaniu”. Według oficjalnej dokumentacji Kubernetes, kontroler HPA podejmuje decyzje o skalowaniu na podstawie średniej arytmetycznej metryk podów, co oznacza, że jeden „gorący” pod może zniekształcić średnią i wywołać niepotrzebne skalowanie w górę (Kubernetes SIG-Autoscaling, 2023).

Niestandardowe i zewnętrzne metryki dla zaawansowanego autoskalowania

Skalowanie oparte na zasobach (CPU i pamięć) często nie wystarcza dla nowoczesnych mikrousług, których wąskie gardła występują w głębokości kolejki komunikatów, pulach połączeń z bazą danych lub opóźnieniach zapytań. Kubernetes rozwiązuje ten problem za pomocą Custom Metrics API i External Metrics API, które pozwalają HPA konsumować metryki z Prometheus, Datadog lub systemów monitorowania dostawców chmurowych. Na przykład wdrożenie konsumenta Kafka może skalować się na podstawie opóźnienia offsetów grupy konsumentów, gwarantując, że wydajność przetwarzania odpowiada ilości danych wejściowych niezależnie od obciążenia CPU. Badanie z 2022 roku opublikowane w IEEE Transactions on Cloud Computing wykazało, że autoskalowanie oparte na niestandardowych metrykach zmniejszyło opóźnienie na ogonie o 42% w porównaniu ze skalowaniem tylko według CPU w architekturach zdarzeniowych, choć wymagało starannego dostrojenia interwałów zbierania metryk (Chen et al., 2022). Podczas wdrażania niestandardowych metryk upewnij się, że Twój adapter metryk dostarcza dane z wystarczającą szczegółowością – próbkowanie co 30 sekund jest powszechnym poziomem bazowym, podczas gdy systemy handlu wysokiej częstotliwości mogą wymagać rozdzielczości 5 sekund.

Google AdInline article slot

Cluster Autoscaler i skalowanie na poziomie węzłów

Podczas gdy HPA reguluje liczbę podów, Cluster Autoscaler reguluje liczbę węzłów roboczych w podstawowej infrastrukturze chmurowej. Ta dwupoziomowa hierarchia tworzy łańcuch zależności: Cluster Autoscaler uruchamia dodawanie węzłów tylko wtedy, gdy istnieją nieprzydzielone pody z powodu braku zasobów, i usuwa węzły, gdy stają się niedociążone, a wszystkie ich pody mogą zostać przeniesione gdzie indziej. Oficjalne FAQ Cluster Autoscaler zauważa, że decyzje o skalowaniu węzłów podejmowane są z 10-minutowym oknem stabilizacji, aby uniknąć częstej zmiany rozmiaru, co może być problematyczne dla obciążeń z nagłymi, trwałymi skokami, ponieważ łączne opóźnienie (HPA skaluje pody w górę + Cluster Autoscaler dostarcza węzły + ładowanie węzłów) może przekraczać pięć minut w wielu środowiskach chmurowych. Dla aplikacji wrażliwych na opóźnienia rozważ użycie pul węzłów z wstępnie przydzieloną rezerwą mocy lub wdrożenie wyprzedzającego skalowania opartego na przewidywanym popycie – ta metoda została zbadana w artykule naukowym „Proactive Autoscaling for Kubernetes” (arXiv:2301.04567, 2023), gdzie wykazano zmniejszenie opóźnienia skalowania o 30% przy użyciu modeli predykcyjnych.

Routing ruchu: abstrakcja Service i kube-proxy

Skalowanie podów to tylko połowa rozwiązania; konieczne jest również dystrybuowanie przychodzącego ruchu do odpowiedniego zestawu działających replik. Każdy obiekt Service w Kubernetes działa jako stabilny wewnętrzny load balancer, udostępniając stały adres IP i nazwę DNS, które abstrahują dynamiczne punkty końcowe podów. Domyślna implementacja używa kube-proxy, który działa na każdym węźle i utrzymuje reguły iptables lub IPVS, przekształcające adresy IP usług na rzeczywiste adresy IP podów. W trybie iptables każda usługa tworzy probabilistyczny łańcuch reguł – rozkład prawdopodobieństwa jest proporcjonalny do wagi każdego poda, co w praktyce zapewnia równoważenie metodą round-robin. Jednak podejście iptables może cierpieć na spadek wydajności podczas skalowania: klaster z 5000 usług i 50 000 punktów końcowych może doświadczać opóźnień aktualizacji reguł wynoszących 10-15 sekund, co zostało udokumentowane w testach wydajności Kubernetes. Tryb IPVS, oparty na module jądra Linux virtual server, zapewnia lepszą skalowalność dla dużych klastrów i obsługuje kilka algorytmów równoważenia obciążenia (round-robin, least connections, source hashing), które można wybrać za pomocą flagi --ipvs-scheduler.

Typy usług i dostęp zewnętrzny

Dla ruchu zewnętrznego wchodzącego do klastra Kubernetes udostępnia trzy typy usług: NodePort, LoadBalancer i Ingress. NodePort otwiera statyczny port na adresie IP każdego węzła, odpowiedni do programowania lub środowisk lokalnych, gdzie nie ma osobnego zewnętrznego load balancera. Typ LoadBalancer integruje się z API dostawców chmurowych (AWS ELB, Azure Load Balancer, GCP Cloud Load Balancing) w celu udostępnienia dedykowanego zewnętrznego load balancera, który przekierowuje ruch na NodePorty wszystkich węzłów. To podejście przenosi sprawdzanie stanu i zakończenie SSL na dostawcę chmury, ale pociąga za sobą koszty na każdy zasób – na przykład AWS Application Load Balancers kosztują około $0,0225 za godzinę plus opłaty za przetwarzanie danych (AWS Pricing, 2024). Ingress z kolei działa na poziomie HTTP/HTTPS i zapewnia routing oparty na ścieżce i hoście, pozwalając jednemu load balancerowi obsługiwać wiele usług. Kontroler Ingress (NGINX, Traefik lub AWS ALB Ingress Controller) implementuje rzeczywiste reguły routingu i wykonuje zakończenie TLS, buforowanie i ograniczanie prędkości.

Google AdInline article slot

Zaawansowane równoważenie obciążenia z Service Mesh

Dla zespołów wymagających precyzyjnej kontroli nad zachowaniem ruchu – takich jak wdrożenia canary, circuit breaking czy wprowadzanie awarii – service mesh, taki jak Istio lub Linkerd, zapewnia potężniejszą alternatywę dla kube-proxy. Te meshe wdrażają sidecar-proxy (Envoy lub Linkerd2-proxy) obok każdego poda, tworząc dedykowaną płaszczyznę danych, która przechwytuje cały ruch przychodzący i wychodzący. Płaszczyzna sterowania zarządza dystrybucją konfiguracji i zbieraniem telemetrii, umożliwiając złożone polityki równoważenia obciążenia na poziomie aplikacji. Według analizy z 2023 roku przeprowadzonej przez społeczność użytkowników końcowych Cloud Native Computing Foundation, wdrożenie service mesh koreluje ze skróceniem czasu odzyskiwania po częściowych awariach o 45%, co tłumaczy się automatycznymi ponownymi próbami i wykrywaniem odchyleń. Jednak narzut jest znaczący: proxy Envoy z Istio dodaje około 5-10 ms opóźnienia na każdy przeskok i zużywa 0,5-1 vCPU na pod przy umiarkowanym ruchu. Wybierając między kube-proxy a service mesh, rozważ, czy Twoje wymagania wykraczają poza podstawową dystrybucję round-robin – jeśli potrzebujesz mirrorowania ruchu, uwierzytelniania JWT lub ważonego routingu opartego na nagłówkach HTTP, service mesh jest uzasadniony; w przeciwnym razie wystarczą natywne zasoby Service i Ingress.

Horizontal Pod Autoscaling w praktyce: konfiguracja i dostrajanie

Aby zilustrować, jak Kubernetes zarządza skalowaniem kontenerów i równoważeniem obciążenia w rzeczywistym wdrożeniu, rozważmy typową aplikację webową z następującą konfiguracją HPA:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "500"
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Pods
        value: 2
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
      - type: Pods
        value: 5
        periodSeconds: 30
      - type: Percent
        value: 100
        periodSeconds: 30
      selectPolicy: Max

Ten HPA używa zarówno obciążenia CPU, jak i niestandardowej metryki szybkości żądań HTTP, z oddzielnymi oknami stabilizacji i politykami skalowania. Polityka scaleUp priorytetyzuje najbardziej agresywną opcję (albo dodanie 5 podów, albo podwojenie bieżącej liczby) co 30 sekund, co pozwala na szybką reakcję na skoki ruchu. Polityka scaleDown ogranicza usuwanie do 2 podów na minutę po 5-minutowym okresie ochłodzenia, zapobiegając oscylacjom przy zmiennym obciążeniu. Okna stabilizacji – 300 sekund dla skalowania w dół i 30 sekund dla skalowania w górę – pochodzą z domyślnych zaleceń w przewodniku po HPA od Kubernetes, dostosowanych dla aplikacji webowej z przewidywalnymi dziennymi wzorcami ruchu.

Częste błędy i strategie ich łagodzenia

Nawet przy prawidłowej konfiguracji zespoły często napotykają problemy ze skalowaniem i równoważeniem obciążenia w Kubernetes. Jednym z powszechnych problemów jest efekt „stada” (thundering herd), gdy nagły skok ruchu powoduje, że HPA skaluje wiele replik jednocześnie, przeciążając scheduler i API server. Aby tego uniknąć, użyj spec.behavior.scaleUp.selectPolicy: Max z mniejszą wartością periodSeconds, aby rozłożyć zdarzenia skalowania na kilka cykli. Innym błędem jest poleganie wyłącznie na metrykach CPU dla aplikacji intensywnie korzystających z pamięci – aplikacje Java z dużymi stertami mogą wykazywać wysokie użycie pamięci przy niskim obciążeniu CPU, co uniemożliwia HPA uruchomienie skalowania. Rozwiązaniem jest użycie metryk opartych na pamięci lub niestandardowych metryk odzwierciedlających przepustowość aplikacji. Ponadto upewnij się, że Twój load balancer (kube-proxy lub service mesh) wykonuje sprawdzanie stanu z odpowiednimi progami – domyślny próg dla readiness probe (3 niepowodzenia w ciągu 10 sekund) może być zbyt agresywny dla aplikacji Java z opóźnieniem zimnego startu; rozważ zwiększenie initialDelaySeconds do 60-120 sekund w zależności od czasu uruchamiania Twojej aplikacji.

Monitorowanie i obserwowalność dla decyzji o skalowaniu

Efektywne skalowanie wymaga widoczności zarówno metryk na poziomie systemu, jak i wskaźników biznesowych. Ekosystem Prometheus w połączeniu z dashboardami Grafana jest faktycznym standardem dla obserwowalności Kubernetes. Kluczowe metryki do monitorowania:

  • Status HPA: kube_horizontalpodautoscaler_status_desired_replicas i kube_horizontalpodautoscaler_status_current_replicas do wykrywania opóźnień skalowania
  • Opóźnienie planowania: kube_scheduler_e2e_scheduling_duration_seconds do identyfikacji wąskich gardeł w rozmieszczaniu podów
  • Stan load balancera: kube_service_status_load_balancer_ingress dla chmurowych load balancerów
  • Opóźnienie zapytań i wskaźnik błędów: pochodne z metryk Istio lub NGINX Ingress do korelacji działań skalowania z doświadczeniem użytkownika

Według raportu „State of Kubernetes Observability 2024” od D2iQ, zespoły, które instrumentują niestandardowe metryki biznesowe (np. aktywne sesje, głębokość kolejki, szybkość transakcji płatniczych), doświadczają o 38% mniej incydentów nadmiernego przydzielania zasobów w porównaniu z zespołami używającymi tylko metryk CPU/pamięci. Jest to zgodne z zaleceniem Google Cloud Architecture Center, aby definiować Service Level Objectives (SLO), które kierują działaniami skalowania – na przykład skalowanie, gdy 99. percentyl opóźnienia przekracza 200 ms przez ponad 2 minuty, a nie reagowanie tylko na metryki zasobów.

Często zadawane pytania

Czy Kubernetes automatycznie skaluje kontenery na podstawie ruchu lub CPU? Tak, Kubernetes może automatycznie skalować kontenery za pomocą Horizontal Pod Autoscaler, który reguluje liczbę replik na podstawie obserwowanego obciążenia CPU, zużycia pamięci lub niestandardowych metryk, takich jak szybkość żądań. Jednak autoskalowanie nie jest włączone domyślnie – musisz jawnie zdefiniować zasób HPA z politykami skalowania i progami metryk dla swojego wdrożenia.

Jak Kubernetes równoważy ruch między podami? Usługi Kubernetes zapewniają wewnętrzne równoważenie obciążenia za pomocą kube-proxy, który utrzymuje reguły sieciowe dystrybuujące ruch do punktów końcowych podów przez iptables lub IPVS. Dla ruchu zewnętrznego kontrolery Ingress lub chmurowe usługi LoadBalancer obsługują routing. Równoważenie obciążenia odbywa się zazwyczaj metodą round-robin, ale service mesh oferują bardziej zaawansowane algorytmy, takie jak least-requests lub consistent hashing.

Jaka jest różnica między Horizontal Pod Autoscaler a Cluster Autoscaler? Horizontal Pod Autoscaler reguluje liczbę replik podów w ramach wdrożenia na podstawie metryk popytu, podczas gdy Cluster Autoscaler reguluje liczbę węzłów roboczych w klastrze, gdy pody nie mogą być zaplanowane z powodu braku zasobów. Działają one uzupełniająco: HPA reaguje na zmiany obciążenia, a Cluster Autoscaler dostarcza podstawową infrastrukturę do obsługi zwiększonej liczby podów.

Czy mogę skalować pody Kubernetes na podstawie niestandardowych metryk aplikacji? Oczywiście. Kubernetes obsługuje niestandardowe i zewnętrzne metryki przez Custom Metrics API i External Metrics API. Musisz wdrożyć adapter metryk, taki jak Prometheus Adapter lub Datadog Cluster Agent, który dostarcza metryki specyficzne dla Twojej aplikacji do kontrolera HPA. Typowe niestandardowe metryki obejmują długość kolejki, aktywne połączenia lub szybkość przetwarzania zamówień.

Jakie algorytmy równoważenia obciążenia obsługuje Kubernetes? Natywna usługa (kube-proxy) obsługuje round-robin, a w trybie IPVS dodatkowe algorytmy, takie jak least connections, source hashing i ważony round-robin. Kontrolery Ingress i service mesh rozszerzają to o routing HTTP, wdrożenia canary i wzorce circuit breaking. Wybór zależy od wzorców ruchu Twojej aplikacji – proste usługi bezstanowe dobrze działają z round-robin, podczas gdy scenariusze stanowe lub z lepkimi sesjami wymagają session affinity lub consistent hashing.

Źródła

  1. Kubernetes SIG-Autoscaling. (2023). Horizontal Pod Autoscaler Walkthrough. Kubernetes Documentation. https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
  2. Chen, L., et al. (2022). "Custom-Metric Autoscaling for Microservices: A Comparative Study." IEEE Transactions on Cloud Computing, 10(4): 2891-2905.
  3. Kubernetes Cluster Autoscaler. (2024). FAQ and Best Practices. https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler
  4. Zhao, W., & Zhang, Y. (2023). "Proactive Autoscaling for Kubernetes Using Predictive Models." arXiv:2301.04567.
  5. Cloud Native Computing Foundation. (2023). Service Mesh End-User Survey Report. CNCF Technical Advisory Group.
  6. AWS Pricing. (2024). Elastic Load Balancing Pricing. https://aws.amazon.com/elasticloadbalancing/pricing/
  7. D2iQ. (2024). State of Kubernetes Observability 2024. Industry Report.
  8. Google Cloud Architecture Center. (2023). Scaling Microservices with Kubernetes. https://cloud.google.com/architecture/scaling-microservices

— Editorial Team

Advertisement 728x90

Czytaj dalej