Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Berechnung und Autoscaling
Als Entwickler erstellen Sie Schätzungen zu den Ressourcenanforderungen Ihrer Anwendung, z. B. CPU und Arbeitsspeicher. Wenn Sie sie jedoch nicht ständig anpassen, können sie veraltet sein, was Ihre Kosten erhöhen und Leistung und Zuverlässigkeit verschlechtern könnte. Es ist wichtiger, die Ressourcenanforderungen einer Anwendung kontinuierlich anzupassen, als sie gleich beim ersten Mal richtig zu machen.
Die unten genannten Best Practices helfen Ihnen beim Aufbau und Betrieb kostenbewusster Workloads, mit denen Sie Geschäftsergebnisse erzielen und gleichzeitig die Kosten minimieren und Ihrem Unternehmen eine maximale Investitionsrendite ermöglichen. Für die Optimierung Ihrer Cluster-Rechenkosten sind folgende Punkte von großer Bedeutung:
-
Workloads in der richtigen Größe
-
Reduzieren Sie ungenutzte Kapazitäten
-
Optimieren Sie Rechenkapazitätstypen (z. B. Spot) und Beschleuniger (z. B. GPUs)
Passen Sie die Größe Ihrer Workloads an
In den meisten EKS-Clustern entfällt der Großteil der Kosten auf die EC2 Instances, die zur Ausführung Ihrer containerisierten Workloads verwendet werden. Sie werden nicht in der Lage sein, Ihre Rechenressourcen richtig zu dimensionieren, ohne Ihre Workload-Anforderungen zu verstehen. Aus diesem Grund ist es wichtig, dass Sie die entsprechenden Anfragen und Grenzwerte verwenden und diese Einstellungen bei Bedarf anpassen. Darüber hinaus können Abhängigkeiten wie Instanzgröße und Speicherauswahl die Workload-Leistung beeinträchtigen, was eine Vielzahl unbeabsichtigter Folgen auf Kosten und Zuverlässigkeit haben kann.
Anfragen sollten sich an der tatsächlichen Nutzung orientieren. Wenn die Anfragen eines Containers zu hoch sind, bleibt ungenutzte Kapazität übrig, was einen großen Faktor bei den Gesamtkosten des Clusters ausmacht. Für jeden Container in einem Pod, z. B. für Anwendung und Sidecars, sollten eigene Anfragen und Grenzwerte festgelegt werden, um sicherzustellen, dass die aggregierten Pod-Grenzwerte so genau wie möglich sind.
Verwenden Sie Tools wie Goldilocks
Wir empfehlen, den Horizontal Pod Autoscaler (HPA) zu verwenden, um zu steuern, wie viele Replikate Ihrer Anwendung ausgeführt werden sollen, den Vertical Pod Autoscaler (VPA), um anzupassen, wie viele Anfragen und Beschränkungen Ihre Anwendung pro Replikat benötigt, und einen Node-Autoscaler wie Karpenter
Der Vertical Pod Autoscaler kann die Anforderungen und Grenzwerte, die Containern zugewiesen sind, anpassen, sodass Workloads optimal ausgeführt werden. Sie sollten den VPA im Überwachungsmodus ausführen, damit er nicht automatisch Änderungen vornimmt, und Ihre Pods neu starten. Es schlägt Änderungen vor, die auf beobachteten Messwerten basieren. Bei allen Änderungen, die sich auf Produktionsworkloads auswirken, sollten Sie diese Änderungen zunächst in einer Umgebung außerhalb der Produktionsumgebung überprüfen und testen, da sie sich auf die Zuverlässigkeit und Leistung Ihrer Anwendung auswirken können.
Reduzieren Sie den Verbrauch
Der beste Weg, Geld zu sparen, besteht darin, weniger Ressourcen bereitzustellen. Eine Möglichkeit, dies zu tun, besteht darin, die Workloads an ihre aktuellen Anforderungen anzupassen. Sie sollten alle Bemühungen zur Kostenoptimierung damit beginnen, sicherzustellen, dass Ihre Workloads ihre Anforderungen definieren und dynamisch skalieren. Dazu müssen Sie Metriken aus Ihren Anwendungen abrufen und Konfigurationen wie PodDisruptionBudgets
Der Horizontal Pod Autoscaler ist ein flexibler Workload-Autoscaler, mit dem Sie anpassen können, wie viele Replikate benötigt werden, um die Leistungs- und Zuverlässigkeitsanforderungen Ihrer Anwendung zu erfüllen. Er verfügt über ein flexibles Modell, mit dem anhand verschiedener Messwerte wie CPU, Arbeitsspeicher oder benutzerdefinierter Messwerte wie Warteschlangentiefe, Anzahl der Verbindungen zu einem Pod usw. festgelegt werden kann, wann hoch- und herunterskaliert werden soll.
Der Kubernetes Metrics Server ermöglicht die Skalierung als Reaktion auf integrierte Messwerte wie CPU- und Speicherauslastung. Wenn Sie jedoch auf der Grundlage anderer Metriken wie Amazon CloudWatch oder SQS-Warteschlangentiefe skalieren möchten, sollten Sie ereignisgesteuerte Autoscaling-Projekte wie KEDA in Betracht ziehen.
Die Reduzierung des Workload-Verbrauchs führt zu überschüssiger Kapazität in einem Cluster. Mit der richtigen Autoscaling-Konfiguration können Sie Knoten automatisch herunterskalieren und so Ihre Gesamtausgaben reduzieren. Wir empfehlen Ihnen, nicht zu versuchen, die Rechenkapazität manuell zu optimieren. Der Kubernetes-Scheduler und die Node-Autoscaler wurden so konzipiert, dass sie diesen Prozess für Sie übernehmen.
Reduzieren Sie ungenutzte Kapazitäten
Nachdem Sie die richtige Größe für Anwendungen ermittelt und so die Anzahl der Anfragen reduziert haben, können Sie damit beginnen, die bereitgestellte Rechenkapazität zu reduzieren. Sie sollten in der Lage sein, dies dynamisch zu tun, wenn Sie sich die Zeit genommen haben, Ihre Workloads anhand der obigen Abschnitte richtig zu dimensionieren. Es gibt zwei primäre Node-Autoscaler, die mit Kubernetes in AWS verwendet werden.
Karpenter und Cluster Autoscaler
Sowohl Karpenter als auch der Kubernetes Cluster Autoscaler skalieren die Anzahl der Knoten in Ihrem Cluster, wenn Pods erstellt oder entfernt werden und sich die Rechenanforderungen ändern. Das Hauptziel ist bei beiden dasselbe, aber Karpenter verfolgt einen anderen Ansatz für die Bereitstellung und Deprovisionierung von Knoten, was zur Kostensenkung und Optimierung der clusterweiten Nutzung beitragen kann.
Je größer die Cluster werden und die Vielfalt der Workloads zunimmt, desto schwieriger wird es, Knotengruppen und Instanzen vorzukonfigurieren. Genau wie bei Workload-Anfragen ist es wichtig, eine anfängliche Ausgangsbasis festzulegen und diese bei Bedarf kontinuierlich anzupassen.
Wenn Sie Cluster Autoscaler verwenden, werden die Minimal- und Maximalwerte jeder Auto Scaling Scaling-Gruppe (ASG) berücksichtigt und nur der „gewünschte“ Wert angepasst. Bei der Festlegung dieser Werte für die zugrunde liegende ASG ist Vorsicht geboten, da Cluster Autoscaler eine ASG nicht über ihre „minimale“ Anzahl hinaus herunterskalieren kann. Stellen Sie die „gewünschte“ Anzahl als die Anzahl der Knoten ein, die Sie während der normalen Geschäftszeiten benötigen, und „Minimum“ als die Anzahl der Knoten, die Sie außerhalb der Geschäftszeiten benötigen. Weitere Informationen finden Sie im Dokument Häufig gestellte Fragen zu Cluster Autoscaler
Cluster Autoscaler Priority Expander
Der Kubernetes Cluster Autoscaler funktioniert, indem er Gruppen von Knoten — eine so genannte Knotengruppe — nach oben und unten skaliert, während Anwendungen nach oben und unten skaliert werden. Wenn Sie Workloads nicht dynamisch skalieren, hilft Ihnen der Cluster Autoscaler nicht dabei, Geld zu sparen. Für den Cluster Autoscaler muss ein Clusteradministrator im Voraus Knotengruppen erstellen, damit die Workloads genutzt werden können. Die Knotengruppen müssen so konfiguriert werden, dass sie Instanzen verwenden, die dasselbe „Profil“ haben, d. h. ungefähr die gleiche Menge an CPU und Arbeitsspeicher.
Sie können mehrere Knotengruppen haben und der Cluster Autoscaler kann so konfiguriert werden, dass er Prioritätsskalierungsstufen festlegt. Jede Knotengruppe kann Knoten unterschiedlicher Größe enthalten. Knotengruppen können unterschiedliche Kapazitätstypen haben und der Priority Expander kann verwendet werden, um kostengünstigere Gruppen zuerst zu skalieren.
Im Folgenden finden Sie ein Beispiel für einen Ausschnitt aus der Clusterkonfiguration, der a verwendet, um reservierte Kapazität ConfigMap`
zu priorisieren, bevor On-Demand-Instances verwendet werden. Sie können dieselbe Technik verwenden, um Graviton- oder Spot-Instances gegenüber anderen Typen zu priorisieren.
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster managedNodeGroups: - name: managed-ondemand minSize: 1 maxSize: 7 instanceType: m5.xlarge - name: managed-reserved minSize: 2 maxSize: 10 instanceType: c5.2xlarge
apiVersion: v1 kind: ConfigMap metadata: name: cluster-autoscaler-priority-expander namespace: kube-system data: priorities: |- 10: - .*ondemand.* 50: - .*reserved.*
Die Verwendung von Knotengruppen kann dazu beitragen, dass die zugrunde liegenden Rechenressourcen standardmäßig das Erwartete tun, z. B. Knoten über mehrere Knoten verteilen AZs, aber nicht alle Workloads haben dieselben Anforderungen oder Erwartungen, und es ist besser, Anwendungen ihre Anforderungen explizit deklarieren zu lassen. Weitere Informationen zu Cluster Autoscaler finden Sie im Abschnitt mit bewährten
Descheduler
Der Cluster Autoscaler kann einem Cluster Knotenkapazität hinzufügen oder daraus entfernen, wenn neue Pods geplant werden müssen oder Knoten nicht ausgelastet sind. Die Pod-Platzierung, nachdem sie für einen Knoten geplant wurde, wird nicht ganzheitlich betrachtet. Wenn Sie den Cluster Autoscaler verwenden, sollten Sie sich auch den Kubernetes-Descheduler
Wenn Sie 10 Knoten in einem Cluster haben und jeder Knoten zu 60% ausgelastet ist, nutzen Sie nicht 40% der bereitgestellten Kapazität im Cluster. Mit dem Cluster Autoscaler können Sie den Auslastungsschwellenwert pro Knoten auf 60% festlegen. Damit wird jedoch nur versucht, einen einzelnen Knoten herunterzuskalieren, wenn die Auslastung unter 60% gesunken ist.
Mit dem Descheduler kann er sich die Clusterkapazität und -auslastung ansehen, nachdem Pods geplant oder Knoten zum Cluster hinzugefügt wurden. Es versucht, die Gesamtkapazität des Clusters über einem bestimmten Schwellenwert zu halten. Es kann auch Pods entfernen, die auf Knotenfehlern oder neuen Knoten basieren, die dem Cluster beitreten, um sicherzustellen, dass Pods in ihrer optimalen Rechenumgebung ausgeführt werden. Beachten Sie, dass der Descheduler den Austausch entfernter Pods nicht plant, sondern sich dafür auf den Standard-Scheduler stützt.
Konsolidierung von Karpenter
Karpenter verfolgt bei der Knotenverwaltung einen „gruppenlosen“ Ansatz. Dieser Ansatz ist flexibler für verschiedene Workload-Typen und erfordert weniger Vorabkonfiguration für Clusteradministratoren. Anstatt Gruppen vorab zu definieren und jede Gruppe nach den Anforderungen der Workloads zu skalieren, verwendet Karpenter Provisioner und Knotenvorlagen, um allgemein zu definieren, welche Art von EC2 Instanzen erstellt werden können und welche Einstellungen für die Instanzen bei ihrer Erstellung vorgenommen werden.
Beim Bin-Packing werden mehr Ressourcen der Instanz genutzt, indem mehr Workloads auf weniger Instanzen mit optimaler Größe gepackt werden. Dies trägt zwar dazu bei, Ihre Rechenkosten zu senken, da nur Ressourcen bereitgestellt werden, die Ihre Workloads nutzen, aber es hat auch einen Kompromiss. Das Starten neuer Workloads kann länger dauern, da dem Cluster Kapazität hinzugefügt werden muss, insbesondere bei großen Skalierungsereignissen. Achten Sie bei der Einrichtung von Bin Packing auf das Gleichgewicht zwischen Kostenoptimierung, Leistung und Verfügbarkeit.
Karpenter kann die Instanzressourcen kontinuierlich überwachen und nach Bedarf zusammenführen, um die Auslastung der Instanzressourcen zu verbessern und Ihre Rechenkosten zu senken. Karpenter kann auch einen kostengünstigeren Worker-Node für Ihre Arbeitslast auswählen. Dies kann erreicht werden, indem das Flag „Konsolidierung“ im Provisioner auf true gesetzt wird (Beispielcodeausschnitt unten). Das folgende Beispiel zeigt einen Beispiel-Provisioner, der die Konsolidierung ermöglicht. Zum Zeitpunkt der Erstellung dieses Handbuchs wird Karpenter eine laufende Spot-Instance nicht durch eine günstigere Spot-Instance ersetzen. Weitere Informationen zur Konsolidierung von Karpenter finden Sie in diesem Blog.
apiVersion: karpenter.sh/v1 kind: Provisioner metadata: name: enable-binpacking spec: consolidation: enabled: true
Bei Workloads, die möglicherweise nicht unterbrochen werden können, z. B. lange laufende Batch-Jobs ohne Checkpointing, sollten Sie in Erwägung ziehen, Pods mit der Anmerkung zu annotieren. do-not-evict
Indem Sie Pods von der Räumung ausschließen, teilen Sie Karpenter mit, dass es nicht freiwillig Knoten entfernen soll, die diesen Pod enthalten. Wenn jedoch ein do-not-evict
Pod zu einem Knoten hinzugefügt wird, während der Knoten leer ist, werden die verbleibenden Pods trotzdem entfernt, aber dieser Pod blockiert die Beendigung, bis er entfernt wird. In beiden Fällen wird der Knoten gesperrt, um zu verhindern, dass zusätzliche Arbeiten am Knoten geplant werden. Im Folgenden finden Sie ein Beispiel, das zeigt, wie die Anmerkung gesetzt wird:
8"" linenumbering="unnumbered">apiVersion: v1 kind: Pod metadata: name: label-demo labels: environment: production annotations: + "karpenter.sh/do-not-evict": "true" spec: containers: * name: nginx image: nginx ports: ** containerPort: 80
Entfernen Sie nicht ausgelastete Knoten, indem Sie die Cluster Autoscaler-Parameter anpassen
Die Knotenauslastung ist definiert als die Summe der angeforderten Ressourcen geteilt durch die Kapazität. Standardmäßig scale-down-utilization-threshold
ist der Wert auf 50% festgelegt. Dieser Parameter kann zusammen mit und verwendet werdenscale-down-unneeded-time
, wodurch festgelegt wird, wie lange ein Knoten nicht benötigt werden soll, bevor er herunterskaliert werden kann. Die Standardeinstellung ist 10 Minuten. Pods, die immer noch auf einem herunterskalierten Knoten laufen, werden vom kube-scheduler auf anderen Knoten geplant. Das Anpassen dieser Einstellungen kann helfen, nicht ausgelastete Knoten zu entfernen. Es ist jedoch wichtig, dass Sie diese Werte zuerst testen, damit Sie den Cluster nicht zu einer vorzeitigen Herunterskalierung zwingen.
Sie können ein Herunterskalieren verhindern, indem Sie sicherstellen, dass Pods, deren Entfernung teuer ist, durch ein Etikett geschützt sind, das vom Cluster Autoscaler erkannt wird. Stellen Sie dazu sicher, dass Pods, deren Entfernung teuer ist, über die Anmerkung verfügen. cluster-autoscaler.kubernetes.io/safe-to-evict=false
Im Folgenden finden Sie ein Beispiel für Yaml zum Setzen der Anmerkung:
8"" linenumbering="unnumbered">apiVersion: v1 kind: Pod metadata: name: label-demo labels: environment: production annotations: + "cluster-autoscaler.kubernetes.io/safe-to-evict": "false" spec: containers: * name: nginx image: nginx ports: ** containerPort: 80