Für jede Kubernetes-Ressource besteht die Möglichkeit, zwei Arten von Anforderungen zu konfigurieren – Requests und Limits. Erstere beschreibt die minimalen Anforderungen an verfügbare Ressourcen des Knotens, die zum Starten eines Containers oder Pods erforderlich sind, während letztere die Ressourcen, die dem Container zur Verfügung stehen, streng limitiert.
Wenn Kubernetes einen Pod plant, ist es sehr wichtig, dass die Container über genügend Ressourcen für einen reibungslosen Betrieb verfügen. Wenn Sie eine große Anwendung auf einem Knoten mit begrenzten Ressourcen bereitstellen möchten, kann es gut sein, dass diese aufgrund von Speichermangel oder unzureichender Prozessorleistung nicht funktioniert. In diesem Artikel werden wir untersuchen, wie man Probleme mit unzureichenden Rechenressourcen mit Hilfe von Ressourcenanfragen und -beschränkungen lösen kann.
Requests und Limits sind Mechanismen, die Kubernetes verwendet, um Ressourcen wie Prozessor und Speicher zu verwalten. Requests gewährleisten, dass der Container die angeforderten Ressourcen erhält. Wenn der Container Ressourcen anfordert, plant Kubernetes diese nur auf dem Knoten, der sie bereitstellen kann. Limits kontrollieren, dass die vom Container angeforderten Ressourcen niemals einen bestimmten Wert überschreiten.

Ein Container kann seine Rechenleistung nur bis zu einem bestimmten Limit steigern, danach wird er begrenzt. Lassen Sie uns ansehen, wie dies funktioniert. Es gibt also zwei Arten von Ressourcen – Prozessor und Speicher. Der Kubernetes-Planer nutzt Informationen über diese Ressourcen, um herauszufinden, wo Ihre Pods gestartet werden sollen. Eine typische Spezifikation der Ressourcen für einen Pod sieht folgendermaßen aus.

Jeder Container in einem Pod kann seine eigenen Anforderungen und Limits festlegen, und all dies ist additiv. Die Ressourcen des Prozessors werden in Millikernen definiert. Wenn Ihr Container zum Starten zwei volle Kerne benötigt, stellen Sie den Wert auf 2000m ein. Benötigt der Container jedoch nur eine Leistung von 1/4 Kern, beträgt der Wert 250m. Bitte beachten Sie, dass, wenn Sie einen Wert für die Prozessorressourcen festlegen, der größer ist als die Anzahl der Kerne des größten Knotens, der Start Ihres Pods überhaupt nicht geplant wird. Eine ähnliche Situation tritt ein, wenn Sie einen Pod haben, der vier Kerne benötigt, der Kubernetes-Cluster jedoch nur aus zwei Haupt-VMs besteht.
Es sei denn, Ihre Anwendung wurde speziell entwickelt, um die Vorteile mehrerer Kerne zu nutzen (worauf Programme wie komplexe wissenschaftliche Berechnungen und Datenbankoperationen einfallen), ist es am besten, CPU-Anforderungen auf 1 oder weniger festzulegen und anschließend eine größere Anzahl von Replikaten für die Skalierbarkeit zu starten. Diese Lösung verleiht dem System größere Flexibilität und Zuverlässigkeit.
Wenn es um die Begrenzungen des Prozessors geht, wird es interessanter, da er als komprimierbare Ressource betrachtet wird. Wenn Ihre Anwendung dem Limit der Prozessorleistung näher kommt, wird Kubernetes beginnen, Ihren Container zu drosseln, indem es CPU-Throttling anwendet — die Frequenz des Prozessors wird gesenkt. Das bedeutet, dass der Prozessor künstlich begrenzt wird, was möglicherweise zu einer schlechteren Leistung der Anwendung führt, jedoch wird der Prozess nicht beendet oder herausgenommen.
Speicherressourcen werden in Bytes definiert. In der Regel wird der Wert in den Einstellungen in Mebibytes (Mib) angegeben, aber Sie können jeden Wert von Bytes bis Petabytes festlegen. Hier gilt die gleiche Situation wie bei der CPU: Wenn Sie einen Antrag auf eine Menge an Speicher stellen, die den Speicher Ihrer Knoten übersteigt, wird die Ausführung dieses Pods nicht geplant. Im Gegensatz zu den Ressourcen des Prozessors kann der Speicher jedoch nicht komprimiert werden, da es keine Möglichkeit gibt, seine Nutzung zu begrenzen. Daher wird die Ausführung des Containers gestoppt, sobald er die ihm zugewiesene Speichermenge überschreitet.

