Verteilen Sie die Workloads auf Knoten und Availability Zones - AWS Präskriptive Leitlinien

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.

Verteilen Sie die Workloads auf Knoten und Availability Zones

Die Verteilung eines Workloads auf Ausfalldomänen wie Availability Zones und Knoten verbessert die Verfügbarkeit der Komponenten und verringert die Ausfallwahrscheinlichkeit horizontal skalierbarer Anwendungen. In den folgenden Abschnitten werden Möglichkeiten zur Verteilung von Workloads auf Knoten und Availability Zones vorgestellt.

Verwenden Sie Einschränkungen bei der Verteilung der Pod-Topologie

Beschränkungen für die Verteilung der Kubernetes-Pod-Topologie weisen den Kubernetes-Scheduler an, Pods, die von ReplicaSet oder StatefulSet über verschiedene Ausfalldomänen (Availability Zones, Knoten und Hardwaretypen) verwaltet werden, zu verteilen. Wenn Sie Beschränkungen für die Verteilung der Pod-Topologie verwenden, können Sie Folgendes tun:

  • Verteilen oder konzentrieren Sie Pods je nach Anwendungsanforderungen auf verschiedene Fehlerdomänen. Sie können Pods beispielsweise verteilen, um die Ausfallsicherheit zu erhöhen, und Sie können Pods aus Gründen der Netzwerkleistung konzentrieren.

  • Kombinieren Sie verschiedene Bedingungen, z. B. die Verteilung auf Availability Zones und die Verteilung auf mehrere Knoten.

  • Geben Sie die bevorzugte Aktion an, wenn die Bedingungen nicht erfüllt werden können:

    • Verwenden Sie diese Option whenUnsatisfiable: DoNotSchedule zusammen mit einer Kombination aus maxSkew undminDomains, um strenge Anforderungen an den Scheduler zu stellen.

    • Wird verwendetwhenUnsatisfiable: ScheduleAnyway, um zu reduzierenmaxSkew.

Wenn eine Fehlerzone nicht mehr verfügbar ist, werden die Pods in dieser Zone fehlerhaft. Kubernetes plant die Pods neu und hält sich dabei, wenn möglich, an die Verbreitungsbeschränkung.

Einschränkungen bei der Verteilung der Pod-Topologie

Der folgende Code zeigt ein Beispiel für die Verwendung von Beschränkungen für die Verteilung der Pod-Topologie über Availability Zones oder Knoten hinweg:

... spec: selector: matchLabels: app: <your-app-label> replicas: 3 template: metadata: labels: <your-app-label> spec: serviceAccountName: <ServiceAccountName> ... topologySpreadConstraints: - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: topology.kubernetes.io/zone # <---spread those pods evenly over all availability zones whenUnsatisfiable: ScheduleAnyway - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: kubernetes.io/hostname # <---spread those pods evenly over all nodes whenUnsatisfiable: ScheduleAnyway

Standardmäßige Einschränkungen für die clusterweite Topologieverteilung

Standardmäßig bietet Kubernetes einen Standardsatz von Beschränkungen für die Topologieverteilung für die Verteilung von Pods auf Knoten und Availability Zones:

defaultConstraints: - maxSkew: 3 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: ScheduleAnyway - maxSkew: 5 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway
Anmerkung

Anwendungen, die unterschiedliche Arten von Topologieeinschränkungen benötigen, können die Richtlinie auf Clusterebene außer Kraft setzen.

In den Standardeinschränkungen ist ein hoher Wert festgelegtmaxSkew, was für Bereitstellungen mit einer kleinen Anzahl von Pods nicht sinnvoll ist. KubeSchedulerConfigurationKann derzeit in Amazon EKS nicht geändert werden. Wenn Sie andere Gruppen von Beschränkungen für die Topologieverteilung durchsetzen müssen, sollten Sie die Verwendung eines mutierenden Zugangscontrollers in Betracht ziehen, wie im folgenden Abschnitt beschrieben. Sie können auch die standardmäßigen Beschränkungen für die Topologieverteilung steuern, wenn Sie einen alternativen Scheduler verwenden. Die Verwaltung benutzerdefinierter Scheduler erhöht jedoch die Komplexität und kann Auswirkungen auf die Clusterausfallsicherheit und Hochverfügbarkeit haben. Aus diesen Gründen empfehlen wir nicht, einen alternativen Scheduler nur für Einschränkungen der Topologieverteilung zu verwenden.

