Autoscaler in Kubernetes nutzen

HPA - Horizontal Pod Autoscaler

Für Kubernetes Cluster ist es vom Vorteil im Bedarfsfall die Gesamtzahl laufender Pods automatisch erhöhen zu lassen. Dies ist vorzugsweise dann zu tun, wenn die CPU Auslastung wächst und so ein Pod für die weitere Nutzung "dicht" wird. Neu gestartete Pods sollen dann Abhilfe schaffen und die Reaktionsgeschwindigkeit des Clusters aufrechterhalten.

Voraussetzungen für die Nutzung des Horizontal Pod Autoscaler (HPA)

  • Gewählter Objekttyp erzeugt ein ReplicaSet: Typ Deployment oder Replication Controller
  • Ressourcenlimit für die CPU Nutzung ist im Objekt gesetzt.

Die Lösung sieht also nicht nur vor, dass Instanzen auf weniger befahrenen Nodes gestartet werden, sondern auch neue Instanzen auf denselben Nodes genutzt werden, welche die verfügbare CPU Leistung auf weitere Pods aufteilt. Der Algorithmus der als Grundlage zur Bedarfsermittlung dient, ist in Kubernetes bereits fest integriert. Ein spezifischer Trigger kann ersatzweise auch auf Basis eines metrics-servers laufen und so weitere Abhängigkeiten einfließen lassen.

HAP Pod Schema

Als Beispiel wird ein Deployment als Datei nginx-deployment.yaml verwendet:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-group
 labels:
   app: nginx
spec:
 replicas: 1
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.14
       ports:
       - containerPort: 80
       resources:
         limits:
           memory: 512Mi
           cpu: 200m
         requests:
           cpu: 100m

Der Inhalt kann mit kubectl im Cluster erzeugt werden.

kubectl create -f nginx-deployment.yaml

Dies generiert ein Objekt vom Typ Deployment, Replicaset und 1 Pods. Das Replicaset hält die gewünschte Anzahl von Pods zunächst stabil. Um die Pods nun automatisch skalieren zu lassen muss ein HPA Objekt (Horizontal Pod Autoscaler) gestartet werden.

Autoscaler erstellen

Für das Deployment mit dem Namen nginx-group wird eingestellt, dass zwischen 1 und 10 Pods skaliert wird. Abhängig gemacht wird die Entscheidung von der CPU Auslastung, hier auf 20% gesetzt. Wichtig: Die Entscheidung des bei welchem Wert weitere Pods gestartet oder bestehende gelöscht werden muss bereits beim Erstellen des Deployments fallen, nicht erst bei der Erstellung des HPAs. Denn am sinnvollsten ist es den dem HPA übergebenen Wert bereits im Deploment als Limit zu definieren, um die Kalkulierbarkeit gradlinig zu machen. Hier entsprechen 200m dem Wert 20%.

kubectl autoscale deployment nginx-group --cpu-percent=20 --min=1 --max=10

Zum Testen kann Load auf dem Pod generiert werden. Hierfür ist die individuelle Bezeichnung des Pods wichtig. Im aktuellen Testfall war sie nginx-group-7997458685-gm7p9.

kubectl exec -it nginx-group-7997458685-n5qhh -- cat /dev/urandom > /dev/null

Der Befehl "kubectl get hpa" würde die aktuelle Situation der Skalierung wiedergeben. Soll die Änderung auch zeitlich noch nachvollzogen werden können, eignet sich ein describe Aufruf besser, wie gleich verwendet.

Zum kurzzeitigen Überwachen der Funktionalität sorgen jeweils in einem Terminal eingegeben diese Zeilen.

watch -n 1 kubectl top pod nginx-group-7997458685-gm7p9
watch -n 1 kubectl describe hpa nginx-group
watch -n 1 kubectl get pods

Info: Für die Nutzung von "top" muss ein metrics-server im Kubernetes Cluster laufen. Durch die Nutzung von Projekten wie Prometheus wird dieser ohnehin gestartet. Bei Minikube kann er mit dieser Zeile nachträglich aktiviert werden:

minikube addons enable metrics-server

Standardmäßig wird eine Messung vom HPA alle 15 Sekunden vorgenommen. Zur Anpassung kann der Wert per Parameter beim Erstellen überschrieben werden:
--horizontal-pod-autoscaler-sync-period

Was ist aber, wenn die Anzahl des Replicasets im Deployment bereits beim Start auf z.B. 3 festgelegt wurde? Dies ist auch kein Problem, da ohne Last nach einiger Zeit ebenfalls auf die Gesamtzahl 1 herunter skaliert werden kann und der Bereich zwischen 1 bis 10 so eingehalten wird. Fürs Testen ist der Startwert von 1 jedoch am besten geeignet, da zufällig genau der Pod der Skalierung zum Opfer fallen könnte, auf dem die Testload gerade erst gestartet wurde. Im produktiven Betrieb ist ein passender Startwert wiederum sinnvoll. Beobachtet werden kann, dass der Algorithmus vom HPA bewusst schnell auf hohe Änderungen und eher träge auf kleinere Änderungen reagiert. So kann das Regelverhalten für den beim Start fehlenden CPU Verlauf z.B. durch die Parameter --horizontal-pod-autoscaler-initial-readiness-delay (standardmäßig 30 Sekunden) und --horizontal-pod-autoscaler-cpu-initialization-period (standardmäßig 5 Minuten) angepasst werden. Alles in Allem ist beim Einsatz von HPA etwas Planung wichtig, um auch die skalierbaren Komponenten mit den Limits zu versehen. Dann aber ist der Einsatz sehr lohnenswert.

Timo Hohmann - Serveradministrator



 

Viel Spaß beim ausprobieren.
Euer Timo. 

siehe auch:
Managed Kubernetes
Kubernetes Schulungen

Wenn ihr Fragen habt, meldet euch: info@mobilistics.de

Im Blog oder auf unserer Homepage könnt ihr gerne schauen, was wir sonst noch so machen.