
Skalierbarkeit ist eine entscheidende Anforderung für Cloud-Anwendungen. Mit Kubernetes ist es so einfach, eine Anwendung zu skalieren, wie die Anzahl der Repliken für das entsprechende Deployment zu erhöhen oder ReplicaSet — aber das ist ein manueller Prozess.
Kubernetes ermöglicht das automatische Skalieren von Anwendungen (d.h. Pods in einem Deployment oder ReplicaSet) deklarativ mithilfe der Spezifikation des Horizontal Pod Autoscaler. Standardmäßig ist das Kriterium für das automatische Skalieren eine Metrik zur Nutzung der CPU (Ressourcenschlüssel), aber es können benutzerdefinierte Metriken und Metriken von externen Quellen integriert werden.
Team übersetzte einen Artikel darüber, wie externe Metriken zum automatischen Skalieren einer Kubernetes-Anwendung verwendet werden können. Um zu zeigen, wie alles funktioniert, verwendet der Autor Metriken zu HTTP-Anfragen, die von Prometheus erfasst werden.
Anstelle des horizontalen automatischen Skalierens von Pods wird das Kubernetes Event Driven Autoscaling (KEDA) verwendet — ein Open-Source-Kubernetes-Operator. Er integriert sich von Anfang an mit dem Horizontal Pod Autoscaler, um ein nahtloses automatisches Skalieren (einschließlich Hoch- und Herunterskalierung) für ereignisgesteuerte Workloads zu ermöglichen. Der Code ist verfügbar unter .
Kurze Übersicht über die Funktionsweise des Systems