Die Gatekeeper-Richtlinie für Beschränkungen der Topologie-Spread-Verteilung

Eine weitere Option zur Durchsetzung von Beschränkungen der Topologieverteilung besteht darin, eine Richtlinie aus dem Gatekeeper-Projekt zu verwenden. Gatekeeper-Richtlinien werden auf Anwendungsebene definiert.

Die folgenden Codebeispiele zeigen die Verwendung einer Gatekeeper OPA Richtlinie für die Bereitstellung. Sie können die Richtlinie an Ihre Bedürfnisse anpassen. Wenden Sie die Richtlinie beispielsweise nur auf Bereitstellungen an, die das Label tragenHA=true, oder schreiben Sie eine ähnliche Richtlinie mit einem anderen Policy-Controller.

Dieses erste Beispiel zeigt die ConstraintTemplate Verwendung mitk8stopologyspreadrequired_template.yml:

apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8stopologyspreadrequired spec: crd: spec: names: kind: K8sTopologySpreadRequired validation: openAPIV3Schema: type: object properties: message: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8stopologyspreadrequired get_message(parameters, _default) =3D msg { not parameters.message msg :=_default } get_message(parameters, _default) =3D msg { msg := parameters.message } violation[{"msg": msg}] { input.review.kind.kind ="Deployment" not input.review.object.spec.template.spec.topologySpreadConstraint def_msg :"Pod Topology Spread Constraints are required for Deployments" msg :get_message(input.parameters, def_msg) }

Der folgende Code zeigt das constraints YAML-Manifestk8stopologyspreadrequired_constraint.yml:

apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sTopologySpreadRequired metadata: name: require-topologyspread-for-deployments spec: match: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] namespaces: ## Without theses two lines will apply to the whole cluster - "example"

Wann sollten Topologie-Spread-Beschränkungen verwendet werden

Erwägen Sie die Verwendung von Beschränkungen für die Topologieverteilung in den folgenden Szenarien:

  • Jede horizontal skalierbare Anwendung (z. B. statusfreie Webdienste)

  • Anwendungen mit aktiv-aktiven oder aktiv-passiven Replikaten (z. B. NoSQL-Datenbanken oder -Caches)

  • Anwendungen mit Standby-Replikaten (z. B. Controller)

Zu den Systemkomponenten, die für das horizontal skalierbare Szenario verwendet werden können, gehören beispielsweise die folgenden:

Pod-Affinität und Anti-Affinität

In einigen Fällen ist es von Vorteil, sicherzustellen, dass nicht mehr als ein Pod eines bestimmten Typs auf einem Knoten ausgeführt wird. Um beispielsweise zu vermeiden, dass mehrere netzwerkintensive Pods auf demselben Knoten geplant werden, können Sie die Anti-Affinitätsregel mit der Bezeichnung oder verwenden. Ingress Network-heavy Wenn Sie verwendenanti-affinity, können Sie auch eine Kombination der folgenden Optionen verwenden:

  • Makel auf netzwerkoptimierten Knoten

  • Entsprechende Toleranzen bei netzwerkintensiven Pods

  • Knotenaffinität oder Knotenauswahl, um sicherzustellen, dass netzwerkintensive Pods netzwerkoptimierte Instanzen verwenden

Als Beispiel werden netzwerkintensive Pods verwendet. Möglicherweise haben Sie unterschiedliche Anforderungen, z. B. GPU, Arbeitsspeicher oder lokalen Speicher. Weitere Anwendungsbeispiele und Konfigurationsoptionen finden Sie in der Kubernetes-Dokumentation.

Pods neu ausbalancieren

In diesem Abschnitt werden zwei Ansätze für das Rebalancing von Pods in einem Kubernetes-Cluster erörtert. Der erste verwendet den Descheduler für Kubernetes. Der Descheduler trägt zur Aufrechterhaltung der Pod-Verteilung bei, indem er Strategien zur Entfernung von Pods durchsetzt, die gegen Beschränkungen der Topologieverteilung oder gegen Anti-Affinitätsregeln verstoßen. Der zweite Ansatz verwendet die Karpenter Funktion zur Konsolidierung und zum Bin-Packen. Bei der Konsolidierung wird die Ressourcennutzung kontinuierlich bewertet und optimiert, indem Workloads auf weniger, aber effizienter gepackte Knoten konsolidiert werden.

Wir empfehlen die Verwendung von Descheduler, wenn Sie Karpenter nicht verwenden. Wenn Sie Karpenter und Cluster Autoscaler zusammen verwenden, können Sie Descheduler mit Cluster Autoscaler für Knotengruppen verwenden.

Descheduler für gruppenlose Knoten

Es gibt keine Garantie dafür, dass die Topologieeinschränkungen auch dann eingehalten werden, wenn Pods entfernt werden. Beispielsweise kann die Verkleinerung einer Bereitstellung zu einer unausgewogenen Pod-Verteilung führen. Da Kubernetes die Beschränkungen der Verteilung der Pod-Topologie jedoch nur in der Planungsphase verwendet, bleiben Pods in der gesamten Ausfalldomäne unausgewogen.

Um in solchen Szenarien eine ausgewogene Pod-Verteilung aufrechtzuerhalten, können Sie Descheduler for Kubernetes verwenden. Descheduler ist ein nützliches Tool für mehrere Zwecke, z. B. um das maximale Pod-Alter oder die maximale Gültigkeitsdauer (TTL) durchzusetzen oder die Nutzung der Infrastruktur zu verbessern. Im Zusammenhang mit Ausfallsicherheit und Hochverfügbarkeit (HA) sollten Sie die folgenden Descheduler-Strategien in Betracht ziehen:

Karpenter-Funktion zur Konsolidierung und zum Einpacken von Papierkörben

Für Workloads, die Karpenter verwenden, können Sie die Konsolidierungs- und Bin-Packing-Funktionen verwenden, um die Ressourcennutzung zu optimieren und die Kosten in Kubernetes-Clustern zu senken. Karpenter bewertet kontinuierlich die Pod-Platzierungen und die Knotenauslastung und versucht, Workloads nach Möglichkeit auf weniger, effizienter gepackte Knoten zu konsolidieren. Dieser Prozess beinhaltet die Analyse der Ressourcenanforderungen unter Berücksichtigung von Einschränkungen wie Pod-Affinitätsregeln und die potenzielle Verschiebung von Pods zwischen Knoten, um die Cluster-Effizienz insgesamt zu verbessern. Der folgende Code enthält ein Beispiel:

apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: default spec: disruption: consolidationPolicy: WhenUnderutilized expireAfter: 720h

Für consolidationPolicy können Sie WhenUnderutilized oder verwendenWhenEmpty:

  • Wenn auf gesetzt consolidationPolicy istWhenUnderutilized, berücksichtigt Karpenter alle Knoten bei der Konsolidierung. Wenn Karpenter einen Knoten entdeckt, der leer oder zu wenig genutzt ist, versucht Karpenter, den Knoten zu entfernen oder zu ersetzen, um die Kosten zu senken.

  • Wenn auf gesetzt consolidationPolicy ist, berücksichtigt Karpenter für die Konsolidierung nur KnotenWhenEmpty, die keine Workload-Pods enthalten.

Die Entscheidungen von Karpenter zur Konsolidierung basieren nicht ausschließlich auf der prozentualen CPU- oder Speicherauslastung, die Sie möglicherweise in Überwachungstools sehen. Stattdessen verwendet Karpenter einen komplexeren Algorithmus, der auf Pod-Ressourcenanforderungen und potenziellen Kostenoptimierungen basiert. Weitere Informationen finden Sie in der Karpenter-Dokumentation.