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.
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.
Wenn ihr Fragen habt, meldet euch: info@mobilistics.de