Das Diagramm zeigt eine kurze Beschreibung, wie alles funktioniert:
- Die Anwendung liefert Metriken über die Anzahl der HTTP-Zugriffe im Prometheus-Format.
- Prometheus ist konfiguriert, um diese Metriken zu sammeln.
- Der Prometheus-Skalierer in KEDA ist so konfiguriert, dass er die Anwendung basierend auf der Anzahl der HTTP-Zugriffe automatisch skaliert.
Jetzt werde ich jedes Element im Detail erläutern.
KEDA und Prometheus
Prometheus ist ein Open-Source-Toolkit zur Überwachung und Benachrichtigung von Systemen, Teil . Er sammelt Metriken aus verschiedenen Quellen und speichert sie als Zeitreihendaten. Zur Visualisierung der Daten können oder andere Visualisierungstools verwendet werden, die mit der Kubernetes-API arbeiten.
KEDA unterstützt das Konzept des Skalierers - er fungiert als Brücke zwischen KEDA und dem externen System. Die Implementierung des Skalierers ist spezifisch für jedes Zielsystem und extrahiert Daten daraus. Anschließend verwendet KEDA diese Daten zur Verwaltung der automatischen Skalierung.
Skalierer unterstützen mehrere Datenquellen, wie z.B. Kafka, Redis, Prometheus. Das bedeutet, dass KEDA für das automatische Skalieren von Kubernetes-Deployments verwendet werden kann, wobei die Prometheus-Metriken als Kriterien dienen.
Testanwendung
Die Test-Golang-Anwendung bietet HTTP-Zugriff und erfüllt zwei wichtige Funktionen:
- Verwendet die Client-Bibliothek Prometheus Go zur Instrumentierung der Anwendung und zur Bereitstellung der Metrik http_requests, die einen Zugriffszähler enthält. Der Endpunkt, an dem die Prometheus-Metriken verfügbar sind, befindet sich unter der URI
/metrics.var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{ Name: "http_requests", Help: "Anzahl der HTTP-Anfragen", }) - Als Antwort auf die Anfrage
GETerhöht die Anwendung den Wert des Schlüssels (access_count) in Redis. Dies ist eine einfache Möglichkeit, die Arbeit als Teil des HTTP-Handlers auszuführen und die Prometheus-Metriken zu überprüfen. Der Wert der Metrik sollte gleich dem Wert seinaccess_countin Redis.func main() { http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { defer httpRequestsCounter.Inc() count, err := client.Incr(redisCounterName).Result() if err != nil { fmt.Println("Kann den Redis-Zähler nicht erhöhen", err) os.Exit(1) } resp := "Zugriff am " + time.Now().String() + "nZugriffsanzahl " + strconv.Itoa(int(count)) w.Write([]byte(resp)) }) http.ListenAndServe(":8080", nil) }
Die Anwendung wird in Kubernetes über Deploymentbereitgestellt. Es wird auch ein Dienst erstellt, ClusterIP, der dem Prometheus-Server ermöglicht, die Anwendungsmetriken zu erhalten.
Hier .
Prometheus-Server
Das Bereitstellungsmanifest für Prometheus besteht aus:
ConfigMap— zur Übermittlung der Prometheus-Konfiguration;Deployment— für die Bereitstellung von Prometheus im Kubernetes-Cluster;ClusterIP— Dienst für den Zugang zur Prometheus-UI;Clusterrolle,ClusterRoleBindingundServiceAccount— für die Auto-Discovery der Dienste in Kubernetes.
Hier .
KEDA Prometheus ScaledObject
Der Skalierer fungiert als Brücke zwischen KEDA und dem externen System, aus dem Metriken abgerufen werden müssen. ScaledObject — eine anpassbare Ressource, die bereitgestellt werden muss, um das Deployment mit der Ereignisquelle zu synchronisieren, in diesem Fall mit Prometheus.
ScaledObject enthält Informationen zur Skalierung des Deployments, Metadaten zur Ereignisquelle (z.B. Verbindungsgeheimnisse, Warteschlangenname), Abfrageintervall, Erholungszeitraum und andere Daten. Es führt zu der entsprechenden Autoskalierungsressource (Definition HPA) für das Skalieren des Deployments.
Wenn das Objekt ScaledObject wird gelöscht, das entsprechende HPA wird zurückgesetzt.
Hier ist die Definition ScaledObject für unser Beispiel, es wird ein Scaler verwendet Prometheus:
apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
name: prometheus-scaledobject
namespace: default
labels:
deploymentName: go-prom-app
spec:
scaleTargetRef:
deploymentName: go-prom-app
pollingInterval: 15
cooldownPeriod: 30
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: prometheus
metadata:
serverAddress:
http://prometheus-service.default.svc.cluster.local:9090
metricName: access_frequency
threshold: '3'
query: sum(rate(http_requests[2m]))
Beachten Sie die folgenden Punkte:
- Es verweist auf
Deploymentmit dem Namengo-prom-app. - Der Typ des Triggers ist
Prometheus. Die Adresse des Prometheus-Servers wird zusammen mit dem Metriknamen, dem Schwellenwert und , die verwendet wird. Die PromQL-Abfrage istsum(rate(http_requests[2m])). - Laut
pollingInterval, KEDA fragt das Ziel alle fünfzehn Sekunden bei Prometheus ab. Es wird mindestens ein Pod unterstützt (minReplicaCount), und die maximale Anzahl der Pods liegt beimaxReplicaCount(in diesem Beispiel zehn).
Es kann auf minReplicaCount null gesetzt werden. In diesem Fall aktiviert KEDA das Deployment von null auf eins und stellt dann HPA für die weitere Automatisierung bereit. Es ist auch möglich, in umgekehrter Reihenfolge zu skalieren, also von eins auf null. In unserem Beispiel haben wir null nicht gewählt, da es sich um einen HTTP-Dienst handelt und nicht um ein Abfragesystem.
Die Magie des automatischen Skalierens
Der Schwellenwert wird als Auslöser zum Skalieren des Deployments verwendet. In unserem Beispiel gibt die PromQL-Abfrage sum(rate(http_requests[2m])) einen aggregierten Wert der Rate von HTTP-Anfragen (Anzahl der Anfragen pro Sekunde) zurück, die in den letzten zwei Minuten gemessen wurde.
Da der Schwellenwert drei beträgt, wird es einen Pod geben, solange der Wert sum(rate(http_requests[2m])) weniger als drei ist. Wenn der Wert jedoch steigt, wird jedes Mal ein zusätzlicher Pod hinzugefügt, wenn sum(rate(http_requests[2m])) er um drei ansteigt. Zum Beispiel, wenn der Wert von 12 auf 14 steigt, beträgt die Anzahl der Pods vier.
Lassen Sie uns jetzt versuchen, es einzurichten!
Vorbereitende Konfiguration
Alles, was Sie brauchen, ist ein Kubernetes-Cluster und ein eingerichtetes Tool kubectl. In diesem Beispiel wird ein Cluster verwendet minikube, aber Sie können jeden anderen verwenden. Für den Clusteraufbau gibt es .
Installieren Sie die neueste Version auf Mac:
curl -Lo minikube
https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
&& chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/
Installieren Sie , um Zugriff auf den Kubernetes-Cluster zu erhalten.
Neueste Version auf Mac installieren:
curl -LO
"https://storage.googleapis.com/kubernetes-release/release/$(curl -s
https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubectl version
KEDA-Installation
Sie können KEDA auf mehrere Arten bereitstellen, die im aufgelistet sind. Ich verwende ein monolithisches YAML:
kubectl apply -f
https://raw.githubusercontent.com/kedacore/keda/master/deploy/KedaScaleController.yaml
KEDA und ihre Komponenten werden im Namensraum kedainstalliert. Der Befehl zur Überprüfung:
kubectl get pods -n keda
Warten Sie, bis der KEDA-Operator-Pod startet — in den Running Stateübergeht. Und fahren Sie dann fort.
Installation von Redis mit Helm
Wenn Sie Helm nicht installiert haben, verwenden Sie dieses Befehl zur Installation auf Mac:
brew install kubernetes-helm
helm init --history-max 200
helm init initialisiert die lokale Befehlszeilenoberfläche und installiert auch Tiller im Kubernetes-Cluster.
kubectl get pods -n kube-system | grep tiller
Warten Sie, bis der Tiller-Pod in den Zustand Running übergeht.
Hinweis des Übersetzers: Der Autor verwendet Helm@2, das die Installation der Serverkomponente Tiller erfordert. Aktuell ist Helm@3, für den kein Serverteil benötigt wird.
Nach der Installation von Helm reicht ein Befehl aus, um Redis zu starten:
helm install --name redis-server --set cluster.enabled=false --set
usePassword=false stable/redis
Stellen Sie sicher, dass Redis erfolgreich gestartet wurde:
kubectl get pods/redis-server-master-0
Warten Sie, bis der Redis-Pod in den Zustand Laufend.
Anwendungsbereitstellung
Befehl zur Bereitstellung:
kubectl apply -f go-app.yaml
//output
deployment.apps/go-prom-app created
service/go-prom-app-service created
Überprüfen Sie, dass alles gestartet wurde:
kubectl get pods -l=app=go-prom-app
Warten Sie, bis Redis in den Zustand Laufend.
Bereitstellung des Prometheus-Servers
Das Manifest von Prometheus verwendet . Es ermöglicht das dynamische Entdecken von Anwendungs-Pods basierend auf dem Servicelabel.
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_run]
regex: go-prom-app-service
action: keep
Für die Bereitstellung:
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
Überprüfen Sie, dass alles gestartet wurde:
kubectl get pods -l=app=prometheus-server
Warten Sie, bis der Prometheus-Pod in den Zustand Laufend.
Verwenden Sie kubectl port-forward zum Zugriff auf die Benutzeroberfläche von Prometheus (oder den API-Server) unter .
kubectl port-forward service/prometheus-service 9090
Bereitstellung der KEDA-Autoskalierungs-Konfiguration
Befehl zur Erstellung ScaledObject:
kubectl apply -f keda-prometheus-scaledobject.yaml
Überprüfen Sie die Protokolle des KEDA-Operators:
KEDA_POD_NAME=$(kubectl get pods -n keda
-o=jsonpath='{.items[0].metadata.name}')
kubectl logs $KEDA_POD_NAME -n keda
Das Ergebnis sieht ungefähr so aus:
time="2019-10-15T09:38:28Z" level=info msg="Skalierungsobjekt beobachten:
default/prometheus-scaledobject"
time="2019-10-15T09:38:28Z" level=info msg="HPA mit
Namespace default und Name keda-hpa-go-prom-app erstellt"
Überprüfen Sie die Anwendung Pods. Es sollte ein Exemplar laufen, da minReplicaCount es gleich 1 ist:
kubectl get pods -l=app=go-prom-app
Überprüfen Sie, ob der HPA-Ressource erfolgreich erstellt wurde:
kubectl get hpa
Sie sollten etwas sehen wie:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-go-prom-app Deployment/go-prom-app 0/3 (avg) 1 10 1 45s
Überprüfung der Funktionsfähigkeit: Zugriff auf die Anwendung
Um auf den REST-Endpunkt unserer Anwendung zuzugreifen, führen Sie aus:
kubectl port-forward service/go-prom-app-service 8080
Jetzt können Sie auf die Go-Anwendung unter der Adresse zugreifen . Führen Sie dazu den Befehl aus:
curl http://localhost:8080/test
Das Ergebnis sieht ungefähr so aus:
Zugriff am 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Zugriffsanzahl 1
Überprüfen Sie zu diesem Zeitpunkt auch Redis. Sie werden sehen, dass der Schlüssel access_count auf 1 erhöht wurde:
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Stellen Sie sicher, dass der Wert der Metrik http_requests derselbe ist:
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests Anzahl der HTTP-Anfragen
# TYPE http_requests counter
http_requests 1
Lastenüberprüfung
Wir werden — ein Tool zur Lastgenerierung:
curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64
&& chmod a+x hey
Sie können auch das Tool für oder .
Führen Sie es aus:
./hey http://localhost:8080/test
Standardmäßig sendet das Tool 200 Anfragen. Sie können dies über die Prometheus-Metriken und Redis überprüfen.
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests Anzahl der HTTP-Anfragen
# TYPE http_requests counter
http_requests 201
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
201
Bestätigen Sie den Wert der tatsächlichen Metrik (zurückgegeben durch die PromQL-Abfrage):
curl -g
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
//output
{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1571734214.228,"1.686057971014493"]}]}}
In diesem Fall beträgt das tatsächliche Ergebnis 1,686057971014493 und wird im Feld angezeigt value. Das reicht nicht aus, um zu skalieren, da unser gesetzter Schwellenwert 3 beträgt.
Mehr Last!
Überwachen Sie in einem neuen Terminal die Anzahl der Anwendung Pods:
kubectl get pods -l=app=go-prom-app -w
Lassen Sie uns die Last mit folgendem Befehl erhöhen:
./hey -n 2000 http://localhost:8080/test
Nach einer gewissen Zeit werden Sie sehen, dass der HPA das Deployment skaliert und neue Pods startet. Überprüfen Sie den HPA, um dies zu bestätigen:
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
Wenn die Last unregelmäßig ist, wird das Deployment auf den Punkt verringert, an dem nur ein Pod läuft. Wenn Sie die tatsächliche Metrik (die von PromQL zurückgegeben wird) überprüfen möchten, verwenden Sie den Befehl:
curl -g
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
Bereinigung
//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
Fazit
KEDA ermöglicht das automatische Skalieren Ihrer Kubernetes-Deployments (bis/ab null) basierend auf Daten von externen Metriken. Beispielsweise basierend auf Prometheus-Metriken, der Länge der Warteschlange in Redis, der Latenz des Verbrauchers in einem Kafka-Thema.
KEDA integriert sich mit einer externen Quelle und stellt deren Metriken über den Metrics Server für den Horizontal Pod Autoscaler bereit.
Viel Erfolg!
Was Sie sonst noch lesen sollten:
- .
- .
- .
Quelle: habr.com
