

 **Unterstützung für die Verbesserung dieser Seite beitragen** 

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.

Um zu diesem Benutzerhandbuch beizutragen, wählen Sie den GitHub ** Link Diese Seite ** bearbeiten unter, der sich im rechten Bereich jeder Seite befindet.

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.

# Amazon EKS-Cluster für AI/ML Workloads mit Terraform einrichten
<a name="ml-cluster-setup-tf"></a>

**Tipp**  
 [Registrieren Sie sich ](https://events.eksworkshop.com/workshops/genai/) für bevorstehende Amazon EKS-Workshops. AI/ML 

Dieser Abschnitt führt Sie durch die Schritte zur Erstellung der Infrastruktur, die für die Ausführung von Schulungs- oder Inferenz-Workloads auf Amazon EKS mithilfe von Terraform erforderlich ist. Zu den Schritten gehören das Erstellen eines EKS-Clusters, GPU-enabled Knoten mit EKS Auto Mode oder Karpenter, ein Monitoring-Stack mit Prometheus und Grafana sowie Amazon S3-Speicher für Modellgewichte.

Weitere Informationen dazu, wie diese Funktionen EC2-Instances in [ EKS-Clustern bereitstellen ](https://docs.aws.amazon.com/eks/latest/userguide/automode.html) und automatisch skalieren, finden Sie in der Dokumentation [ für EKS Auto Mode und ](https://karpenter.sh/docs/) Karpenter.

 **High-level Architektur und Arbeitsablauf ** 

![High-level Architektur, die eine <shared id= zeigt](https://docs.aws.amazon.com/de_de/eks/latest/userguide/images/ml-cluster-setup-tf-architecture.png)


Das Diagramm zeigt die AWS allgemeine Architektur für das Setup dieses Abschnitts.

## Voraussetzungen
<a name="cluster-setup-tf-prerequisites"></a>

**Wichtig**  
Für die Ressourcen, die Sie in diesem Tutorial erstellen, einschließlich EKS-Cluster, GPU-Instances, Application Load Balancers und Amazon Managed Service für Prometheus, fallen Gebühren an. Löschen Sie Ressourcen, wenn Sie fertig sind, um laufende Gebühren zu vermeiden.
+ Terraform >= 1.15.0. Anweisungen zur Einrichtung finden Sie unter Terraform installieren. [https://developer.hashicorp.com/terraform/install](https://developer.hashicorp.com/terraform/install)
+  `kubectl`>= 1.36. Anweisungen zur Einrichtung finden Sie unter. [Richten Sie `kubectl und eksctl ein` ``](install-kubectl.md)
+  AWS CLI >= 2.27. Anweisungen zur Einrichtung finden Sie unter [ Installieren. ](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)
+  `jq`. Anweisungen zur Einrichtung finden Sie unter jq [https://jqlang.github.io/jq/download/](https://jqlang.github.io/jq/download/) herunterladen.

Überprüfen Sie Ihre Toolversionen:

```
terraform --version
aws --version
kubectl version --client
jq --version
```

## Schritt 1: Laden Sie den Terraform-Code herunter und stellen Sie ihn bereit
<a name="cluster-setup-tf-deploy"></a>

In dieser exemplarischen Vorgehensweise wird der Terraform-Code im Beispiel-Repository sample-eks-docs verwendet. [https://github.com/aws-samples/sample-eks-docs](https://github.com/aws-samples/sample-eks-docs) AWS GitHub Klonen Sie das Repository in ein Arbeitsverzeichnis:

```
git clone git@github.com:aws-samples/sample-eks-docs.git
cd sample-eks-docs/ai-ml/set-up-cluster
```

Das Projektarchiv hat die folgende Struktur unter dem `ai-ml/set-up-cluster/` Verzeichnis, in das Sie gerade gewechselt haben:

```
set-up-cluster/
├── scripts/
│   └── cleanup.sh
└── terraform/
    ├── auto-mode/
    └── karpenter/
```

Das Repository bietet zwei Bereitstellungspfade. Wählen Sie nur einen aus und verwenden Sie ihn im gesamten Handbuch.
+  **EKS-Automatikmodus ** (`terraform/auto-mode/`) — Zusätzlich zu den wichtigsten [ Netzwerk-, Speicher- und Load-Balancing-Add-Ons ](https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html#addon-consider-auto) umfasst und verwaltet EKS Auto Mode die folgenden Funktionen für Trainings- und Inferenz-Workloads: EKS-Node-Monitoring-Agent, automatische Node-Reparatur, [https://github.com/awslabs/soci-snapshotter](https://github.com/awslabs/soci-snapshotter) SOCI-Snapshotter für schnelle Container-Pulls und GPU-Bereitschaft für die Standardeinstellung. NodeClass Das NVIDIA-Geräte-Plugin ist im Bottlerocket-beschleunigten AMI enthalten, das EKS Auto Mode für Knoten verwendet. GPU-enabled 
+  **Self-managed Karpenter ** (`terraform/karpenter/`) — Auf einem EKS-Cluster ohne EKS-Auto-Modus installiert und konfiguriert der Terraform-Code die Komponenten, die für Trainings- und Inferenz-Workloads erforderlich sind. Dazu gehören Netzwerk-Add-Ons (VPC CNI, CoreDNS, Kube-Proxy), Karpenter, der EKS-Knotenüberwachungsagent, das NVIDIA-Geräte-Plugin und der SOCI-Snapshotter für schnelle Container-Pulls.

**Wichtig**  
Wählen Sie entweder den EKS-Automodus oder den selbstverwalteten Karpenter aus und verwenden Sie ihn im gesamten Handbuch. Um mitten im Stream zu wechseln, muss der Cluster zerstört und von vorne begonnen werden.

 **EKS-Cluster-Optionen: EKS-Automatikmodus und selbstverwaltetes Karpenter ** 

![Side-by-side Vergleich der beiden Cluster-Optionen: ein EKS-Auto-Mode-Cluster mit einem und ein EKS-Standardcluster mit selbstverwaltetem Karpenter NodePool, CoreDNS, VPC CNI, NVIDIA-Geräte-Plugin, EKS Pod Identity Agent, Node Monitoring Agent, Kube-Proxy und a und NodeClass NodePool](https://docs.aws.amazon.com/de_de/eks/latest/userguide/images/ml-cluster-setup-cli-cluster-options.png)


**Grafana ist öffentlich über HTTP mit Standardanmeldeinformationen zugänglich**  
Die Grafana ALB `Ingress` ist standardmäßig `var.my_cidr` auf eingestellt`0.0.0.0/0`, wodurch Grafana über einfaches HTTP mit Standard-Administratoranmeldedaten dem öffentlichen Internet zugänglich gemacht wird. Automatisierte Scanner erkennen öffentliche Load Balancer innerhalb von Minuten. Sie ** müssen ** den Zugriff einschränken, indem Sie `var.my_cidr` mit Ihrer eigenen IP-Adresse überschreiben:  

```
export MY_CIDR="$(curl -s https://checkip.amazonaws.com)/32"
terraform apply -var "my_cidr=${MY_CIDR}"
```
Behandeln Sie die Quell-IP-Allowlisting als Mindestschutz, nicht als vollständigen Schutz. Ändern Sie auch das Standard-Grafana-Admin-Passwort nach der ersten Anmeldung. Für eine stärkere Haltung ändern Sie das `alb.ingress.kubernetes.io/scheme` auf `internal` (nur von Ihrer VPC oder einem verbundenen VPN aus erreichbar) und fügen Sie ein TLS-Zertifikat hinzu.

### Bereitstellen des Clusters
<a name="_deploy_the_cluster"></a>

Wechseln Sie in das Verzeichnis für den von Ihnen gewählten Pfad, initialisieren Sie Terraform und wenden Sie Folgendes an:

Beide Varianten verwenden standardmäßig die Region. `us-east-2` Um in einer anderen Region bereitzustellen, fügen Sie `-var "region={{region-code}}"` dem `terraform apply` Befehl im folgenden Schritt hinzu, in {{region-code}} welcher AWS Region Sie die Bereitstellung durchführen möchten.

Der Terraform-Code verwendet alle verfügbaren Availability Zones in der Zielregion, mit Ausnahme von `use1-az3``usw1-az2`, und `cac1-az3` weil [ Amazon EKS die Platzierung von Kontrollebenen in diesen Zonen nicht unterstützt. ](https://repost.aws/knowledge-center/eks-cluster-creation-errors)

------
#### [ EKS Auto Mode ]

```
cd terraform/auto-mode
terraform init
terraform apply
```

Die Ausführung dieses Befehls dauert einige Minuten.

------
#### [ Self-managed Karpenter ]

```
cd terraform/karpenter
terraform init
terraform apply
```

Dieser Befehl dauert etwa 15 Minuten. Es erstellt einen EKS-Cluster mit einer verwalteten Knotengruppe, die dem Hosten von Add-Ons und dem Karpenter Controller gewidmet ist. Terraform installiert Karpenter, wobei die Spot-Unterbrechungswarteschlange aktiviert ist und die Feature-Gates aktiviert sind. `NodeRepair` `StaticCapacity` Es installiert auch das NVIDIA-Geräte-Plugin, den Load AWS Balancer Controller und den Monitoring-Stack.

------

### Überprüfen Sie die Terraform-Ausgaben
<a name="_review_the_terraform_outputs"></a>

Wenn der Antrag abgeschlossen ist, druckt Terraform die folgenden Ausgaben aus (die Werte variieren je nach Ihrer Konfiguration):

```
Apply complete! Resources: 74 added, 0 changed, 0 destroyed.

Outputs:

cluster_name         = "ai-eks-docs"
configure_kubectl    = "aws eks update-kubeconfig --region us-east-2 --name ai-eks-docs --alias ai-eks-docs"
configure_model_bucket = "export MODEL_BUCKET=ai-eks-docs-models-20250612abc1"
model_bucket         = "ai-eks-docs-models-20250612abc1"
node_iam_role_name   = "ai-eks-docs-eks-auto-20250612..."
region               = "us-east-2"
```

Die `configure_kubectl` Ausgabe ist ein ausführbarer Befehl, der auf den Cluster verweist`kubectl`. Die `model_bucket` Ausgabe enthält den S3-Bucket-Namen für Modellgewichte. Die `node_iam_role_name` Ausgabe zeigt die IAM-Rolle, die Knoten verwenden.

### Konfigurieren Sie kubectl
<a name="_configure_kubectl"></a>

Zeigen `kubectl` Sie auf den neuen Cluster. Die `configure_kubectl` Ausgabe ist ein sofort ausführbarer Befehl:

```
eval "$(terraform output -raw configure_kubectl)"
```

### Überprüfen Sie den Cluster
<a name="_verify_the_cluster"></a>

------
#### [ EKS Auto Mode ]

```
kubectl get pods --all-namespaces
```

Erwartete Ausgabe:

```
NAMESPACE     NAME                                                       READY   STATUS    RESTARTS   AGE
kube-system   metrics-server-5db89f9ffd-h4mlr                            1/1     Running   0          3m
kube-system   metrics-server-5db89f9ffd-nd748                            1/1     Running   0          3m
monitoring    kube-prometheus-stack-grafana-ff9b5fd57-dh562              3/3     Running   0          3m
monitoring    kube-prometheus-stack-kube-state-metrics-5dcbfdf69b-wd6qn  1/1     Running   0          3m
monitoring    kube-prometheus-stack-operator-548c4f4485-m5wh2            1/1     Running   0          3m
monitoring    kube-prometheus-stack-prometheus-node-exporter-p2z7l       1/1     Running   0          3m
monitoring    prometheus-kube-prometheus-stack-prometheus-0              2/2     Running   0          3m
```

Im EKS-Automatikmodus werden VPC-CNI, Kube-Proxy und CoreDNS als verwaltete Komponenten ausgeführt und erscheinen nicht als Pods in. `kube-system`

------
#### [ Self-managed Karpenter ]

```
kubectl get pods --all-namespaces
```

Zu den erwarteten Ausgaben gehören Karpenter, CoreDNS, Kube-Proxy, aws-node (VPC CNI), der EKS Pod Identity Agent, der EKS Node Monitoring Agent und das NVIDIA-Geräte-Plugin:

```
NAMESPACE     NAME                                                              READY   STATUS    RESTARTS   AGE
kube-system   aws-node-bzdcz                                                    2/2     Running   0          5m
kube-system   aws-node-vkbhb                                                    2/2     Running   0          5m
kube-system   coredns-7dbb8998cf-9b9wk                                          1/1     Running   0          5m
kube-system   coredns-7dbb8998cf-pwtjd                                          1/1     Running   0          5m
kube-system   ebs-csi-controller-748f54b69-8h7jv                                6/6     Running   0          5m
kube-system   ebs-csi-controller-748f54b69-v2mv8                                6/6     Running   0          5m
kube-system   eks-node-monitoring-agent-5qw4l                                   1/1     Running   0          5m
kube-system   eks-node-monitoring-agent-7lrtm                                   1/1     Running   0          5m
kube-system   eks-pod-identity-agent-ddvlv                                      1/1     Running   0          5m
kube-system   eks-pod-identity-agent-q4g29                                      1/1     Running   0          5m
kube-system   karpenter-898ff78-cndbd                                           1/1     Running   0          5m
kube-system   karpenter-898ff78-hfbhn                                           1/1     Running   0          5m
kube-system   kube-proxy-gcfnh                                                  1/1     Running   0          5m
kube-system   kube-proxy-tktcf                                                  1/1     Running   0          5m
kube-system   metrics-server-5b789db597-cm9qd                                   1/1     Running   0          5m
kube-system   metrics-server-5b789db597-w57b6                                   1/1     Running   0          5m
kube-system   nvidia-device-plugin-node-feature-discovery-gc-66cb7f5dc-xvftc    1/1     Running   0          5m
kube-system   nvidia-device-plugin-node-feature-discovery-master-854d6b5hnqtp   1/1     Running   0          5m
monitoring    kube-prometheus-stack-grafana-6797bcb59f-2zlwg                    3/3     Running   0          5m
monitoring    kube-prometheus-stack-kube-state-metrics-8446bd549c-q6gjc         1/1     Running   0          5m
monitoring    kube-prometheus-stack-operator-5f499b784-vf5xb                    1/1     Running   0          5m
monitoring    kube-prometheus-stack-prometheus-node-exporter-4c6wq              1/1     Running   0          5m
monitoring    kube-prometheus-stack-prometheus-node-exporter-l5t25              1/1     Running   0          5m
monitoring    prometheus-kube-prometheus-stack-prometheus-0                     2/2     Running   0          5m
```

Stellen Sie sicher, dass das NVIDIA-Geräte-Plugin installiert ist. Es werden keine Geräte-Plug-In-Pods angezeigt, bis eine GPU NodePool mit dem passenden `amiFamily=al2023` Label bereitgestellt wird:

```
kubectl get daemonset nvidia-device-plugin -n kube-system
```

Erwartete Ausgabe:

```
NAME                   DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR      AGE
nvidia-device-plugin   0         0         0       0            0           amiFamily=al2023   5m
```

------

## Schritt 2: Dynamische GPU erstellen NodePool
<a name="cluster-setup-tf-create-gpu-nodepool"></a>

GPU NodePools sind optional. `terraform apply`Erstellt standardmäßig den Cluster und den Monitoring-Stack ohne GPU-Kapazität und ohne GPU-Abrechnung. Um GPU-Knoten bereitzustellen, übergeben Sie die `nodepools` Variable mit einem Strategienamen.

Aktivieren Sie die `spot-ondemand` Strategie, die G-family GPU-Instances mit einer Generation von mehr als 4 bereitstellt, und verwenden Sie Spot-Kapazität mit On-Demand als Fallback:

```
terraform apply -var 'nodepools={"spot-ondemand"={}}'
```

Mit diesem Befehl werden die NodeClass Vorlagen NodePool und aus dem `nodepools/spot-ondemand/` Verzeichnis angewendet. Beide Pfade verwenden dieselbe NodePool API, unterscheiden sich jedoch in NodeClass den NodePool Referenzen.

------
#### [ EKS Auto Mode ]

Die NodePool Referenzen sind das Managed `default` NodeClass, das bereits das Bottlerocket Accelerated AMI, die NVIDIA-Treiber, das NVIDIA-Geräte-Plugin und SOCI Parallel Pull auswählt. Die `spot-ondemand` Strategie eignet sich nicht NodeClass von selbst für diesen Weg.

Bestätigen Sie NodePool:

```
kubectl get nodepools,nodeclasses
```

Erwartete Ausgabe. Das `gpu-inf` NodePool verknüpft das integrierte `general-purpose` und `system` NodePools, und alle drei verweisen auf das verwaltete `default` NodeClass:

```
NAME                                    NODECLASS   NODES   READY   AGE
nodepool.karpenter.sh/general-purpose   default     0       True    12m
nodepool.karpenter.sh/gpu-inf           default     0       True    20s
nodepool.karpenter.sh/system            default     1       True    12m

NAME                                  ROLE                       READY   AGE
nodeclass.eks.amazonaws.com/default   ai-eks-docs-eks-auto-...   True    12m
```

------
#### [ Self-managed Karpenter ]

Terraform wendet `gpu-inf` `EC2NodeClass` neben dem einen benutzerdefinierten Wert an. NodePool Der `EC2NodeClass` pinnt den EKS-optimized AL2023 AMI-Alias, aktiviert SOCI über das `FastImagePull` Feature Gate und legt fest, dass der enthaltene Image-Cache `instanceStorePolicy: RAID0` auf das lokale NVMe verschoben wird.

Validieren Sie das und: NodePool EC2NodeClass

```
kubectl get nodepools,ec2nodeclasses
```

Erwartete Ausgabe. Das `gpu-inf` Paar schließt sich dem an `general-purpose` NodePool und EC2NodeClass , das Terraform für Nicht-GPU-Workloads erstellt:

```
NAME                                    NODECLASS         NODES   READY   AGE
nodepool.karpenter.sh/general-purpose   general-purpose   1       True    14m
nodepool.karpenter.sh/gpu-inf           gpu-inf           0       True    25s

NAME                                             READY   AGE
ec2nodeclass.karpenter.k8s.aws/general-purpose   True    14m
ec2nodeclass.karpenter.k8s.aws/gpu-inf           True    25s
```

------

Beide Pfade zeigen `0` Knoten an, `gpu-inf` bis ein GPU-Workload geplant ist. EKS Auto Mode und Karpenter starten Knoten nur, wenn ausstehende Pods sie benötigen.

## Schritt 3: Testen Sie mit einem Beispiel-Pod
<a name="cluster-setup-tf-test-with-a-sample-pod"></a>

Testen Sie Ihr NodePool GPU-Setup mit einem `nvidia-smi` Pod:

```
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: nvidia-smi
  labels:
    guide: ai-eks-docs
spec:
  restartPolicy: OnFailure
  tolerations:
    - key: "nvidia.com/gpu"
      operator: "Exists"
      effect: "NoSchedule"
  containers:
    - name: nvidia-smi
      image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
      command: ["nvidia-smi"]
      resources:
        limits:
          nvidia.com/gpu: 1
EOF
```

Stellen Sie sicher, dass der Pod geplant und erfolgreich abgeschlossen ist:

```
kubectl get pods nvidia-smi
```

Erwartete Ausgabe:

```
NAME         READY   STATUS      RESTARTS   AGE
nvidia-smi   0/1     Completed   0          67s
```

Das `STATUS: Completed` bedeutet, dass der `nvidia-smi` Befehl ausgeführt und beendet wurde. Sehen Sie in den Pod-Protokollen nach, welche GPU vom Knoten erkannt wurde:

```
kubectl logs nvidia-smi
```

Erwartete Ausgabe:

```
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.159.03             Driver Version: 580.159.03     CUDA Version: 13.0     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA L4                      On  |   00000000:31:00.0 Off |                    0 |
| N/A   41C    P8             13W /   72W |       0MiB /  23034MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
```

Die Ausgabe zeigt das GPU-Modell, die Treiberversion, die CUDA-Version und den verfügbaren Speicher. In diesem Beispiel hat Karpenter eine G6-Instanz bereitgestellt, die über eine NVIDIA L4-GPU mit 24 GB Arbeitsspeicher verfügt. Das GPU-Modell und der Arbeitsspeicher variieren je nach dem Instanztyp, den Karpenter auswählt. G5-Instances haben NVIDIA A10G-GPUs (24 GB), G6-Instances haben NVIDIA L4-GPUs (24 GB) und G6e-Instanzen haben NVIDIA L40S-GPUs (48 GB).

Um zu verstehen, wie Karpenter und der Kubernetes-Scheduler die Bereitstellung eines Knotens und die Platzierung des Pods koordiniert haben, schauen Sie sich die Lebenszyklus-Ereignisse des Pods an:

```
kubectl describe pod nvidia-smi
```

Erwartete Ausgabe:

```
Events:
  Type     Reason            Age   From                   Message
  ----     ------            ----  ----                   -------
  Warning  FailedScheduling  75s   default-scheduler      0/2 nodes are available: 2 node(s) had untolerated taint(s).
  Normal   Nominated         74s   eks-auto-mode/compute  Pod should schedule on: nodeclaim/gpu-inf-z6q75
  Normal   Scheduled         35s   default-scheduler      Successfully assigned default/nvidia-smi to i-0eb897a8302551589
  Normal   Pulling           27s   kubelet                spec.containers{nvidia-smi}: Pulling image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal"
  Normal   Pulled            22s   kubelet                spec.containers{nvidia-smi}: Successfully pulled image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal" in 5.625s (5.626s including waiting). Image size: 37440620 bytes.
  Normal   Created           22s   kubelet                spec.containers{nvidia-smi}: Container created
  Normal   Started           21s   kubelet                spec.containers{nvidia-smi}: Container started
```

Diese Ereignisse zeigen die Reihenfolge der Pod-Planung: Der Pod kann zunächst nicht geplant werden, weil keine GPU-Knoten vorhanden sind (`FailedScheduling`), Karpenter nominiert einen neuen NodeClaim (`Nominated`), der Scheduler weist den Pod zu, sobald der Knoten bereit ist (`Scheduled`), und dann wird das Container-Image abgerufen und gestartet. Im EKS-Auto-Modus ist SOCI (Seekable OCI) Parallel-Pull standardmäßig auf G-, P- und Trn-Instances installiert und konfiguriert, und der selbstverwaltete Karpenter-Pfad konfiguriert ihn explizit über das `FastImagePull` Feature Gate.

**Anmerkung**  
Auf einem selbstverwalteten Karpenter-Cluster wird das Ereignis anstelle von angezeigt. `Nominated` `karpenter/compute` `eks-auto-mode/compute`

A NodeClaim ist eine Anfrage, die Karpenter erstellt, um einen bestimmten Knoten bereitzustellen. Es zeigt den Instanztyp, den Kapazitätstyp, AZ und ob der Knoten bereit ist:

```
kubectl get nodeclaims
```

Erwartete Ausgabe:

```
NAME            TYPE        CAPACITY   ZONE         NODE                  READY   AGE
gpu-inf-z6q75   g6.xlarge   spot       us-east-2a   i-0eb897a8302551589   True    5m
```

Der Instanztyp und AZ variieren. Jede G-family Instance mit einer Generation von mehr als 4 ist berechtigt.

**Tipp**  
Wenn kein Knoten angezeigt wird, suchen Sie nach Fehlern bei unzureichender Kapazität:  

```
kubectl get events | grep InsufficientCapacityError
```
Karpenter speichert nicht verfügbare Angebote 3 Minuten lang im Cache. Wenn Sie die zulässigen Instance-Typen und AZs in Ihrem System erweitern, NodePool erhöhen Sie die Wahrscheinlichkeit, dass Ihnen Kapazitäten zur Verfügung stehen.

**Anmerkung**  
Spot-Instances, die von Karpenter gestartet wurden, werden nicht in der EC2 Spot Requests Console angezeigt. Karpenter verwendet die EC2-API [`CreateFleet`](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateFleet.html) mit. `type: instant` Die Instances werden in der EC2-Instanzen-Konsole mit einem Lebenszyklus angezeigt. `spot`

## Schritt 4: Fügen Sie reservierte Kapazität zur hinzu NodePool (optional)
<a name="cluster-setup-tf-attach-odcr"></a>

Während die GPU NodePool aus Schritt 2 Spot oder On-Demand Instances dynamisch bereitstellt, ist in einigen Anwendungsfällen eine garantierte Kapazität erforderlich. Sie können eine On-Demand Kapazitätsreservierung (ODCR) erstellen, um sicherzustellen, dass die GPU-Kapazität bei Bedarf verfügbar ist.

Bei Terraform erstellt ein einziger Befehl den ODCR, einen benutzerdefinierten NodeClass Wert, der die Reservierung anhand von Tags referenziert, und aktualisiert ihn, sodass er `reserved` als NodePool Kapazitätstyp aufgenommen wird. Terraform taggt das ODCR mit `nodepool=reserved-spot-ondemand` und wählt es dann anhand dieses Tags aus NodeClass .

**Warnung**  
Mit dem folgenden Befehl wird ein ODCR erstellt, das sofort fakturiert wird, und setzt die Abrechnung fort, bis Sie es mit `terraform destroy` oder dem Bereinigungsskript löschen, unabhängig davon, ob Knoten darauf laufen oder nicht.

Verwenden Sie Standardwerte (`g6e.4xlarge`, 1 Instanz, erster Cluster AZ):

```
terraform apply -var 'nodepools={"reserved-spot-ondemand"={reservation={}}}'
```

Wählen Sie den Instanztyp, die Anzahl und die AZ aus:

```
terraform apply -var 'nodepools={"reserved-spot-ondemand"={reservation={instance_type="g6e.2xlarge",instance_count=1,az="us-east-2a"}}}'
```

Das `reservation` Objekt unterstützt die folgenden Felder:
+  `instance_type`— Der zu reservierende GPU-Instanztyp. Standard: `g6e.4xlarge`.
+  `instance_count`— Die Anzahl der zu reservierenden Instanzen. Standard: `1`.
+  `az`— Die Availability Zone für die Reservierung. Standard: `""` (verwendet den ersten Cluster AZ).

**Wichtig**  
Die `reserved-spot-ondemand` Strategien `spot-ondemand` und schließen sich gegenseitig aus. Sie können höchstens eine in der `nodepools` Variablen aktivieren. Wenn Sie ihn zuvor `spot-ondemand` in Schritt 2 verwendet haben, wird er durch den `reserved-spot-ondemand` Befehl ersetzt, da beide dasselbe verwalten `gpu-inf` NodePool.

Wenn Sie eine `InsufficientInstanceCapacity` Fehlermeldung erhalten, kann die Reservierung in der angegebenen AZ nicht erfüllt werden. Brechen Sie den Terraform-Vorgang ab (Strg\+C) und führen Sie ihn erneut mit einem anderen Wert aus: `az`

```
terraform apply -var 'nodepools={"reserved-spot-ondemand"={reservation={instance_type="g6e.4xlarge",az="us-east-2b"}}}'
```

Nach der Anwendung aktualisiert Terraform die Anforderungen, um den Kapazitätstyp NodePool einzubeziehen`reserved`, und in den Kapazitätstyp `spot` einzubeziehen. `on-demand` Karpenter betrachtet es als die kostengünstigste Option `reserved` und bringt sie als erstes auf den Markt. Sobald die Reservierung vollständig ist, fällt sie auf Spot oder zurück. On-Demand

Auf dem EKS-Automodus-Pfad erstellt Terraform ein benutzerdefiniertes Objekt `gpu-inf` NodeClass (da das Paket schreibgeschützt `default` NodeClass ist), das das ODCR per Tag-through referenziert. `capacityReservationSelectorTerms` Auf dem selbstverwalteten Karpenter-Pfad wendet Terraform das mit hinzugefügtem Element erneut an und aktualisiert es auf Include. `gpu-inf` EC2NodeClass `capacityReservationSelectorTerms` NodePool `reserved`

Stellen Sie sicher, dass das ODCR erstellt wurde:

```
aws ec2 describe-capacity-reservations \
  --filters "Name=state,Values=active" "Name=tag:nodepool,Values=reserved-spot-ondemand" \
  --query 'CapacityReservations[0].{Id:CapacityReservationId,State:State,InstanceType:InstanceType,AvailableCount:AvailableInstanceCount}' \
  --output table \
  --region $(terraform output -raw region)
```

Überprüfen Sie, ob die NodeClass ODCR referenziert wird:

------
#### [ EKS Auto Mode ]

```
kubectl get nodeclasses gpu-inf -o yaml | grep 'id: cr-.*'
```

Erwartete Ausgabe:

```
        id: cr-xxxxxxxxxxxxxxxxx
```

------
#### [ Self-managed Karpenter ]

```
kubectl get ec2nodeclasses gpu-inf -o yaml | grep 'id: cr-.*'
```

Erwartete Ausgabe:

```
        id: cr-xxxxxxxxxxxxxxxxx
```

------

Stellen Sie sicher, NodePool dass der bereit ist:

```
kubectl get nodepools gpu-inf
```

Erwartete Ausgabe:

```
NAME      NODECLASS   NODES   READY   AGE
gpu-inf   gpu-inf     0       True    30s
```

### Stellen Sie mit Spot-Fallback sicher, dass die reservierte Kapazität zuerst genutzt wird
<a name="cluster-setup-tf-step4-validate"></a>

Nachdem Sie die Änderungen übernommen haben, überprüfen Sie, ob Karpenter der reservierten Kapazität Priorität einräumt und auf Spot oder zurückgreift. On-Demand Stellen Sie eine Bereitstellung mit 2 Replikaten bereit, die 1 GPU pro Pod anfordert. Der ODCR gilt für eine Instance (1 GPU), sodass der erste Pod Karpenter veranlasst, einen reservierten Knoten zu starten. Der zweite Pod passt nicht auf den reservierten Knoten und veranlasst Karpenter, einen weiteren Knoten von Spot oder Kapazität aus zu starten. On-Demand 

```
cat << 'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gpu-overflow-test
  labels:
    guide: ai-eks-docs
spec:
  replicas: 2
  selector:
    matchLabels:
      app: gpu-overflow-test
  template:
    metadata:
      labels:
        app: gpu-overflow-test
        guide: ai-eks-docs
    spec:
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      containers:
        - name: nvidia-smi
          image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
          command: ["sh", "-c", "nvidia-smi && sleep infinity"]
          resources:
            limits:
              nvidia.com/gpu: 1
EOF
```

Im Gegensatz zum `nvidia-smi` Test-Pod aus Schritt 3, der ausgeführt und beendet wurde, hält dieses Deployment die Pods am Laufen (`sleep infinity`), sodass sie die GPU enthalten und verhindern, dass der Knoten konsolidiert wird.

Überprüfen Sie, ob die Pods auf verschiedenen Knoten geplant sind:

```
kubectl get pods -l app=gpu-overflow-test -o wide
```

Erwartete Ausgabe:

```
NAME                                 READY   STATUS    RESTARTS   AGE     IP            NODE                  NOMINATED NODE   READINESS GATES
gpu-overflow-test-55d55ff5b9-dvg52   1/1     Running   0          4m42s   10.0.75.210   i-08741a36089ff2088   <none>           <none>
gpu-overflow-test-55d55ff5b9-hw4m9   1/1     Running   0          4m43s   10.0.82.49    i-0f50cdbacb2017202   <none>           <none>
```

Überprüfen Sie das NodeClaims , um die Kapazitätstypen zu sehen:

```
kubectl get nodeclaims
```

Erwartete Ausgabe:

```
NAME            TYPE          CAPACITY   ZONE         NODE                  READY   AGE
gpu-inf-vw99m   g6e.4xlarge   reserved   us-east-2c   i-0f50cdbacb2017202   True    6m
gpu-inf-s65s6   g6.xlarge     spot       us-east-2b   i-08741a36089ff2088   True    5m59s
```

Der reservierte Knoten wurde zuerst gestartet, gefolgt von einem Spot oder On-Demand Knoten, sobald die Reservierung vollständig war.

Bereinigen Sie die Testbereitstellung:

```
kubectl delete deployment gpu-overflow-test
```

## Überwachen
<a name="cluster-setup-tf-monitoring"></a>

Terraform hat bereits in Schritt 1 den gesamten Monitoring-Stack bereitgestellt`terraform apply`. Der Stack umfasst einen Amazon Managed Service for Prometheus (AMP) -Workspace, IAM-Richtlinien und EKS-Pod Identity Associations für Prometheus-Fernschreib- und Grafana-Abfragezugriff, das Kube-Prometheus-Stack-Helm-Diagramm (Prometheus, Grafana, kube-state-metrics, node-exporter) und den NVIDIA DCGM Exporter für GPU-Metriken.

In diesem Abschnitt wird die Überprüfung der eingesetzten Überwachungskomponenten behandelt.

### Überprüfen Sie die Monitoring-Pods
<a name="_verify_monitoring_pods"></a>

Warten Sie, bis alle Monitoring-Pods bereit sind:

```
kubectl wait --for=condition=Ready pod --all -n monitoring --timeout=300s
kubectl get pods -n monitoring
```

Erwartete Ausgabe:

```
NAME                                                       READY   STATUS    RESTARTS   AGE
kube-prometheus-stack-grafana-7c58f54f77-rftrj             3/3     Running   0          5m
kube-prometheus-stack-kube-state-metrics-d68dcbc84-5smxq   1/1     Running   0          5m
kube-prometheus-stack-operator-5895df479f-ttm47            1/1     Running   0          5m
kube-prometheus-stack-prometheus-node-exporter-t9q7s       1/1     Running   0          5m
kube-prometheus-stack-prometheus-node-exporter-x6vfb       1/1     Running   0          5m
prometheus-kube-prometheus-stack-prometheus-0              2/2     Running   0          5m
```

### Greifen Sie auf Grafana zu
<a name="cluster-setup-tf-grafana"></a>

Grafana wird über einen mit dem Internet verbundenen AWS Application Load Balancer (ALB) verfügbar gemacht, der auf den von Ihnen eingestellten CIDR beschränkt ist. `var.my_cidr` Drucken Sie die Load Balancer-URL aus (warten Sie ein oder zwei Minuten, bis der ALB die Bereitstellung abgeschlossen hat):

```
echo "http://$(kubectl get ingress kube-prometheus-stack-grafana -n monitoring -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
```

Öffnen Sie die URL in Ihrem Browser. Loggen Sie sich mit dem Benutzernamen `admin` und dem Passwort aus dem folgenden Befehl ein:

```
kubectl --namespace monitoring get secrets kube-prometheus-stack-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo
```

### Überprüfen Sie die Metrik-Pipeline
<a name="_verify_the_metrics_pipeline"></a>

Gehen Sie wie folgt vor, um zu überprüfen, ob die Metrik-Pipeline durchgängig funktioniert:

1. Navigieren Sie zu ** Verbindungen > Datenquellen ** und bestätigen Sie, dass dies als Standarddatenquelle aufgeführt ** Amazon-Managed-Prometheus ** ist.

    **Validieren Sie die AMP-Datenquelle in Grafana **   
![Die Seite „Grafana-Verbindungen“ wird als Amazon-Managed-Prometheus Standarddatenquelle aufgeführt](https://docs.aws.amazon.com/de_de/eks/latest/userguide/images/ml-cluster-setup-cli-prometheus-ds-validate.png)

1. Navigieren Sie zu ** Drilldown > Metriken ** und suchen Sie nach der Metrik. `up` Sie sollten Ergebnisse aus den Scrape-Zielen Ihres Clusters sehen.

    **Validieren Sie die `up` Metrik in Grafana **   
![Seite mit Grafana-Drilldown-Metriken, auf der die Aufwärtsmetrik mit grünen Statusleisten angezeigt wird, die auf aktive Scrape-Ziele hinweisen](https://docs.aws.amazon.com/de_de/eks/latest/userguide/images/ml-cluster-setup-cli-prometheus-metrics-validate.png)

Wenn Ergebnisse `up` angezeigt werden, funktioniert die Pipeline (Cluster → Prometheus → AMP → Grafana).

### Validieren Sie DCGM-GPU-Metriken
<a name="_validate_dcgm_gpu_metrics"></a>

Der DCGM-Exporter DaemonSet wird auf GPU-Knoten ausgeführt und meldet GPU-Auslastung, Speicher, Temperatur, Stromverbrauch, NVLink-Bandbreite und Tensor-Aktivitätsmetriken.

Überprüfen Sie den DCGM-Exporter: DaemonSet

```
kubectl get daemonset dcgm-exporter -n monitoring
```

Sobald ein GPU-Knoten läuft (ab Schritt 2 oder Schritt 4), sollten Sie einen oder mehrere bereite Pods sehen. Um DCGM-Metriken zu validieren, navigieren Sie ** in Grafana zu ** Drilldown > Metriken und suchen Sie nach. `DCGM_`

 **Validieren Sie die DCGM-Metriken in Grafana ** 

![Die nach DCGM_ gefilterte Seite mit Grafana-Drilldown-Metriken zeigt GPU-Metriken wie DCGM_FI_DEV_ECC_SBE_VOL_TOTAL, DCGM_FI_DEV_ENC_UTIL, DCGM_FI_DEV_FB_FREE und DCGM_FI_DEV_FB_USED](https://docs.aws.amazon.com/de_de/eks/latest/userguide/images/ml-cluster-setup-cli-dcgm-metrics-validate.png)


Um das Dashboard ** anzuzeigen, navigieren Sie zu Dashboards > GPU-Überwachung > NVIDIA DCGM Exporter-Dashboard. **

 **Das NVIDIA DCGM Exporter-Dashboard in Grafana ** 

![Das Grafana NVIDIA DCGM Exporter-Dashboard zeigt die Panels GPU-Auslastung, GPU Avg Temp, GPU-Framebuffer Mem Used und GPU Power Total](https://docs.aws.amazon.com/de_de/eks/latest/userguide/images/ml-cluster-setup-cli-dcgm-dashboard.png)


## Das Modell wiegt den S3-Eimer
<a name="cluster-setup-tf-model-bucket"></a>

Terraform hat bereits einen Amazon S3-Bucket zum Speichern von Modellgewichten erstellt, einen `model-storage-sa` ServiceAccount im `default` Namespace, eine IAM-Richtlinie für den Bucket und eine EKS Pod Identity Association, die sie verknüpft. Workload-Pods, die festgelegt sind, `serviceAccountName: model-storage-sa` können aus dem Bucket lesen und in den Bucket schreiben.

### Überprüfen Sie den Bucket
<a name="_verify_the_bucket"></a>

Rufen Sie den Bucket-Namen aus den Terraform-Ausgaben ab:

```
MODEL_BUCKET=$(terraform output -raw model_bucket)
echo ${MODEL_BUCKET}
```

Stellen Sie sicher, dass der Bucket existiert:

```
aws s3api head-bucket --bucket ${MODEL_BUCKET}
```

Erwartete Ausgabe:

```
{
    "BucketArn": "arn:aws:s3:::ai-eks-docs-models-20250612abc1",
    "BucketRegion": "us-east-2",
    "AccessPointAlias": false
}
```

#### Validieren Sie den S3-Zugriff von einem Pod aus
<a name="cluster-setup-tf-s3-validate"></a>

Führen Sie einen einmaligen Pod mit dem AWS CLI-Image aus und verwenden Sie dabei den, um zu bestätigen `model-storage-sa` ServiceAccount, dass EKS Pod Identity verkabelt ist und der S3-Zugriff funktioniert:

```
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: s3-test
  labels:
    guide: ai-eks-docs
spec:
  serviceAccountName: model-storage-sa
  containers:
    - name: aws-cli
      image: public.ecr.aws/aws-cli/aws-cli:2.27.0
      command:
        - sh
        - -c
        - |
          echo "=== Caller Identity ==="
          aws sts get-caller-identity
          echo ""
          echo "=== S3 Write Test ==="
          echo "pod identity works" | aws s3 cp - s3://${MODEL_BUCKET}/test.txt
          echo ""
          echo "=== S3 List Test ==="
          aws s3 ls s3://${MODEL_BUCKET}/
          echo ""
          echo "=== S3 Delete Test ==="
          aws s3 rm s3://${MODEL_BUCKET}/test.txt
  restartPolicy: Never
EOF
```

Warten Sie, bis der Pod fertig ist, und überprüfen Sie die Protokolle:

```
kubectl wait --for=jsonpath='{.status.phase}'=Succeeded pod/s3-test --timeout=300s
kubectl logs s3-test
```

Erwartete Ausgabe:

```
=== Caller Identity ===
{
    "UserId": "AROA...:eks-ai-eks-docs-model-s-...",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/ai-eks-docs-models-.../eks-ai-eks-docs-..."
}

=== S3 Write Test ===
upload: - to s3://ai-eks-docs-models-20250612abc1/test.txt

=== S3 List Test ===
2026-07-15 12:00:00         19 test.txt

=== S3 Delete Test ===
delete: s3://ai-eks-docs-models-20250612abc1/test.txt
```

Die Identität des Anrufers bestätigt, dass der Pod über EKS Pod Identity die Rolle des Modellspeichers übernommen hat. Die S3-Befehle bestätigen den Lese- und Schreibzugriff.

Bereinigen Sie den Test-Pod:

```
kubectl delete pod s3-test
```

## Nächste Schritte
<a name="cluster-setup-tf-next-steps"></a>

Wenn Ihr Cluster bereit ist, können Sie mit [ Load & Serve Model fortfahren](ml-inference-load-serve-model.md), um ein umfangreiches Sprachmodell bereitzustellen und mit dem Inferenzendpunkt zu interagieren.

## Bereinigen
<a name="cluster-setup-tf-cleanup"></a>

**Tipp**  
Wenn Sie mit den nächsten Abschnitten dieses Handbuchs fortfahren möchten, überspringen Sie die vollständige Bereinigung. Führen Sie es erst aus, wenn Sie fertig sind.

Löschen Sie die Test-Workloads, sodass keine Pods GPU-Knoten enthalten:

```
kubectl delete pod nvidia-smi --ignore-not-found
kubectl delete deployment gpu-overflow-test --ignore-not-found
```

### Stornieren Sie die Kapazitätsreservierung, ohne den Cluster zu zerstören
<a name="cluster-setup-tf-cleanup-cancel-reservation"></a>

Wenn Sie nur den ODCR veröffentlichen und auf Spot und On-Demand Kapazität zurückgreifen möchten, stellen Sie die `nodepools` Variable wieder auf die `spot-ondemand` Strategie um:

```
terraform apply -var 'nodepools={"spot-ondemand"={}}'
```

Dadurch fallen die Anforderungen `reserved` an den NodePool Kapazitätstyp weg und das ODCR wird zerstört. Der Cluster, der Monitoring-Stack und der S3-Bucket bleiben unverändert.

**Wichtig**  
Durch das Stornieren einer Reservierung werden Instances, die bereits auf dieser Reservierung ausgeführt werden, nicht beendet. Diese Instances laufen zu On-Demand Standardtarifen weiter, bis sie beendet werden. Löschen Sie zuerst die GPU-Workloads, wie oben gezeigt, damit der reservierte Knoten leer wird, bevor die Reservierung freigegeben wird.

### Zerstören Sie den Cluster und alle Ressourcen Terraform-managed
<a name="cluster-setup-tf-cleanup-destroy"></a>

Entleeren Sie die Karpenter-managed Knoten, bevor Sie sie zerstören, sodass kein laufender Knotenlebenszyklus die Zerstörung blockiert. Löschen Sie alle PodDisruptionBudgets Elemente, die einen Drain verhindern würden, und löschen Sie dann: NodeClaims

```
kubectl delete pdb -A --all --ignore-not-found
kubectl delete nodeclaim --all --wait=true --timeout=900s
```

Zerstören Sie dann alles, was Terraform erstellt hat, einschließlich des EKS-Clusters, der VPC, des Monitoring-Stacks, des NodePools und NodeClasses, des S3-Modell-Buckets und aller ODCR:

```
terraform destroy
```

**Warnung**  
Das Modellgewicht, mit dem der S3-Bucket erstellt wurde`force_destroy = true`, `terraform destroy` löscht also den Bucket zusammen mit allen Modellgewichten, die Sie darauf hochgeladen haben. Kopieren Sie zuerst alles, was Sie behalten möchten, an einen anderen Ort.

**Anmerkung**  
Das Repository enthält auch ein `scripts/cleanup.sh` Hilfsprogramm, das die oben genannten Schritte Drain und Destroy ausführt und dann alle verwaisten EBS-Volumes, die mit dem Clusternamen markiert sind, entfernt. Führen Sie es in dem `terraform/<mode>/` Verzeichnis aus, aus dem Sie sich beworben haben, und geben Sie den Befehl ein, um die `--auto-approve` Terraform-Bestätigungsaufforderung zu überspringen.

### Stellen Sie sicher, dass die Reservierung weg ist
<a name="cluster-setup-tf-cleanup-verify"></a>

Vergewissern Sie sich, dass für den Cluster keine aktive Kapazitätsreservierung mehr vorhanden ist:

```
aws ec2 describe-capacity-reservations \
  --filters "Name=state,Values=active" "Name=tag:nodepool,Values=reserved-spot-ondemand" \
  --query 'CapacityReservations[].CapacityReservationId' \
  --output text
```

Ein leeres Ergebnis bedeutet, dass keine Reservierung aktiv ist und keine weiteren Gebühren anfallen.