Es ist wichtig, daran zu denken, dass Sie keine Anfragen einrichten können, die die Größe der Ressourcen überschreiten, die Ihre Knoten bereitstellen können. Die Eigenschaften der gemeinsamen Ressourcen für virtuelle Maschinen von GKE finden Sie in den Links unter diesem Video.
In einer idealen Welt wären die Standard-Container-Einstellungen ausreichend, damit die Workflows reibungslos ablaufen. Aber die Realität sieht anders aus, denn Menschen vergessen leicht, die Ressourcennutzung zu konfigurieren, oder Hacker setzen Anfragen und Limits, die die tatsächlichen Möglichkeiten der Infrastruktur überschreiten. Um die Entwicklung solcher Szenarien zu verhindern, können Sie Ressourcen-Quotas (ResourceQuota) und Limit-Bereiche (LimitRange) einrichten.
Nach der Erstellung von Namespaces können diese durch Quotas abgesichert werden. Zum Beispiel, wenn Sie die Namespaces prod und dev haben, wird ein Muster verwendet, bei dem es keinerlei Quotas für die Produktionsumgebung gibt, während die Quotas für die Entwicklungsumgebung sehr streng sind. Dies ermöglicht es prod, bei einem plötzlichen Anstieg des Datenverkehrs alle verfügbaren Ressourcen zu beanspruchen und dev vollständig zu blockieren.
Eine Ressourcen-Quota könnte folgendermaßen aussehen. In diesem Beispiel gibt es 4 Abschnitte – das sind die 4 unteren Codezeilen.

Lassen Sie uns jeden von ihnen betrachten. Requests.cpu ist die maximale Menge an kombinierten CPU-Anfragen, die von allen Containern des Namespaces kommen können. In diesem Beispiel können Sie 50 Container mit Anfragen von 10m, fünf Container mit Anfragen von 100m oder einfach einen Container mit einer Anfrage von 500m haben. Solange die Gesamtzahl der requests.cpu dieses Namespaces unter 500m bleibt, ist alles in Ordnung.
Der angeforderte Speicher requests.memory ist die maximale Summe der Speicheranfragen, die alle Container im Namespace haben können. Wie im vorherigen Fall können Sie 50 Container mit jeweils 2 MiB, fünf Container mit jeweils 20 MiB oder einen einzelnen Container mit 100 MiB haben, solange die gesamte angeforderte Speichermenge im Namespace weniger als 100 MiB beträgt.
Limits.cpu ist der maximale kombinierte Wert der CPU-Leistung, die alle Container im Namespace verwenden können. Man kann sagen, dass dies das Limit für die CPU-Anfragen ist.
Schließlich ist limits.memory der maximale Gesamtbetrag an Arbeitsspeicher, den alle Container im Namensraum verwenden können. Diese Einschränkung bezieht sich auf die Gesamtanforderungen an den Arbeitsspeicher.
Standardmäßig arbeiten Container im Kubernetes-Cluster mit unbegrenzten Rechenressourcen. Mit Ressourcenkontingenten können Clusteradministratoren den Ressourcenverbrauch und deren Erstellung basierend auf dem Namensraum begrenzen. Im Namensraum kann ein Pod oder Container so viel CPU-Leistung und Arbeitsspeicher nutzen, wie im Ressourcenkontingent definiert. Es gibt jedoch Bedenken, dass ein Pod oder Container alle verfügbaren Ressourcen monopolisiert. Um dies zu verhindern, wird ein Limit Range verwendet – eine Richtlinie zur Einschränkung der Ressourcenzuteilung (für Pods oder Container) im Namensraum.
Der Limit Range bietet Einschränkungen, die folgendes ermöglichen:
- minimale und maximale Nutzung von Rechenressourcen für jeden Pod oder Container im Namensraum sicherzustellen;
- das minimale und maximale Speicherkontingent Storage Request für jeden PersistentVolumeClaim im Namensraum durchzusetzen;
- das Verhältnis zwischen der Anfrage Request und dem Limit Limit für die Ressource im Namensraum durchzusetzen;
- Standardeinstellungen für Requests/Limits der Rechenressourcen im Namensraum festzulegen und diese automatisch bei der Ausführung in die Container zu implementieren.
So können Sie einen Limit Range in Ihrem Namensraum erstellen. Im Gegensatz zum Kontingent, das für den gesamten Namensraum gilt, wird der Limit Range für einzelne Container verwendet. Dies kann verhindern, dass Benutzer sehr kleine oder im Gegensatz dazu riesige Container im Namensraum erstellen. Ein Limit Range könnte folgendermaßen aussehen.

Wie im vorherigen Fall können hier 4 Abschnitte hervorgehoben werden. Lassen Sie uns jeden einzelnen betrachten.
Im Abschnitt default werden die Standardbegrenzungen für Container im Pod festgelegt. Wenn Sie diese Werte im Limit Range angeben, gelten die Standardwerte für alle Container, für die diese Werte nicht ausdrücklich festgelegt wurden.
Im Abschnitt Standardanforderung defaultRequest sind die Standardanforderungen für Container im Pod konfiguriert. Wenn Sie diese Werte im Grenzwertbereich festlegen, verwenden alle Container, für die diese Parameter nicht ausdrücklich festgelegt sind, standardmäßig diese Werte.
Im Abschnitt max sind die maximalen Beschränkungen aufgeführt, die für Container im Pod festgelegt werden können. Die Werte im Abschnitt default und Einschränkungen für Container dürfen nicht über diesem Limit festgelegt werden. Es ist wichtig zu beachten, dass, wenn ein max-Wert festgelegt ist und der Abschnitt default fehlt, der maximale Wert zum Standardwert wird.
Im Abschnitt min sind die minimalen Anforderungen aufgeführt, die für Container im Pod festgelegt werden können. Dabei dürfen die Werte im Abschnitt default und die Anforderungen für Container nicht unter diesem Limit festgelegt werden.
Es ist wichtig zu beachten, dass, wenn dieser Wert festgelegt ist und der Standardwert nicht, das minimale Wert zur Standardanforderung wird.
Diese Ressourcenanforderungen werden vom Kubernetes-Scheduler zur Ausführung Ihrer Workloads verwendet. Um Ihre Container richtig zu konfigurieren, ist es wichtig zu verstehen, wie es funktioniert. Angenommen, Sie möchten mehrere Module in Ihrem Cluster starten. Vorausgesetzt, die Pod-Spezifikationen sind gültig, wird im Kubernetes-Plan eine zyklische Lastverteilung verwendet, um einen Knoten zur Ausführung der Workload auszuwählen.

