Cloud-native eingehende Analyse von K8S-Anfragen und -Einschränkungen

1. Kubernetes-Einschränkungen und -Anfragen

  • Bei der Arbeit mit Containern in Kubernetes ist es wichtig zu verstehen, um welche Ressourcen es sich handelt und warum sie benötigt werden. Da einige Prozesse mehr CPU oder Arbeitsspeicher benötigen als andere, ist es von entscheidender Bedeutung, dass Sie einen Prozess niemals aushungern lassen sollten. In diesem Wissen sollten Container und Pods ordnungsgemäß konfiguriert sein, um beides optimal nutzen zu können.
  • Limits und Anfragen sind wichtige Einstellungen bei der Arbeit mit Kubernetes. Kubernetes definiert ein Limit als die maximale Menge an Ressourcen, die ein Container nutzen kann, was bedeutet, dass ein Container niemals mehr als die angegebene Menge an Speicher oder CPU verbraucht. Eine Anfrage hingegen ist die garantierte Mindestmenge an Ressourcen, die für einen Container reserviert sind.

Fügen Sie hier eine Bildbeschreibung ein

  • Betrachten Sie die folgende Bereitstellung, indem Sie Grenzwerte und Anforderungen für CPU und Speicher für zwei verschiedene Container festlegen:
kind: Deployment
apiVersion: extensions/v1beta1
# …
template:
  spec:
    containers:
      - name: redis
        image: redis:5.0.3-alpine
        resources:
          limits:
            memory: 600Mi
            cpu: 1
         requests:
            memory: 300Mi
            cpu: 500m
      - name: busybox
        image: busybox:1.28
        resources:
          limits:
            memory: 200Mi
            cpu: 300m
          requests:
            memory: 100Mi
            cpu: 100m
  • Angenommen, Sie betreiben einen Cluster, beispielsweise mit 4 Kernen und 16 GB RAM-Knoten, können Sie viele Informationen extrahieren:

Fügen Sie hier eine Bildbeschreibung ein

  • Analysebeschreibung:
    • Die effektive Pod-Anforderung beträgt 400 MiB Speicher und 600 Millicore-CPU. Für die Pod-Planung ist ein Knoten mit ausreichend verfügbarem zuweisbarem Speicherplatz erforderlich.
    • Der Redis-Container hat 512 CPU-Anteile, der Busybox-Container hat 102 CPU-Anteile, Kubernetes weist immer 1024 Anteile pro Kern zu, also Redis: 1024 * 0,5 Kerne ≅ 512 und Busybox: 1024 * 0,1 Kerne ≅ 102;
    • Wenn ein Redis-Container versucht, mehr als 600 MB RAM zuzuweisen, wird er durch OOM beendet, was höchstwahrscheinlich zum Ausfall des Pods führt.
    • Wenn Redis versucht, alle 100 ms mehr als 100 ms CPU zu nutzen (da 4 Kerne vorhanden sind, stehen 400 ms pro 100 ms zur Verfügung), ist Redis an die CPU gebunden, was zu einer schlechten Leistung führt.
    • Wenn der Busybox-Container versucht, mehr als 200 MB RAM zuzuweisen, wird er durch OOM beendet, was zum Ausfall des Pods führt.
    • Wenn Busybox versucht, alle 100 ms mehr als 30 ms CPU zu nutzen, kommt es zu einer CPU-Drosselung, was zu einer schlechten Leistung führt.

① Kubernetes-Anfrage

  • Kubernetes definiert eine Anfrage als die garantierte Mindestmenge an Ressourcen, die von einem Container verwendet wird. Im Grunde legt es die Mindestmenge an Ressourcen fest, die ein Container verbrauchen wird.
  • Wenn ein Pod geplant wird, prüft kube-scheduler die Kubernetes-Anfrage, um sie einem bestimmten Knoten zuzuweisen, der mindestens die Anzahl aller Container im Pod erfüllen kann. Wenn die Anzahl der Anfragen höher ist als die verfügbaren Ressourcen, wird der Pod nicht geplant und verbleibt im Status „Ausstehend“.
  • Weitere Informationen zum Status „Ausstehend“ finden Sie unter Grundlegendes zu ausstehenden Problemen mit Kubernetes-Pods .
  • In diesem Beispiel wird in der Containerdefinition eine Anforderung für 100 Mio. CPU-Kerne und 4Mi Speicher festgelegt:
resources:
   requests:
        cpu: 0.1
        memory: 4Mi
  • Nutzungsanfrage:
    • Wenn Sie einem Knoten einen Pod zuweisen, erfüllen Sie die vom Container im Pod angegebene Anforderung.
    • Zur Laufzeit entspricht die angegebene Anforderungsmenge garantiert der Mindestanforderungsmenge für die Container in diesem Pod.

