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, mit denen Kunden konfrontiert sind, da es sich um Cluster mit mehreren Workloads handelt. Es gibt keine one-size-fits Komplettlösung. Im Folgenden finden Sie einige Tipps, mit denen Sie häufig auftretende Fallstricke bei der Skalierung von Rechenleistung vermeiden können.

Automatische Knotenskalierung

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

Verwaltete Knotengruppen bieten Ihnen die Flexibilität von Amazon EC2 Auto Scaling 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-Workload-nativer Node-Autoscaler. Er skaliert Knoten in einem Cluster auf der Grundlage der Arbeitslastanforderungen für Ressourcen (z. B. GPU) sowie von Verschmutzungen und Toleranzen (z. B. Zonenverteilung), ohne Knotengruppen zu verwalten. Knoten werden direkt auf dieser Grundlage erstellt EC2 , wodurch Standardquoten für Knotengruppen — 450 Knoten pro Gruppe — vermieden werden. Dies ermöglicht eine größere Flexibilität bei der Instanzauswahl bei geringerem Betriebsaufwand. Wir empfehlen Kunden, wenn möglich, Karpenter zu verwenden.

Verwenden Sie viele verschiedene Instanztypen EC2

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

Karpenter verwendet standardmäßig eine Vielzahl kompatibler Instance-Typen und wählt zum Zeitpunkt der Bereitstellung eine Instanz auf der Grundlage der ausstehenden Workload-Anforderungen, der Verfügbarkeit und der 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 eine ähnliche Größe haben, damit sie konsistent skaliert werden können. Sie sollten mehrere Gruppen basierend auf der CPU- und Speichergröße erstellen und diese unabhängig voneinander skalieren. Verwenden Sie den ec2-instance-selector, um Instances mit ähnlicher Größe für Ihre Knotengruppen zu identifizieren.

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 Instance-Typen verwendet werden sollen, belasten weniger große Knoten die Kubernetes-Steuerebene, da weniger Kubelets laufen. DaemonSets Große Knoten können jedoch möglicherweise nicht wie kleinere Knoten vollständig genutzt werden. Die Knotengröße sollte 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 beschränkt. Wenn Ihre Pods jeweils 4 Kerne verwenden, ist dies möglicherweise zu erwarten (4 Kerne x 110 = 440 Kerne/Knoten). Bei einem Cluster mit 3 Knoten wäre Ihre Fähigkeit, einen Instance-Vorfall zu bewältigen, gering, da sich der Ausfall einer Instanz auf 1/3 des Clusters auswirken 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 benötigten Ressourcen und die erforderliche Verfügbarkeit anhand von Taints, Toleranzen und definieren. PodTopologySpread Sie sollten die größten Knoten bevorzugen, die voll ausgelastet werden können und die Verfügbarkeitsziele erfüllen, um die Auslastung 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 erfordert.

Um zu erzwingen, dass sich Workloads mit dem Scheduler verteilen und neue Knoten auf mehrere Availability Zones erstellt werden, sollten Sie Folgendes verwenden: topologySpreadConstraints

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 eine vorhersehbare Skalierung zu ermöglichen. Ein Workload, der 500 Millionen CPUs anfordert, wird auf einer Instanz mit 4 Kernen anders abschneiden als auf einer Instanz 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 auf bestimmte Instanzgrößen abzuzielen.

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

Workloads, die in einem Cluster mit dem Kubernetes Cluster Autoscaler geplant werden, sollten basierend auf dem Label-Abgleich einen Knotenselektor 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

Verwenden Sie Rechenressourcen effizient

Zu den Rechenressourcen gehören EC2 Instanzen und Verfügbarkeitszonen. Die effektive Nutzung von Rechenressourcen erhöht Ihre Skalierbarkeit, Verfügbarkeit und Leistung und senkt Ihre Gesamtkosten. In einer Autoscaling-Umgebung mit mehreren Anwendungen ist es äußerst schwierig, eine effiziente Ressourcennutzung vorherzusagen. Karpenter wurde für die On-Demand-Bereitstellung von Instanzen auf der Grundlage der Workload-Anforderungen entwickelt, um die Auslastung und Flexibilität zu maximieren.

Karpenter ermöglicht es Workloads, die Art der benötigten Rechenressourcen zu deklarieren, ohne zuerst Knotengruppen zu erstellen oder Label-Taints für bestimmte Knoten zu konfigurieren. Weitere Informationen finden Sie in den Best Practices von Karpenter. Erwägen Sie, die Konsolidierung in Ihrem Karpenter Provisioner zu aktivieren, um unterausgelastete 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 der Kubernetes-Funktionalität. Durch die Automatisierung von Betriebssystem-, Kernel- und lokal installierten Anwendungspatches wird der Wartungsaufwand bei der Skalierung jedoch reduziert.

Es wird empfohlen, das neueste für 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, aktualisieren die AMI-ID jedoch nicht zum Zeitpunkt der Knotenbereitstellung.

Für verwaltete Knotengruppen müssen Sie die Startvorlage für Auto Scaling Group (ASG) mit neuen AMIs aktualisieren, IDs sobald diese für Patch-Versionen verfügbar sind. AMI-Nebenversionen (z. B. 1.23.5 bis 1.24.3) werden in der EKS-Konsole und 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 mit AMI-Patch-Releases auf dem neuesten Stand halten möchten, müssen Sie eine neue Version der Startvorlage erstellen und die Knotengruppe 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

EBS-Volumes verfügen über ein input/output (I/O-) Kontingent, das auf dem Volumetyp (z. B. gp3) und der Größe der Festplatte basiert. Wenn sich Ihre Anwendungen ein einzelnes EBS-Root-Volume mit dem Host teilen, kann dies das Festplattenkontingent für den gesamten Host erschöpfen und andere Anwendungen dazu veranlassen, auf verfügbare Kapazität zu warten. Anwendungen schreiben auf die Festplatte, wenn sie Dateien auf ihre Overlay-Partition schreiben, ein lokales Volume vom Host mounten und je nach verwendetem Logging-Agent auch, wenn sie sich bei der Standardausgabe (STDOUT) anmelden.

Um eine Überlastung der I/O Festplatte zu vermeiden, sollten Sie ein zweites Volume in den Container-State-Ordner einhängen (z. B. /run/containerd), separate EBS-Volumes als Workload-Speicher verwenden und unnötiges lokales Logging deaktivieren.

Um mithilfe von eksctl ein zweites Volume in Ihre EC2 Instances einzubinden, 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 die Beispiele in EKS Blueprints for Terraform an. Wenn Sie Karpenter zur Bereitstellung von Knoten verwenden, können Sie diese blockDeviceMappingszusammen mit Knoten-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 EBS-Attach-Limits, wenn Workloads EBS-Volumes verwenden

EBS ist eine der einfachsten Möglichkeiten, Workloads persistenten Speicher zur Verfügung zu stellen, bringt aber auch Einschränkungen bei der Skalierbarkeit mit sich. Jeder Instance-Typ 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ötiges Logging 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, bei der häufig gelesen und auf die Festplatte geschrieben wird. Journald ist der lokale Protokollierungsdienst, der einen Protokollpuffer im Speicher hält und in regelmäßigen Abständen auf die Festplatte leert. Journald wird Syslog vorgezogen, das jede Zeile sofort auf der Festplatte protokolliert. Die Deaktivierung von Syslog senkt auch den Gesamtspeicherbedarf und vermeidet komplizierte Regeln für die Protokollrotation. Um Syslog zu deaktivieren, können Sie Ihrer Cloud-Init-Konfiguration den folgenden Ausschnitt hinzufügen:

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

Vorhandene Patch-Instanzen, wenn die Geschwindigkeit des Betriebssystem-Updates erforderlich ist

Wichtig

Vorhandene Instanzen sollten nur dann gepatcht werden, wenn dies erforderlich ist. Amazon empfiehlt, die Infrastruktur als unveränderlich zu behandeln und Updates, die in niedrigeren Umgebungen verbreitet werden, genauso gründlich zu testen wie Anwendungen. Dieser Abschnitt gilt, wenn dies nicht möglich ist.

Die Installation eines Pakets auf einem vorhandenen Linux-Host dauert Sekunden, ohne Container-Workloads zu unterbrechen. Das Paket kann installiert und validiert werden, ohne die Instanz zu sperren, zu entleeren oder zu ersetzen.

Um eine Instanz zu ersetzen, müssen Sie zunächst eine neue Instanz erstellen, validieren und verteilen. AMIs Für die Instanz muss ein Ersatz 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 zu ersetzen, ohne die Workloads zu unterbrechen.

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

Durch das Patchen von Knoten können Sie schnell Sicherheitsupdates bereitstellen und die Instances nach einem regelmäßigen Zeitplan austauschen, nachdem Ihr AMI aktualisiert wurde. Wenn Sie ein Betriebssystem mit einem schreibgeschützten Root-Dateisystem wie Flatcar Container Linux oder Bottlerocket OS verwenden, empfehlen wir die Verwendung der Update-Operatoren, 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.