Kubernetes überprüft, ob genügend Ressourcen auf Node 1 vorhanden sind, um die Anforderungen der Pod-Container zu erfüllen. Wenn dies nicht der Fall ist, wird zum nächsten Knoten gewechselt. Wenn jedoch keiner der Knoten im System die Anforderungen erfüllen kann, gehen die Pods in den Wartestatus Pending state über. Mithilfe solcher Funktionen wie Autoskalierung von Knoten kann Google Kubernetes Engine (GKE) den Wartestatus automatisch erkennen und zusätzliche Knoten erstellen.
Wenn später ein übermäßiges Knotenangebot vorhanden sein sollte, reduziert die Autoskalierungsfunktion deren Anzahl, um Ihnen Geld zu sparen. Daher plant Kubernetes Pods basierend auf den Anforderungen. Es kann jedoch sein, dass das Limit über den Anforderungen liegt, und in einigen Fällen kann der Knoten tatsächlich Ressourcen erschöpfen. Wir nennen solchen Zustand overcommitment state.

Wie ich bereits sagte, wenn es um den Prozessor geht, wird Kubernetes anfangen, Pods zu limitieren. Jeder Pod erhält so viel, wie er angefordert hat, aber wenn er das Limit nicht erreicht, wird Throttling angewendet.
Was den Speicherressourcen betrifft, so muss Kubernetes Entscheidungen treffen, welche Pods gelöscht und welche beibehalten werden, bis Sie Systemressourcen freigeben, sonst stürzt das gesamte System ab.
Lassen Sie uns ein Szenario vorstellen, in dem Sie eine Maschine haben, die ihr Speicherkontingent überschreitet – wie wird Kubernetes damit umgehen?
Kubernetes wird nach Pods suchen, die mehr Ressourcen verwenden, als sie angefragt haben. Wenn Ihre Container überhaupt keine Requests haben, bedeutet das, dass sie standardmäßig mehr verwenden, als sie angefordert haben, einfach weil sie nichts angefordert haben! Solche Container werden die Hauptkandidaten zum Ausschalten. Nächste Kandidaten sind Container, die alle ihre Anfragen erfüllt haben, aber noch unter dem maximalen Limit liegen.
Wenn Kubernetes also mehrere Pods findet, die ihre Anfordernisse überschreiten, wird es sie nach Priorität sortieren und dann die am niedrigsten priorisierten Module löschen. Wenn alle Module die gleiche Priorität haben, wird Kubernetes die Pods ausschalten, die ihre Anfragen mehr überschreiten als die anderen Pods.
In sehr seltenen Fällen kann Kubernetes auch Pods beenden, die sich noch im Rahmen ihrer Anfragen befinden. Dies kann passieren, wenn kritische Systemkomponenten wie der Kubelet-Agent oder Docker mehr Ressourcen verbrauchen, als für sie reserviert sind.
In den Anfangsphasen kleiner Unternehmen kann ein Kubernetes-Cluster hervorragend ohne Ressourcenzuweisungen und -grenzen funktionieren, aber wenn Ihre Teams und Projekte wachsen, sind Sie möglicherweise mit Problemen in diesem Bereich konfrontiert. Das Hinzufügen von Anfragen und Grenzen zu Ihren Modulen und Namespaces erfordert nur wenig zusätzlichen Aufwand und kann viele Probleme vermeiden.

Ein wenig Werbung 🙂
Danke, dass Sie bei uns bleiben. Gefallen Ihnen unsere Artikel? Möchten Sie mehr interessante Inhalte sehen? Unterstützen Sie uns, indem Sie eine Bestellung aufgeben oder uns Freunden empfehlen, , ein einzigartiges Äquivalent zu Einsteigerservern, das wir für Sie entwickelt haben: (es sind Optionen mit RAID1 und RAID10 bis zu 24 Kernen und bis zu 40GB DDR4 verfügbar).
Dell R730xd ist im Equinix Tier IV Rechenzentrum in Amsterdam doppelt so günstig? Nur bei uns in den Niederlanden! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — ab $99! Lesen Sie, wie
Quelle: habr.com