Fügen Sie hier eine Bildbeschreibung ein

② Kubernetes-Einschränkungen

  • Kubernetes definiert ein Limit als die maximale Menge an Ressourcen, die ein Container nutzen kann, was bedeutet, dass ein Container niemals mehr als die angegebene Menge an Speicher oder CPU verbraucht.
 resources:
      limits:
        cpu: 0.5
        memory: 100Mi
  • Nutzungsbeschränkungen:
    • Wenn Pods Knoten zugewiesen werden. Wenn „Requests“ nicht festgelegt ist, weist Kubernetes standardmäßig „Requests = Limits“ zu.
    • Zur Laufzeit prüft Kubernetes, ob die Container im Pod mehr Ressourcen verbrauchen als im Limit angegeben.

Fügen Sie hier eine Bildbeschreibung ein

2. CPU-Funktionen

  • Die CPU ist eine komprimierbare Ressource, was bedeutet, dass sie erweitert werden kann, um allen Anforderungen gerecht zu werden. Wenn ein Prozess zu viel CPU anfordert, wird ein Teil davon gedrosselt.
  • Die CPU stellt die Rechenzeit in Kernen dar:
    • Millicores (m) können verwendet werden, um Mengen darzustellen, die kleiner als Kerne sind (z. B. wären 500 m halb so viele Kerne);
    • Der Mindestbetrag beträgt 1 Mio.;
    • Ein Knoten kann über mehrere Kerne verfügen, daher ist die Anforderung von CPU > 1 möglich.

Fügen Sie hier eine Bildbeschreibung ein

3. Gedächtniseigenschaften

  • Speicher ist eine inkompressible Ressource, das heißt, er kann nicht wie eine CPU erweitert werden. Wenn ein Prozess nicht über genügend Arbeitsspeicher verfügt, um seine Arbeit auszuführen, wird der Prozess beendet.
  • Der Speicher wird in Kubernetes in Bytes gemessen:
    • E, P, T, G, M, k können zur Darstellung von Exabyte, Petabyte, Terabyte, Gigabyte, Megabyte und Kilobyte verwendet werden, obwohl normalerweise nur die letzten vier verwendet werden (z. B. 500 MB, 4 GB).
    • WARNUNG: Verwenden Sie kein kleines m für den Speicher (dies steht für Millibytes, lächerlich niedrig);
    • Mebibyte können mit Mi und der Rest als Ei, Pi, Ti (z. B. 500Mi) definiert werden.
  • 1 Mebibyte (und seine Analoga Kibibyte, Gibibyte usw.) sind 220 Bytes und wurden erstellt, um Verwechslungen mit den metrischen Kilo- und Mega-Definitionen zu vermeiden. Diese Notation sollte verwendet werden, da es sich um die Spezifikation für die Byte-Definition handelt, während Kilo und Mega Vielfache sind von 1000.

Fügen Sie hier eine Bildbeschreibung ein

4. Best Practices

  • In seltenen Fällen sollten Limits verwendet werden, um die Ressourcennutzung in Kubernetes zu steuern, da Anforderungen zuerst verwendet werden sollten, wenn Sie eine Hungersnot vermeiden möchten (stellen Sie sicher, dass jeder wichtige Prozess seinen Anteil erhält).
  • Durch das Festlegen von Grenzwerten verhindern Sie lediglich, dass der Prozess in Ausnahmefällen zusätzliche Ressourcen erhält, OOM-Kill im Falle von Arbeitsspeicher und Drosselung im Falle von CPU (der Prozess muss warten, bis die CPU wieder verwendet werden kann).
  • Weitere Informationen finden Sie im Artikel über OOM und Drosselung .
  • Wenn der Anforderungswert in allen Containern eines Pods auf den Grenzwert gesetzt ist, erhält der Pod eine garantierte Servicequalität. Beachten Sie außerdem, dass Pods mit einer höheren Ressourcennutzung als angefordert mit größerer Wahrscheinlichkeit geräumt werden. Daher kann die Festlegung sehr niedriger Anforderungen mehr schaden als nützen.
  • Weitere Informationen finden Sie im Artikel über Pod-Eviction und Quality of Service.

5. Namespace-Ressourcenkontingent

  • Dank Namespaces ist es möglich, Kubernetes-Ressourcen in verschiedene Gruppen, auch Mandanten genannt, zu isolieren. Mithilfe von ResourceQuotas können Speicher- oder CPU-Limits für den gesamten Namespace festgelegt werden, um sicherzustellen, dass darin enthaltene Entitäten nicht mehr von dieser Menge verbrauchen können.
apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
    requests.cpu: 2
    requests.memory: 1Gi
    limits.cpu: 3
    limits.memory: 2Gi
  • veranschaulichen:
    • equests.cpu: die maximale CPU-Menge in der Summe aller Anfragen in diesem Namespace;
    • request.memory: die maximale Speichermenge in der Summe aller Anfragen in diesem Namespace;
    • limits.cpu: die maximale Anzahl an CPUs für die Summe aller Limits in diesem Namespace;
    • limits.memory: Die maximale Speichermenge für die Summe aller Limits in diesem Namespace.
  • Wenden Sie es dann auf den Namespace an:
kubectl apply -f resourcequota.yaml --namespace=mynamespace
  • Das aktuelle ResourceQuota für einen Namespace kann aufgelistet werden:
kubectl get resourcequota -n mynamespace
  • Beachten Sie, dass Sie, wenn Sie ein ResourceQuota für eine bestimmte Ressource in einem Namespace festlegen, für jeden Pod in diesem Namespace entsprechend ein Limit oder eine Anforderung angeben müssen. Andernfalls gibt Kubernetes den Fehler „Kontingent fehlgeschlagen“ zurück:
Error from server (Forbidden): error when creating "mypod.yaml": pods "mypod" is forbidden: failed quota: mem-cpu-demo: must specify limits.cpu,limits.memory,requests.cpu,requests.memory
  • Wenn Sie versuchen, ein Containerlimit hinzuzufügen oder einen neuen Pod anzufordern, der das aktuelle ResourceQuota überschreitet, gibt Kubernetes den Fehler „Quota Exceeded“ zurück:
Error from server (Forbidden): error when creating "mypod.yaml": pods "mypod" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.memory=2Gi,requests.memory=2Gi, used: limits.memory=1Gi,requests.memory=1Gi, limited: limits.memory=2Gi,requests.memory=1Gi

6. Namespace-Einschränkungen

  • ResourceQuotas sind nützlich, wenn Sie die Gesamtmenge der Ressourcen begrenzen möchten, die einem Namespace zugewiesen werden können. Was aber, wenn Sie den darin enthaltenen Elementen Standardwerte zuweisen möchten? LimitRanges ist eine Kubernetes-Richtlinie, die Ressourceneinstellungen pro Entität in einem Namespace begrenzt.
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-resource-constraint
spec:
  limits:
  - default:
      cpu: 500m
    defaultRequest:
      cpu: 500m
    min:
      cpu: 100m
    max:
      cpu: "1"
    type: Container
  • veranschaulichen:
    • Standard: Wenn nicht angegeben, haben erstellte Container diesen Wert;
    • min: Erstellte Container dürfen kein Limit oder keine kleinere Anforderung haben.
    • max: Erstellte Container dürfen kein größeres Limit oder keine größere Anforderung haben.
  • Wenn Sie später einen neuen Pod ohne festgelegte Anforderungen oder Grenzwerte erstellen, legt LimitRange diese Werte automatisch für alle seine Container fest:
   Limits:
      cpu:  500m
    Requests:
      cpu:  100m
  • Angenommen, Sie fügen einen neuen Pod mit einem Limit von 1200 MB hinzu, erhalten Sie die folgende Fehlermeldung:
Error from server (Forbidden): error when creating "pods/mypod.yaml": pods "mypod" is forbidden: maximum cpu usage per Container is 1, but limit is 1200m
  • Beachten Sie, dass standardmäßig alle Container in einem Pod tatsächlich 100 m CPU anfordern, auch wenn LimitRanges nicht festgelegt ist.

7. Fazit

  • Die Wahl des besten Limits für Ihren Kubernetes-Cluster ist der Schlüssel zum Erreichen der besten Leistung und Kosten.
  • Eine Überdimensionierung oder der Einsatz zu vieler Ressourcen für einen Pod kann die Kosten in die Höhe schnellen lassen.
  • Ein zu kleiner Maßstab oder eine sehr geringe CPU- oder Speicherbelegung führt dazu, dass die Anwendung nicht korrekt ausgeführt wird und sogar Pods entfernt werden.
  • Auf Kubernetes-Einschränkungen kann außer unter ganz bestimmten Umständen verzichtet werden, da sie möglicherweise mehr schaden als nützen. Unter Bedingungen mit wenig Arbeitsspeicher kann der Container beendet werden, oder unter Bedingungen mit wenig CPU kann der Container gedrosselt werden.
  • Verwenden Sie es für Anfragen, wenn Sie sicherstellen müssen, dass Prozesse garantierte Ressourcenanteile erhalten.

Supongo que te gusta

Origin blog.csdn.net/Forever_wj/article/details/131559618
Recomendado
Clasificación