Ich habe Kube Eagle erstellt – einen Prometheus-Exporter. Es stellte sich als beeindruckendes Werkzeug heraus, das hilft, die Ressourcen kleiner und mittlerer Cluster besser zu verstehen. Am Ende habe ich mehrere Hundert Dollar gespart, weil ich die richtigen Maschinentypen ausgewählt und die Ressourcenlimits der Anwendungen an die Arbeitslasten angepasst habe.
Ich werde über die Vorteile sprechen , aber zuerst erkläre ich, warum es zu Problemen kam und warum eine qualitativ hochwertige Überwachung erforderlich war.
Ich habe mehrere Cluster mit 4–50 Knoten verwaltet. In jedem Cluster gab es bis zu 200 Mikrodienste und Anwendungen. Um die vorhandene Hardware effizienter zu nutzen, waren die meisten Deployments mit burstable RAM und CPU-Ressourcen konfiguriert. So können Pods verfügbare Ressourcen nutzen, wenn nötig, ohne die anderen Anwendungen auf diesem Knoten zu stören. Ist das nicht großartig?
Und obwohl der Cluster relativ wenig CPU (8%) und RAM (40%) verbrauchte, hatten wir ständig Probleme mit dem Abdrängen von Pods, wenn sie mehr Speicher anforderten, als auf dem Knoten verfügbar war. Damals hatten wir nur ein Dashboard zur Überwachung der Kubernetes-Ressourcen. So sah es aus:
Grafana-Dashboard nur mit cAdvisor-Metriken
Mit einem solchen Dashboard ist es kein Problem, Knoten zu sehen, die viel Speicher und CPU verbrauchen. Das Problem ist, die Ursache zu verstehen. Um die Pods am Platz zu halten, hätte man natürlich garantierte Ressourcen für alle Pods einrichten können (die angeforderten Ressourcen entsprechen dem Limit). Aber das ist nicht die intelligenteste Nutzung der Hardware. Der Cluster hatte mehrere hundert Gigabyte RAM, während einige Knoten kaum Ressourcen hatten und andere noch 4–10 GB übrig hatten.
Es stellte sich heraus, dass der Kubernetes-Scheduler die Arbeitslasten ungleichmäßig auf die verfügbaren Ressourcen verteilte. Der Kubernetes-Scheduler berücksichtigt verschiedene Konfigurationen: Affinitätsregeln, Taints und Toleranzen, Knoten-Selectoren, die den Zugang zu den verfügbaren Knoten einschränken können. Aber in meinem Fall gab es nichts dergleichen, und die Pods wurden je nach den angeforderten Ressourcen auf jedem Knoten geplant.
Für einen Pod wurde ein Knoten ausgewählt, der die meisten freien Ressourcen hatte und die Anforderungen erfüllte. Wir erhielten, dass die angeforderten Ressourcen auf den Knoten nicht mit der tatsächlichen Nutzung übereinstimmten, und hier kam Kube Eagle mit seinen Monitoring-Möglichkeiten ins Spiel.
Jedoch wurden fast alle meine Kubernetes-Cluster nur mit und . Node Exporter liefert Statistiken über Ein- und Ausgaben sowie die Nutzung von Festplatte, CPU und Arbeitsspeicher, während Kube State Metrics Metriken von Kubernetes-Objekten anzeigt, wie zum Beispiel CPU- und Arbeitsspeicheranforderungen und -limits.
Wir müssen die Nutzungsmetriken mit den Metriken für Anforderungen und Limits in Grafana kombinieren, um alle Informationen über das Problem zu erhalten. Das klingt einfach, aber in diesen beiden Tools werden die Labels unterschiedlich bezeichnet, und einige Metriken haben überhaupt keine Metadaten-Labels. Kube Eagle erledigt das alles automatisch, und das Dashboard sieht so aus:
Wir konnten viele Probleme mit Ressourcen lösen und die Hardware schonen:
- Einige Entwickler wussten nicht, wie viele Ressourcen ihre Mikrodienste benötigten (oder waren einfach nicht daran interessiert). Uns fehlten die Mittel, um falsche Ressourcenanforderungen zu finden – dafür benötigt man die Verbrauchswerte sowie die Anforderungen und Limits. Jetzt sehen sie die Prometheus-Metriken, überwachen die tatsächliche Nutzung und passen die Anforderungen und Limits an.
- JVM-Anwendungen nutzen so viel Arbeitsspeicher, wie sie können. Der Garbage Collector gibt Speicher nur dann frei, wenn mehr als 75 % belegt sind. Da der Arbeitsspeicher der meisten Dienste burstable ist, wurde er immer vom JVM belegt. Daher benötigten all diese Java-Dienste viel mehr Arbeitsspeicher als erwartet.
- Einige Anwendungen forderten zu viel Arbeitsspeicher an, und der Kubernetes-Scheduler gab diese Nodes nicht an andere Anwendungen weiter, obwohl sie tatsächlich freier waren als andere Nodes. Ein Entwickler hatte versehentlich eine zusätzliche Ziffer in der Anforderung hinzugefügt und damit einen großen Teil des Arbeitsspeichers belegt: 20 GB statt 2. Niemand bemerkte es. Die Anwendung hatte 3 Replikate, sodass gleich 3 Nodes betroffen waren.
- Wir haben Ressourcenlimits eingeführt, die Pods mit den richtigen Anforderungen umgeplant und einen idealen Nutzungsausgleich über alle Nodes erhalten. Einige Nodes hätten sogar komplett abgeschaltet werden können. Dann stellten wir fest, dass wir die falschen Maschinen (auf CPU optimiert, nicht auf Arbeitsspeicher) hatten. Wir haben den Typ geändert und noch mehrere Nodes entfernt.
Ergebnisse
Mit burstable Ressourcen im Cluster nutzt man die vorhandene Hardware effektiver, aber der Kubernetes-Scheduler plant Pods basierend auf den Ressourcenanforderungen, was problematisch sein kann. Um zwei Fliegen mit einer Klappe zu schlagen: Probleme zu vermeiden und Ressourcen vollständig zu nutzen, benötigt man ein gutes Monitoring. Dazu ist es hilfreich. (Exporter Prometheus und Dashboard Grafana).
Quelle: habr.com
