Skalowalność jest kluczowym wymaganiem w przypadku aplikacji w chmurze. Dzięki Kubernetes skalowanie aplikacji jest tak proste, jak zwiększenie liczby replik w celu odpowiedniego wdrożenia lub ReplicaSet — ale jest to proces ręczny.
Kubernetes umożliwia automatyczne skalowanie aplikacji (tj. Podów we wdrożeniu lub ReplicaSet) w sposób deklaratywny przy użyciu specyfikacji autoskalera poziomego podu. Domyślnym kryterium automatycznego skalowania są metryki użycia procesora (metryki zasobów), ale można zintegrować metryki niestandardowe i dostarczone zewnętrznie.
Zespół Kubernetes aaS z Mail.ru przetłumaczył artykuł o tym, jak wykorzystać zewnętrzne metryki do automatycznego skalowania aplikacji Kubernetes. Aby pokazać jak to wszystko działa, autor wykorzystuje metryki żądań dostępu HTTP, które zbierane są za pomocą Prometheusa.
Zamiast poziomego automatycznego skalowania podów używany jest Kubernetes Event Driven Autoscaling (KEDA), operator Kubernetes typu open source. Integruje się natywnie z modułem automatycznego skalowania podów poziomych, aby zapewnić płynne automatyczne skalowanie (w tym do/od zera) w przypadku obciążeń sterowanych zdarzeniami. Kod dostępny pod adresem GitHub.
Krótki przegląd systemu
Diagram przedstawia krótki opis działania wszystkiego:
Aplikacja udostępnia metryki liczby trafień HTTP w formacie Prometheus.
Prometheus jest skonfigurowany do zbierania tych metryk.
Skaler Prometheus w KEDA jest skonfigurowany tak, aby automatycznie skalować aplikację na podstawie liczby trafień HTTP.
Teraz opowiem szczegółowo o każdym elemencie.
KEDA i Prometeusz
Prometheus to zestaw narzędzi do monitorowania i ostrzegania systemu typu open source, część Fundacja Cloud Native Computing. Zbiera metryki z różnych źródeł i przechowuje je jako dane szeregów czasowych. Aby zwizualizować dane, których możesz użyć grafana lub inne narzędzia do wizualizacji współpracujące z Kubernetes API.
KEDA wspiera koncepcję skalera - pełni rolę pomostu pomiędzy KEDA a systemem zewnętrznym. Implementacja skalera jest specyficzna dla każdego systemu docelowego i wydobywa z niego dane. Następnie KEDA wykorzystuje je do kontrolowania automatycznego skalowania.
Skalery obsługują wiele źródeł danych, na przykład Kafka, Redis, Prometheus. Oznacza to, że KEDA może służyć do automatycznego skalowania wdrożeń Kubernetes przy użyciu metryk Prometheusa jako kryteriów.
Aplikacja testowa
Aplikacja testowa Golang zapewnia dostęp poprzez HTTP i spełnia dwie ważne funkcje:
Używa biblioteki klienta Prometheus Go do instrumentowania aplikacji i udostępniania metryki http_requests, która zawiera liczbę trafień. Punkt końcowy, w którym dostępne są metryki Prometheus, znajduje się w identyfikatorze URI /metrics.
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "http_requests",
Help: "number of http requests",
})
W odpowiedzi na prośbę GET aplikacja zwiększa wartość klucza (access_count) w Redisie. Jest to prosty sposób na wykonanie pracy w ramach procedury obsługi HTTP i sprawdzenie metryk Prometheusa. Wartość metryki musi być taka sama jak wartość access_count w Redisie.
Aplikacja jest wdrażana w Kubernetes za pośrednictwem Deployment. Tworzony jest także serwis ClusterIPumożliwia serwerowi Prometheus uzyskanie metryk aplikacji.
Skaler pełni rolę pomostu pomiędzy KEDA a systemem zewnętrznym, z którego należy uzyskać metryki. ScaledObject to zasób niestandardowy, który należy wdrożyć, aby zsynchronizować wdrożenie ze źródłem zdarzenia, w tym przypadku Prometheusem.
ScaledObject zawiera informacje o skalowaniu wdrożenia, metadane źródła zdarzeń (takie jak klucze tajne połączenia, nazwa kolejki), interwał odpytywania, okres przywracania i inne dane. Powoduje to odpowiedni zasób automatycznego skalowania (definicja HPA) umożliwiający skalowanie wdrożenia.
Kiedy obiekt ScaledObject zostanie usunięty, odpowiednia definicja HPA zostanie wyczyszczona.
Oto definicja ScaledObject w naszym przykładzie używa skalera Prometheus:
Typ wyzwalacza - Prometheus. Adres serwera Prometheus jest wymieniony wraz z nazwą metryki, progiem i Zapytanie PromQL, który będzie używany. Zapytanie PromQL — sum(rate(http_requests[2m])).
Według pollingInterval,KEDA żąda od Prometeusza celu co piętnaście sekund. Przynajmniej jeden poniżej (minReplicaCount), a maksymalna liczba strąków nie przekracza maxReplicaCount (w tym przykładzie - dziesięć).
Można zainstalować minReplicaCount równy zeru. W tym przypadku KEDA aktywuje wdrożenie „zero do jednego”, a następnie udostępnia HPA do dalszego automatycznego skalowania. Możliwa jest także kolejność odwrotna, czyli skalowanie od jednego do zera. W przykładzie nie wybraliśmy zera, ponieważ jest to usługa HTTP, a nie system na żądanie.
Magia automatycznego skalowania
Próg służy jako wyzwalacz skalowania wdrożenia. W naszym przykładzie zapytanie PromQL sum(rate (http_requests [2m])) zwraca zagregowaną liczbę żądań HTTP (żądań na sekundę) mierzoną w ciągu ostatnich dwóch minut.
Ponieważ wartość progowa wynosi trzy, oznacza to, że wartość będzie poniżej wartości sum(rate (http_requests [2m])) mniej niż trzy. Jeśli wartość wzrasta, za każdym razem dodawany jest dodatkowy sub sum(rate (http_requests [2m])) wzrasta o trzy. Na przykład, jeśli wartość wynosi od 12 do 14, liczba strąków wynosi cztery.
Teraz spróbujmy to skonfigurować!
Wstępne ustawienie
Wszystko czego potrzebujesz to klaster Kubernetes i skonfigurowane narzędzie kubectl. W tym przykładzie zastosowano klaster minikube, ale możesz wziąć dowolny inny. Aby zainstalować klaster, istnieje руководство.
kubectl apply -f prometheus.yaml
//output
clusterrole.rbac.authorization.k8s.io/prometheus created
serviceaccount/default configured
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
configmap/prom-conf created
deployment.extensions/prometheus-deployment created
service/prometheus-service created
Sprawdź, czy wszystko się rozpoczęło:
kubectl get pods -l=app=prometheus-server
Poczekaj, aż Prometeusz przejdzie do stanu Running.
Stosowanie kubectl port-forward aby uzyskać dostęp do interfejsu użytkownika Prometheus (lub serwera API) pod adresem http://localhost:9090.
KEDA_POD_NAME=$(kubectl get pods -n keda
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda
Wynik wygląda mniej więcej tak:
time="2019-10-15T09:38:28Z" level=info msg="Watching ScaledObject:
default/prometheus-scaledobject"
time="2019-10-15T09:38:28Z" level=info msg="Created HPA with
namespace default and name keda-hpa-go-prom-app"
Sprawdź w aplikacjach. Jedna instancja musi być uruchomiona, ponieważ minReplicaCount równa się 1:
kubectl get pods -l=app=go-prom-app
Sprawdź, czy zasób HPA został pomyślnie utworzony:
kubectl get hpa
Powinieneś zobaczyć coś takiego:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-go-prom-app Deployment/go-prom-app 0/3 (avg) 1 10 1 45s
Kontrola stanu: dostęp do aplikacji
Aby uzyskać dostęp do punktu końcowego REST naszej aplikacji, uruchom:
Możesz teraz uzyskać dostęp do aplikacji Go, korzystając z adresu http://localhost:8080. Aby to zrobić, uruchom polecenie:
curl http://localhost:8080/test
Wynik wygląda mniej więcej tak:
Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Access count 1
W tym momencie sprawdź także Redis. Zobaczysz, że to klucz access_count zwiększono do 1:
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Upewnij się, że wartość metryki to http_requests ten sam:
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1
Załaduj tworzenie
Użyjemy hej — narzędzie do generowania obciążenia:
W tym przypadku faktyczny wynik jest taki 1,686057971014493 i jest wyświetlany w polu value. To nie wystarczy do skalowania, ponieważ próg, który ustaliliśmy, wynosi 3.
Więcej obciążenia!
W nowym terminalu monitoruj liczbę podów aplikacyjnych:
kubectl get pods -l=app=go-prom-app -w
Zwiększmy obciążenie za pomocą polecenia:
./hey -n 2000 http://localhost:8080/test
Po chwili zobaczysz, jak HPA skaluje wdrożenie i uruchamia nowe pody. Sprawdź swój HPA, aby upewnić się, że:
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-go-prom-app Deployment/go-prom-app 1830m/3 (avg) 1 10 6 4m22s
Jeśli obciążenie jest niespójne, wdrożenie zostanie ograniczone do punktu, w którym działa tylko jeden zasobnik. Jeśli chcesz sprawdzić rzeczywistą metrykę (zwróconą przez zapytanie PromQL), użyj polecenia:
//Delete KEDA
kubectl delete namespace keda
//Delete the app, Prometheus server and KEDA scaled object
kubectl delete -f .
//Delete Redis
helm del --purge redis-server
wniosek
KEDA umożliwia automatyczne skalowanie wdrożeń Kubernetes (do/od zera) w oparciu o dane z metryk zewnętrznych. Na przykład w oparciu o metryki Prometheusa, długość kolejki w Redis, opóźnienia konsumenckie w temacie Kafka.
KEDA integruje się ze źródłem zewnętrznym, a także udostępnia swoje metryki poprzez serwer metryk do automatycznego skalowania podów poziomych.