
Skalierbarkeit ist eine wichtige Voraussetzung für Cloud-Anwendungen. Mit Kubernetes ist das Skalieren einer Anwendung so einfach wie das Erhöhen der Anzahl von Replikaten für eine geeignete Bereitstellung oder
ReplicaSet- aber es ist ein manueller Prozess.
Mit Kubernetes können Anwendungen
ReplicaSetmithilfe der Horizontal Pod Autoscaler-Spezifikation deklarativautomatisch skaliert werden (d. H. Pods in Bereitstellung oder). Das Standardkriterium für die automatische Skalierung sind CPU-Auslastungsmetriken (Ressourcenmetriken). Benutzerdefinierte Metriken und extern bereitgestellte Metriken können jedoch integriert werden. Kubernetes aaS
Team von Mail.ruübersetzte einen Artikel über die Verwendung externer Metriken zum automatischen Skalieren einer Kubernetes-Anwendung. Um zu zeigen, wie alles funktioniert, verwendet der Autor HTTP-Zugriffsanforderungsmetriken, die mit Prometheus erfasst werden.
Kubernetes Event Driven Autoscaling (KEDA) ist ein Open-Source-Kubernetes-Operator, anstatt horizontal Pods automatisch zu skalieren. Es lässt sich nativ in den Horizontal Pod Autoscaler integrieren, um eine reibungslose automatische Skalierung (einschließlich von / nach Null) für ereignisgesteuerte Workloads zu ermöglichen. Der Code ist auf GitHub verfügbar .
Kurzbeschreibung des Systembetriebs
Das Diagramm zeigt eine kurze Beschreibung, wie alles funktioniert:
- Die Anwendung bietet Metriken für die Anzahl der HTTP-Anforderungen im Prometheus-Format.
- Prometheus soll diese Metriken sammeln.
- Der Prometheus-Skalierer in KEDA ist so konfiguriert, dass die Anwendung automatisch basierend auf der Anzahl der HTTP-Anforderungen skaliert wird.
Jetzt werde ich Ihnen detailliert über jedes Element berichten.
KEDA und Prometheus
Prometheus ist ein Open-Source-Toolkit zur Systemüberwachung und -warnung, das Teil der Cloud Native Computing Foundation ist . Sammelt Metriken aus verschiedenen Quellen und speichert sie als Zeitreihendaten. Zur Visualisierung von Daten können Sie Grafana oder andere Visualisierungstools verwenden, die mit der Kubernetes-API arbeiten.
KEDA unterstützt das Scaler-Konzept - es fungiert als Brücke zwischen KEDA und dem externen System. Die Scaler-Implementierung ist für jedes Zielsystem spezifisch und extrahiert Daten daraus. KEDA verwendet sie dann zur Steuerung der automatischen Skalierung.
Skalierer unterstützen mehrere Datenquellen wie Kafka, Redis, Prometheus. Das heißt, KEDA kann verwendet werden, um Kubernetes-Bereitstellungen automatisch anhand von Prometheus-Metriken als Kriterien zu skalieren.
Anwendung testen
Die Golang-Testanwendung bietet HTTP-Zugriff und erfüllt zwei wichtige Funktionen:
- Verwendet die Prometheus Go-Clientbibliothek, um die Anwendung zu instrumentieren und die Metrik http_requests bereitzustellen, die einen Trefferzähler enthält. Der Endpunkt, an dem Prometheus-Metriken verfügbar sind, befindet sich nach URI
/metrics.
var httpRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{ Name: "http_requests", Help: "number of http requests", }) - Als Antwort auf die Anforderung
GETerhöht die Anwendung den Wert key (access_count) in Redis. Dies ist eine einfache Möglichkeit, die Aufgabe als Teil eines HTTP-Handlers zu erledigen und Prometheus-Metriken zu überprüfen. Der Metrikwert muss mit dem Wertaccess_countin Redis übereinstimmen .
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("Unable to increment redis counter", err) os.Exit(1) } resp := "Accessed on " + time.Now().String() + "\nAccess count " + strconv.Itoa(int(count)) w.Write([]byte(resp)) }) http.ListenAndServe(":8080", nil) }
Die App wird über über Kubernetes bereitgestellt
Deployment. Außerdem wird ein Dienst erstellt ClusterIP, mit dem der Prometheus-Server Anwendungsmetriken empfangen kann.
Hier ist das Bereitstellungsmanifest für die Anwendung .
Prometheus Server
Das Prometheus-Bereitstellungsmanifest besteht aus:
ConfigMap- um die Prometheus-Konfiguration zu übertragen;Deployment- für die Bereitstellung von Prometheus in einem Kubernetes-Cluster;ClusterIP- Dienst für den Zugriff auf UI Prometheus;ClusterRole,ClusterRoleBindingUndServiceAccount- für die automatische Erkennung von Diensten in Kubernetes (Auto-Discovery).
Hier ist das Manifest zum Ausführen von Prometheus .
KEDA Prometheus ScaledObject
Der Skalierer fungiert als Brücke zwischen KEDA und dem externen System, von dem aus die Metriken abgerufen werden.
ScaledObjectIst eine benutzerdefinierte Ressource, muss sie bereitgestellt werden, um die Bereitstellung mit der Ereignisquelle zu synchronisieren, in diesem Fall Prometheus.
ScaledObjectEnthält Informationen zur Skalierung der Bereitstellung, Metadaten der Ereignisquelle (z. B. Verbindungsgeheimnisse, Warteschlangenname), Abfrageintervall, Wiederherstellungszeitraum und andere Informationen. Daraus ergibt sich die entsprechende Ressource für die automatische Skalierung (HPA-Definition) zur Skalierung der Bereitstellung.
Wenn ein Objekt
ScaledObjectgelöscht wird, wird die entsprechende HPA-Definition gelöscht.
Hier ist die Definition
ScaledObjectfür unser Beispiel, es verwendet einen Skalierer 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:
- Er zeigt
Deploymentmit einem Namen daraufgo-prom-app. - Auslösertyp -
Prometheus. Die Prometheus-Serveradresse wird zusammen mit dem Metriknamen , dem Schwellenwert und der zu verwendenden PromQL-Anforderung angegeben . PromQL-Anfrage -sum(rate(http_requests[2m])). - Laut
pollingIntervalKEDA fordert Prometheus alle fünfzehn Sekunden ein Ziel an. Es wird mindestens ein Pod (minReplicaCount) unterstützt , und die maximale Anzahl von Pods wird nicht überschrittenmaxReplicaCount(in diesem Beispiel zehn).
Kann
minReplicaCountauf Null gesetzt werden. In diesem Fall aktiviert KEDA die Null-zu-Eins-Bereitstellung und stellt dann HPA für die weitere automatische Skalierung bereit. Die umgekehrte Reihenfolge ist auch möglich, dh eine Skalierung von eins auf null. Im Beispiel haben wir nicht Null ausgewählt, da dies ein HTTP-Dienst und kein System on Demand ist.
Die Magie in der automatischen Skalierung
Der Schwellenwert wird als Auslöser zum Skalieren der Bereitstellung verwendet. In unserem Beispiel gibt die PromQL-Abfrage
sum(rate (http_requests [2m]))den aggregierten Wert der HTTP-Anforderungsrate (Anforderungen pro Sekunde) zurück, der in den letzten zwei Minuten gemessen wurde.
Da der Schwellenwert drei ist, gibt es einen unter, solange der Wert
sum(rate (http_requests [2m]))kleiner als drei ist. Wenn sich der Wert erhöht, wird jedes Mal, wenn er sum(rate (http_requests [2m]))um drei erhöht wird, ein zusätzliches Unter hinzugefügt . Wenn der Wert beispielsweise zwischen 12 und 14 liegt, beträgt die Anzahl der Pods vier.
Versuchen wir nun zu konfigurieren!
Voreinstellung
Sie benötigen lediglich einen Kubernetes-Cluster und ein benutzerdefiniertes Dienstprogramm
kubectl. In diesem Beispiel wird ein Cluster verwendet minikube, Sie können jedoch auch einen anderen verwenden. Es gibt eine Anleitung zur Installation des Clusters .
Installieren Sie die neueste Version auf dem 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 kubectl, um auf Ihren Kubernetes-Cluster zuzugreifen.
Installieren Sie die neueste Version auf dem Mac:
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 installieren
Sie können KEDA auf verschiedene Arten bereitstellen. Diese sind in der Dokumentation aufgeführt . Ich benutze monolithische YAML:
kubectl apply -f
https://raw.githubusercontent.com/kedacore/keda/master/deploy/KedaScaleController.yaml
KEDA und seine Komponenten werden im Namespace installiert
keda. Zu überprüfender Befehl:
kubectl get pods -n keda
Warten Sie, wenn unter KEDA Operator startet - geht zu
Running State. Und dann weiter.
Redis mit Helm installieren
Wenn Sie Helm nicht installiert haben, verwenden Sie dieses Tutorial . Befehl zur Installation auf dem Mac:
brew install kubernetes-helm
helm init --history-max 200
helm initInitialisiert die lokale CLI und wird auch Tillerim Kubernetes-Cluster installiert .
kubectl get pods -n kube-system | grep tiller
Warten Sie, bis der Pinnen-Pod in den Betriebszustand wechselt.
Anmerkung des Übersetzers : Der Autor verwendet Helm @ 2, für das die Tiller-Serverkomponente installiert sein muss. Helm @ 3 ist derzeit relevant, es wird kein Serverteil benötigt.
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
Überprüfen Sie, ob Redis erfolgreich gestartet wurde:
kubectl get pods/redis-server-master-0
Warten Sie, bis unter Redis der Status aktiviert ist
Running.
Stellen Sie die Anwendung bereit
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, ob alles gestartet ist:
kubectl get pods -l=app=go-prom-app
Warten Sie, bis Redis in den Status übergeht
Running.
Bereitstellen von Prometheus Server
Das Prometheus-Manifest verwendet Kubernetes Service Discovery für Prometheus . Sie können damit Anwendungs-Pods basierend auf einem Service-Label dynamisch erkennen.
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, ob alles gestartet ist:
kubectl get pods -l=app=prometheus-server
Warten Sie, bis unter Prometheus der Zustand erreicht ist
Running.
Verwenden Sie
kubectl port-forwarddiese Option, um auf die Prometheus-Benutzeroberfläche (oder den API-Server) unter http: // localhost: 9090 zuzugreifen .
kubectl port-forward service/prometheus-service 9090
Bereitstellen der KEDA-Autoscaling-Konfiguration
Befehl zum Erstellen
ScaledObject:
kubectl apply -f keda-prometheus-scaledobject.yaml
Überprüfen Sie die Protokolle des KEDA-Betreibers:
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="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"
Überprüfen Sie unter Anwendungen. Eine Instanz sollte ausgeführt werden, da es
minReplicaCount1 ist:
kubectl get pods -l=app=go-prom-app
Stellen Sie sicher, dass die 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
Integritätsprüfung: Zugriff auf die Anwendung
Führen Sie Folgendes aus, um auf den REST-Endpunkt unserer Anwendung zuzugreifen:
kubectl port-forward service/go-prom-app-service 8080
Sie können jetzt über die Adresse http: // localhost: 8080 auf die Go-App zugreifen . Führen Sie dazu den folgenden Befehl aus:
curl http://localhost:8080/test
Das Ergebnis sieht ungefähr so aus:
Accessed on 2019-10-21 11:29:10.560385986 +0000 UTC
m=+406004.817901246
Access count 1
Schauen Sie sich an dieser Stelle auch Redis an. Sie werden sehen, dass der Schlüssel
access_countauf 1 erhöht wird:
kubectl exec -it redis-server-master-0 -- redis-cli get access_count
//output
"1"
Stellen Sie sicher, dass der Metrikwert gleich
http_requestsist:
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# TYPE http_requests counter
http_requests 1
Ladeerstellung
Wir werden hey verwenden , ein Dienstprogramm, um die Last zu erzeugen:
curl -o hey https://storage.googleapis.com/hey-release/hey_darwin_amd64
&& chmod a+x hey
Sie können das Dienstprogramm auch für Linux oder Windows herunterladen .
Starte es:
./hey http://localhost:8080/test
Standardmäßig sendet das Dienstprogramm 200 Anforderungen. Sie können dies sowohl mit Prometheus-Metriken als auch mit Redis überprüfen.
curl http://localhost:8080/metrics | grep http_requests
//output
# HELP http_requests number of http requests
# 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 tatsächlichen Metrikwert (von der PromQL-Abfrage zurückgegeben):
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 ist das tatsächliche Ergebnis gleich
1,686057971014493und wird im Feld angezeigt value. Dies reicht für die Skalierung nicht aus, da der von uns festgelegte Schwellenwert 3 ist.
Mehr Ladung!
Verfolgen Sie im neuen Terminal die Anzahl der Anwendungs-Pods:
kubectl get pods -l=app=go-prom-app -w
Erhöhen wir die Last mit dem Befehl:
./hey -n 2000 http://localhost:8080/test
Nach einer Weile wird HPA die Bereitstellung skalieren und neue Pods starten. Überprüfen Sie die HPA, um sicherzustellen, dass:
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 nicht konstant ist, wird die Bereitstellung so weit reduziert, dass nur noch ein Pod funktioniert. Wenn Sie die tatsächliche Metrik überprüfen möchten (von der PromQL-Abfrage zurückgegeben), verwenden Sie den folgenden Befehl:
curl -g
'http://localhost:9090/api/v1/query?query=sum(rate(http_requests[2m]))'
Reinigung
//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
Mit KEDA können Sie Ihre Kubernetes-Bereitstellungen automatisch (auf / von Null) basierend auf Daten aus externen Metriken skalieren. Zum Beispiel basierend auf Prometheus-Metriken, Warteschlangenlänge in Redis, Verbraucherlatenz im Kafka-Thema.
KEDA lässt sich in eine externe Quelle integrieren und stellt über den Metrics Server auch Metriken für den Horizontal Pod Autoscaler bereit.
Viel Glück!
Was noch zu lesen: