View a markdown version of this page

Kubernetes-Datenebene - Amazon EKS

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.

Kubernetes-Datenebene

Die Auswahl von EC2-Instanztypen ist möglicherweise eine der schwierigsten Entscheidungen, vor denen Kunden stehen, da es sich um Cluster mit mehreren Workloads handelt. Es gibt keine Einheitslösung. Im Folgenden finden Sie einige Tipps, mit denen Sie häufige Fallstricke bei der Skalierung von Rechenleistung vermeiden können.

Automatische Knotenskalierung

Wir empfehlen Ihnen, Node-Autoscaling zu verwenden, das den Aufwand reduziert und tief in Kubernetes integriert ist. Verwaltete Knotengruppen und Karpenter werden für große Cluster empfohlen.

Verwaltete Knotengruppen bieten Ihnen die Flexibilität von Amazon EC2 Auto Scaling-Gruppen mit zusätzlichen Vorteilen für verwaltete Upgrades und Konfigurationen. Es kann mit dem Kubernetes Cluster Autoscaler skaliert werden und ist eine gängige Option für Cluster mit unterschiedlichen Rechenanforderungen.

Karpenter ist ein von AWS entwickelter Open-Source-Node-Autoscaler, der Workload-nativ ist. Er skaliert Knoten in einem Cluster auf der Grundlage der Workload-Anforderungen an Ressourcen (z. B. GPU) und auf der Grundlage von Schwachstellen und Toleranzen (z. B. Zonenverteilung), ohne Knotengruppen zu verwalten. Knoten werden direkt in EC2 erstellt, wodurch die Standardkontingente für Knotengruppen — 450 Knoten pro Gruppe — vermieden werden, und eine größere Flexibilität bei der Instance-Auswahl bei geringerem Betriebsaufwand bietet. Wir empfehlen Kunden, nach Möglichkeit Karpenter zu verwenden.

Verwenden Sie viele verschiedene EC2-Instance-Typen

Jede AWS-Region verfügt über eine begrenzte Anzahl verfügbarer Instances pro Instance-Typ. Wenn Sie einen Cluster erstellen, der nur einen Instanztyp verwendet, und die Anzahl der Knoten über die Kapazität der Region hinaus skalieren, erhalten Sie eine Fehlermeldung, dass keine Instanzen verfügbar sind. Um dieses Problem zu vermeiden, sollten Sie die Art der Instances, die in Ihrem Cluster verwendet werden können, nicht beliebig einschränken.

Karpenter verwendet standardmäßig eine breite Palette kompatibler Instance-Typen und wählt bei der Bereitstellung eine Instance auf Grundlage der ausstehenden Workload-Anforderungen, Verfügbarkeit und Kosten aus. Sie können die Liste der im Schlüssel von verwendeten Instanztypen erweitern. karpenter.k8s.aws/instance-category NodePools

Für den Kubernetes Cluster Autoscaler müssen Knotengruppen ähnlich groß sein, damit sie konsistent skaliert werden können. Sie sollten je nach CPU- und Speichergröße mehrere Gruppen erstellen und diese unabhängig voneinander skalieren. Verwenden Sie den ec2-instance-selector, um Instances zu identifizieren, die für Ihre Knotengruppen ähnlich groß sind.

ec2-instance-selector --service eks --vcpus-min 8 --memory-min 16
a1.2xlarge
a1.4xlarge
a1.metal
c4.4xlarge
c4.8xlarge
c5.12xlarge
c5.18xlarge
c5.24xlarge
c5.2xlarge
c5.4xlarge
c5.9xlarge
c5.metal

Bevorzugen Sie größere Knoten, um die API-Serverlast zu reduzieren

Bei der Entscheidung, welche Instanztypen verwendet werden sollen, belasten weniger, große Knoten die Kubernetes Control Plane weniger, da weniger Kubelets laufen. DaemonSets Große Knoten werden jedoch möglicherweise nicht wie kleinere Knoten vollständig genutzt. Die Knotengrößen sollten auf der Grundlage Ihrer Workload-Verfügbarkeit und Skalierungsanforderungen bewertet werden.

Ein Cluster mit drei u-24tb1.metal-Instances (24 TB Arbeitsspeicher und 448 Kerne) hat 3 Kubelets und wäre standardmäßig auf 110 Pods pro Knoten begrenzt. Wenn Ihre Pods jeweils 4 Kerne verwenden, ist dies möglicherweise zu erwarten (4 Kerne x 110 = 440). cores/node Bei einem Cluster mit 3 Knoten wäre Ihre Fähigkeit, einen Instance-Vorfall zu bewältigen, gering, da ein Ausfall einer Instanz Auswirkungen auf den Cluster haben 1/3 könnte. Sie sollten die Knotenanforderungen und die Verteilung der Pods in Ihren Workloads angeben, damit der Kubernetes-Scheduler die Workloads richtig platzieren kann.

Workloads sollten die Ressourcen, die sie benötigen, und die erforderliche Verfügbarkeit anhand von Taints, Toleranzen usw. definieren. PodTopologySpread Sie sollten die größten Knoten bevorzugen, die voll ausgelastet werden können, und die Verfügbarkeitsziele erfüllen, um die Belastung der Steuerungsebene zu reduzieren, den Betrieb zu senken und die Kosten zu senken.

Der Kubernetes Scheduler versucht automatisch, Workloads auf Availability Zones und Hosts zu verteilen, sofern Ressourcen verfügbar sind. Wenn keine Kapazität verfügbar ist, versucht der Kubernetes Cluster Autoscaler, Knoten in jeder Availability Zone gleichmäßig hinzuzufügen. Karpenter wird versuchen, Knoten so schnell und kostengünstig wie möglich hinzuzufügen, sofern die Arbeitslast keine anderen Anforderungen stellt.

Um zu erzwingen, dass sich die Arbeitslasten mithilfe des Schedulers verteilen und neue Knoten auf mehrere Verfügbarkeitszonen erstellt werden, sollten Sie die Topologie verwenden: SpreadConstraints

spec:
  topologySpreadConstraints:
    - maxSkew: 3
      topologyKey: "topology.kubernetes.io/zone"
      whenUnsatisfiable: ScheduleAnyway
      labelSelector:
        matchLabels:
          dev: my-deployment
    - maxSkew: 2
      topologyKey: "kubernetes.io/hostname"
      whenUnsatisfiable: ScheduleAnyway
      labelSelector:
        matchLabels:
          dev: my-deployment

Verwenden Sie ähnliche Knotengrößen für eine konsistente Workload-Leistung

Workloads sollten definieren, auf welcher Knotengröße sie ausgeführt werden müssen, um eine konsistente Leistung und vorhersehbare Skalierung zu ermöglichen. Ein Workload, der 500 Millionen CPUs benötigt, wird auf einer Instance mit 4 Kernen anders funktionieren als auf einer Instance mit 16 Kernen. Vermeiden Sie Instance-Typen, die Burstable-CPUs wie Instances der T-Serie verwenden.

Um sicherzustellen, dass Ihre Workloads eine konsistente Leistung erzielen, kann ein Workload die unterstützten Karpenter-Labels verwenden, um bestimmte Instance-Größen anzusprechen.

kind: deployment
...
spec:
  template:
    spec:
    containers:
    nodeSelector:
      karpenter.k8s.aws/instance-size: 8xlarge

Workloads, die mit dem Kubernetes Cluster Autoscaler in einem Cluster geplant werden, sollten einen Knotenselektor anhand des Label-Matchings den Knotengruppen zuordnen.

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/nodegroup
            operator: In
            values:
            - 8-core-node-group    # match your node group name

Nutzen Sie Rechenressourcen effizient

Zu den Rechenressourcen gehören EC2-Instances und Availability Zones. Die effektive Nutzung von Rechenressourcen erhöht Ihre Skalierbarkeit, Verfügbarkeit und Leistung und senkt Ihre Gesamtkosten. Eine effiziente Ressourcennutzung ist in einer Autoscaling-Umgebung mit mehreren Anwendungen äußerst schwer vorherzusagen. Karpenter wurde entwickelt, um Instanzen auf der Grundlage der Workload-Anforderungen bei Bedarf bereitzustellen, um die Auslastung und Flexibilität zu maximieren.

Karpenter ermöglicht es Workloads, die Art der benötigten Rechenressourcen zu deklarieren, ohne zuerst Knotengruppen erstellen oder Label-Taints für bestimmte Knoten konfigurieren zu müssen. Weitere Informationen finden Sie in den Best Practices von Karpenter. Erwägen Sie, die Konsolidierung in Ihrem Karpenter-Provisioner zu aktivieren, um zu wenig ausgelastete Knoten zu ersetzen.

Automatisieren Sie Amazon Machine Image (AMI) -Updates

Wenn Sie die Worker-Node-Komponenten auf dem neuesten Stand halten, stellen Sie sicher, dass Sie über die neuesten Sicherheitspatches und kompatiblen Funktionen mit der Kubernetes-API verfügen. Die Aktualisierung des Kubelets ist die wichtigste Komponente für die Kubernetes-Funktionalität. Durch die Automatisierung von Betriebssystem-, Kernel- und lokal installierten Anwendungspatches wird jedoch der Wartungsaufwand bei der Skalierung reduziert.

Es wird empfohlen, das neueste Amazon EKS-optimierte Amazon Linux 2 - oder Amazon EKS-optimierte Bottlerocket-AMI für Ihr Node-Image zu verwenden. Karpenter verwendet automatisch das neueste verfügbare AMI, um neue Knoten im Cluster bereitzustellen. Verwaltete Knotengruppen aktualisieren das AMI während eines Knotengruppen-Updates, aber die AMI-ID wird nicht zum Zeitpunkt der Knotenbereitstellung aktualisiert.

Für verwaltete Knotengruppen müssen Sie die Startvorlage für Auto Scaling Group (ASG) mit neuen AMI-IDs aktualisieren, sobald diese für Patch-Releases verfügbar sind. AMI-Nebenversionen (z. B. 1.23.5 bis 1.24.3) werden in der EKS-Konsole und in der API als Upgrades für die Knotengruppe verfügbar sein. Patch-Release-Versionen (z. B. 1.23.5 bis 1.23.6) werden nicht als Upgrades für die Knotengruppen angeboten. Wenn Sie Ihre Knotengruppe über die AMI-Patch-Releases auf dem Laufenden halten möchten, müssen Sie eine neue Launch-Vorlagenversion erstellen und die Node-Gruppe Instances durch die neue AMI-Version ersetzen lassen.

Sie können das neueste verfügbare AMI auf dieser Seite finden oder die AWS-CLI verwenden.

aws ssm get-parameter \
  --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \
  --query "Parameter.Value" \
  --output text

Verwenden Sie mehrere EBS-Volumes für Container

Wichtig

Diese Funktion wird nur auf AL2 unterstützt; auf AL2023 wird sie noch nicht unterstützt.

Für EBS-Volumes gibt es ein Kontingent input/output (I/O), das vom Typ des Volumes (z. B. gp3) und der Größe des Datenträgers abhängt. Wenn Ihre Anwendungen ein einziges EBS-Root-Volume mit dem Host teilen, kann dies das Festplattenkontingent für den gesamten Host erschöpfen und dazu führen, dass andere Anwendungen auf verfügbare Kapazität warten. Anwendungen schreiben auf die Festplatte, wenn sie Dateien auf ihre Overlay-Partition schreiben, ein lokales Volume vom Host aus einbinden und auch, wenn sie sich über Standard Out (STDOUT) abmelden, je nachdem, welcher Logging-Agent verwendet wird.

Um eine Überlastung der I/O Festplatte zu vermeiden, sollten Sie ein zweites Volume in den Container-Status-Ordner mounten (z. B./run/containerd), separate EBS-Volumes für die Workload-Speicherung verwenden und unnötiges lokales Logging deaktivieren.

Um mithilfe von eksctl ein zweites Volume auf Ihren EC2-Instances zu mounten, können Sie eine Knotengruppe mit dieser Konfiguration verwenden:

managedNodeGroups:
  - name: al2-workers
    amiFamily: AmazonLinux2
    desiredCapacity: 2
    volumeSize: 80
    additionalVolumes:
      - volumeName: '/dev/sdz'
        volumeSize: 100
    preBootstrapCommands:
    - |
      "systemctl stop containerd"
      "mkfs -t ext4 /dev/nvme1n1"
      "rm -rf /var/lib/containerd/*"
      "mount /dev/nvme1n1 /var/lib/containerd/"
      "systemctl start containerd"

Wenn Sie Terraform zur Bereitstellung Ihrer Knotengruppen verwenden, sehen Sie sich bitte die Beispiele in EKS Blueprints for Terraform an. Wenn Sie Karpenter zur Bereitstellung von Knoten verwenden, können Sie diese blockDeviceMappings zusammen mit den Node-Benutzerdaten verwenden, um zusätzliche Volumes hinzuzufügen.

Um ein EBS-Volume direkt auf Ihrem Pod zu mounten, sollten Sie den AWS-EBS-CSI-Treiber verwenden und ein Volume mit einer Speicherklasse verwenden.

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-sc
  resources:
    requests:
      storage: 4Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: public.ecr.aws/docker/library/nginx
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-claim

Vermeiden Sie Instances mit niedrigen Grenzwerten für EBS-Anhänge, wenn Workloads EBS-Volumes verwenden

EBS ist eine der einfachsten Möglichkeiten für Workloads, über persistenten Speicher zu verfügen. Allerdings gibt es auch Einschränkungen bei der Skalierbarkeit. Jeder Instanztyp hat eine maximale Anzahl von EBS-Volumes, die angehängt werden können. Workloads müssen angeben, auf welchen Instance-Typen sie ausgeführt werden sollen, und die Anzahl der Replikate auf einer einzelnen Instance mit Kubernetes-Taints begrenzen.

Deaktivieren Sie unnötige Protokollierung auf der Festplatte

Vermeiden Sie unnötige lokale Protokollierung, indem Sie Ihre Anwendungen nicht mit Debug-Protokollierung in der Produktion ausführen und die Protokollierung deaktivieren, die häufig Lese- und Schreibvorgänge auf die Festplatte durchführt. Journald ist der lokale Protokollierungsdienst, der einen Protokollpuffer im Speicher speichert und regelmäßig Daten auf die Festplatte speichert. Journald wird dem Syslog vorgezogen, das jede Zeile sofort auf die Festplatte protokolliert. Die Deaktivierung von Syslog reduziert auch den Gesamtspeicherbedarf und vermeidet komplizierte Regeln für die Protokollrotation. Um Syslog zu deaktivieren, können Sie Ihrer Cloud-Init-Konfiguration das folgende Snippet hinzufügen:

runcmd:
  - [ systemctl, disable, --now, syslog.service ]

Patch-Instanzen, wenn die Geschwindigkeit der Betriebssystemaktualisierung erforderlich ist

Wichtig

Das Patchen vorhandener Instanzen sollte nur durchgeführt werden, wenn dies erforderlich ist. Amazon empfiehlt, die Infrastruktur als unveränderlich zu behandeln und Updates, die in niedrigeren Umgebungen verbreitet werden, auf die gleiche Weise wie Anwendungen gründlich zu testen. Dieser Abschnitt gilt, wenn dies nicht möglich ist.

Es dauert Sekunden, ein Paket auf einem vorhandenen Linux-Host zu installieren, ohne dass die containerisierten Workloads unterbrochen werden. Das Paket kann installiert und validiert werden, ohne dass die Instanz gesperrt, entleert oder ausgetauscht werden muss.

Um eine Instanz zu ersetzen, müssen Sie zunächst neue AMIs erstellen, validieren und verteilen. Für die Instanz muss eine Ersatzinstanz erstellt werden, und die alte Instanz muss abgesperrt und entleert werden. Anschließend müssen Workloads auf der neuen Instanz erstellt, verifiziert und für alle Instanzen, die gepatcht werden müssen, wiederholt werden. Es dauert Stunden, Tage oder Wochen, um Instanzen sicher auszutauschen, ohne die Workloads zu unterbrechen.

Amazon empfiehlt die Verwendung einer unveränderlichen Infrastruktur, die von einem automatisierten, deklarativen System aus erstellt, getestet und gefördert wird. Wenn Sie jedoch Systeme schnell patchen müssen, müssen Sie die vorhandenen Systeme patchen und sie ersetzen, sobald neue AMIs verfügbar sind. Aufgrund des großen Zeitunterschieds zwischen dem Patchen und dem Ersetzen von Systemen empfehlen wir, AWS Systems Manager Patch Manager zu verwenden, um das Patchen von Knoten bei Bedarf zu automatisieren.

Durch das Patchen von Knoten können Sie schnell Sicherheitsupdates bereitstellen und die Instances nach der Aktualisierung Ihres AMI regelmäßig austauschen. Wenn Sie ein Betriebssystem mit einem schreibgeschützten Root-Dateisystem wie Flatcar Container Linux oder Bottlerocket OS verwenden, empfehlen wir, die Update-Operatoren zu verwenden, die mit diesen Betriebssystemen funktionieren. Der Flatcar Linux Update Operator und der Bottlerocket Update Operator starten die Instanzen neu, um die Knoten automatisch auf dem neuesten Stand zu halten.