View a markdown version of this page

Configura il cluster Amazon EKS per i AI/ML carichi di lavoro utilizzando Terraform - Amazon EKS

Contribuisci a migliorare questa pagina

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Per contribuire a questa guida per l'utente, scegli il GitHub link Modifica questa pagina su che si trova nel riquadro destro di ogni pagina.

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Configura il cluster Amazon EKS per i AI/ML carichi di lavoro utilizzando Terraform

Suggerimento

Registrati per i prossimi workshop Amazon EKS. AI/ML

Questa sezione illustra i passaggi per creare l'infrastruttura necessaria per eseguire carichi di lavoro di formazione o inferenza su Amazon EKS utilizzando Terraform. I passaggi includono la creazione di un cluster EKS, GPU-enabled nodi con EKS Auto Mode o Karpenter, uno stack di monitoraggio con Prometheus e Grafana e lo storage Amazon S3 per i pesi dei modelli.

Consulta la documentazione per EKS Auto Mode e Karpenter per ulteriori informazioni su come queste funzionalità forniscono e scalano automaticamente le istanze EC2 nei cluster EKS.

High-level architettura e flusso di lavoro

High-level architettura che mostra un <shared id=

Il diagramma mostra l'architettura AWS di alto livello per la configurazione di questa sezione.

Prerequisiti

Importante

Le risorse create in questo tutorial, tra cui cluster EKS, istanze GPU, Application Load Balancer e Amazon Managed Service for Prometheus, sono a pagamento. Elimina le risorse quando hai finito per evitare addebiti continui.

Verifica le versioni dei tuoi strumenti:

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

Passaggio 1: scarica e distribuisci il codice Terraform

Questa procedura dettagliata utilizza il codice Terraform nel repository sample-eks-docs Samples. AWS GitHub Clona il repository in una directory di lavoro:

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

Il repository ha la seguente struttura ai-ml/set-up-cluster/ nella directory in cui hai appena cambiato:

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

Il repository fornisce due percorsi di distribuzione. Scegline solo uno e utilizzalo in tutta la guida.

  • EKS Auto Mode (terraform/auto-mode/) — Oltre ai principali componenti aggiuntivi di rete, storage e bilanciamento del carico, EKS Auto Mode include e gestisce le seguenti funzionalità per l'addestramento e l'inferenza dei carichi di lavoro: agente di monitoraggio dei nodi EKS, riparazione automatica dei nodi, snapshotter SOCI per una rapida estrazione dei container e predisposizione della GPU per l'impostazione predefinita. NodeClass Il plug-in per dispositivi NVIDIA è incluso nell'AMI accelerata Bottlerocket che EKS Auto Mode utilizza per i nodi. GPU-enabled

  • Self-managed Karpenter (terraform/karpenter/) — Su un cluster EKS senza EKS Auto Mode, il codice Terraform installa e configura i componenti necessari per i carichi di lavoro di addestramento e inferenza. Ciò include componenti aggiuntivi di rete (VPC CNI, CoreDNS, kube-proxy), Karpenter, l'agente di monitoraggio dei nodi EKS, il plug-in per dispositivi NVIDIA e lo snapshotter SOCI per richiamare rapidamente i container.

Importante

Scegli EKS Auto Mode o Karpenter autogestito e usalo in tutta la guida. Il passaggio a metà flusso richiede la distruzione del cluster e il riavvio da capo.

Opzioni del cluster EKS: EKS Auto Mode e Karpenter autogestito

Side-by-side confronto delle due opzioni di cluster: un cluster EKS Auto Mode con un e un cluster standard EKS con Karpenter NodePool, CoreDNS, VPC CNI autogestiti, plug-in per dispositivi NVIDIA, agente EKS Pod Identity, Node Monitoring Agent, kube-proxy e un e NodeClass NodePool
Grafana è accessibile pubblicamente tramite HTTP con credenziali predefinite

L'Ingressimpostazione predefinita di Grafana ALB è0.0.0.0/0, che espone Grafana var.my_cidr alla rete Internet pubblica tramite un semplice HTTP con credenziali di amministratore predefinite. Gli scanner automatici scoprono i sistemi di bilanciamento del carico pubblici in pochi minuti. È necessario limitare l'accesso sovrascrivendo il proprio var.my_cidr indirizzo IP:

export MY_CIDR="$(curl -s https://checkip.amazonaws.com)/32" terraform apply -var "my_cidr=${MY_CIDR}"

Considera l'elenco degli indirizzi IP di origine come una protezione minima, non completa. Cambia anche la password amministratore predefinita di Grafana dopo il primo accesso. Per una postura più sicura, modifica l'alb.ingress.kubernetes.io/schemeimpostazione internal (raggiungibile solo dall'interno del tuo VPC o da una VPN connessa) e aggiungi un certificato TLS.

Distribuzione del cluster

Entra nella directory del percorso scelto, inizializza Terraform e applica:

Entrambe le varianti utilizzano per impostazione predefinita la regione. us-east-2 Per eseguire la distribuzione in una regione diversa, aggiungi -var "region=region-code" al terraform apply comando nel passaggio successivo, region-code dov'è la AWS regione in cui desideri eseguire la distribuzione.

Il codice Terraform utilizza tutte le zone di disponibilità disponibili nella regione di destinazione use1-az3usw1-az2, escluse e cac1-az3 perché Amazon EKS non supporta il posizionamento dei piani di controllo in quelle zone.

EKS Auto Mode
cd terraform/auto-mode terraform init terraform apply

Il completamento di questo comando richiede alcuni minuti.

Self-managed Karpenter
cd terraform/karpenter terraform init terraform apply

Questo comando richiede circa 15 minuti. Crea un cluster EKS con un gruppo di nodi gestiti dedicato all'hosting di componenti aggiuntivi e il controller Karpenter. Terraform installa Karpenter con la coda di interruzione Spot abilitata e i gate delle funzionalità e attivati. NodeRepair StaticCapacity Installa anche il plug-in del dispositivo NVIDIA, il Load Balancer Controller e lo AWS stack di monitoraggio.

Esamina gli output di Terraform

Al termine dell'applicazione, Terraform stampa i seguenti output (i valori variano in base alla configurazione):

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"

L'configure_kubectloutput è un comando pronto per l'esecuzione che punta al cluster. kubectl L'model_bucketoutput contiene il nome del bucket S3 per i pesi del modello. L'node_iam_role_nameoutput mostra il ruolo IAM utilizzato dai nodi.

Configura kubectl

Indicate il kubectl nuovo cluster. L'configure_kubectloutput è un comando pronto per l'esecuzione:

eval "$(terraform output -raw configure_kubectl)"

Verifica il cluster

EKS Auto Mode
kubectl get pods --all-namespaces

Output previsto:

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

In EKS Auto Mode, VPC CNI, kube-proxy e CoreDNS vengono eseguiti come componenti gestiti e non vengono visualizzati come pod in. kube-system

Self-managed Karpenter
kubectl get pods --all-namespaces

L'output previsto include Karpenter, CoreDNS, kube-proxy, aws-node (VPC CNI), EKS Pod Identity Agent, l'agente di monitoraggio dei nodi EKS e il plug-in per i dispositivi NVIDIA:

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

Verifica che il plug-in del dispositivo NVIDIA sia installato. Zero Device Plugin Pod viene visualizzato finché non viene fornita una GPU NodePool con l'amiFamily=al2023etichetta corrispondente:

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

Output previsto:

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

Passaggio 2: crea una GPU dinamica NodePool

Le GPU NodePools sono attivate. Per impostazione predefinita, terraform apply crea il cluster e lo stack di monitoraggio senza capacità GPU e senza fatturazione GPU. Per eseguire il provisioning dei nodi GPU, passate la nodepools variabile con un nome di strategia.

Attivate la spot-ondemand strategia, che prevede il provisioning di istanze G-family GPU con una generazione superiore a 4, utilizzando la capacità Spot con On-Demand come riserva:

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

Questo comando applica i NodeClass modelli NodePool e contenuti nella directory. nodepools/spot-ondemand/ Entrambi i percorsi utilizzano la stessa NodePool API, ma differiscono NodeClass nei NodePool riferimenti.

EKS Auto Mode

Fanno NodePool riferimento a managed default NodeClass, che già seleziona l'AMI accelerata Bottlerocket, i driver NVIDIA, il plug-in del dispositivo NVIDIA e il pull parallelo SOCI. La spot-ondemand strategia non si prefigge di per sé questa strada. NodeClass

Convalida: NodePool

kubectl get nodepools,nodeclasses

Output previsto. I gpu-inf NodePool join incorporati e tutti general-purpose e system NodePools tre fanno riferimento al gestore: 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 applica una personalizzazione gpu-inf EC2NodeClass insieme a. NodePool Inserisce EC2NodeClass l'alias AMI EKS-optimized AL2023, abilita SOCI attraverso il FastImagePull feature gate e imposta lo spostamento della cache delle immagini contenuta instanceStorePolicy: RAID0 su NVMe locali.

Convalida la e: NodePool EC2NodeClass

kubectl get nodepools,ec2nodeclasses

Output previsto. La gpu-inf coppia si unisce alla band creata da Terraform per carichi di lavoro non GPU: general-purpose NodePool EC2NodeClass

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

Entrambi i percorsi mostrano i 0 nodi gpu-inf fino alla pianificazione del carico di lavoro della GPU. EKS Auto Mode e Karpenter avviano i nodi solo quando i Pod in sospeso li richiedono.

Fase 3: Esegui il test con un Pod di esempio

Verifica la NodePool configurazione della GPU con un 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

Verifica che il Pod sia pianificato e completato correttamente:

kubectl get pods nvidia-smi

Output previsto:

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

Indica STATUS: Completed che il nvidia-smi comando è stato eseguito ed è terminato. Controlla i log del Pod per vedere la GPU rilevata dal nodo:

kubectl logs nvidia-smi

Output previsto:

+-----------------------------------------------------------------------------------------+
| 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 |
+-----------------------------------------+------------------------+----------------------+

L'output mostra il modello della GPU, la versione del driver, la versione CUDA e la memoria disponibile. In questo esempio, Karpenter ha effettuato il provisioning di un'istanza G6 con una GPU NVIDIA L4 con 24 GB di memoria. Il modello e la memoria della GPU variano a seconda del tipo di istanza selezionato da Karpenter. Le istanze G5 hanno GPU NVIDIA A10G (24 GB), le istanze G6 hanno GPU NVIDIA L4 (24 GB) e le istanze G6e hanno GPU NVIDIA L40S (48 GB).

Per capire come Karpenter e lo scheduler Kubernetes si sono coordinati per fornire un nodo e posizionare il Pod, controlla gli eventi del ciclo di vita del Pod:

kubectl describe pod nvidia-smi

Output previsto:

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

Questi eventi mostrano la sequenza di pianificazione del Pod: il Pod inizialmente non riesce a pianificare perché non esistono nodi GPU (FailedScheduling), Karpenter ne nomina un nuovo (), lo scheduler assegna il Pod una volta che il nodo è pronto NodeClaim (Nominated), quindi l'immagine del contenitore viene estratta e avviata. Scheduled EKS Auto Mode ha il pull parallelo SOCI (Seekable OCI) installato e configurato di default sulle istanze G, P e Trn e il percorso Karpenter autogestito lo configura esplicitamente tramite il FastImagePull feature gate.

Nota

In un cluster Karpenter autogestito, l'evento viene visualizzato al posto di. Nominated karpenter/compute eks-auto-mode/compute

A NodeClaim è una richiesta creata da Karpenter per eseguire il provisioning di un nodo specifico. Mostra il tipo di istanza, il tipo di capacità, l'AZ e se il nodo è pronto:

kubectl get nodeclaims

Output previsto:

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

Il tipo di istanza e l'AZ variano. Qualsiasi G-family istanza con una generazione superiore a 4 è idonea.

Suggerimento

Se non viene visualizzato alcun nodo, verifica la presenza di errori di capacità insufficiente:

kubectl get events | grep InsufficientCapacityError

Karpenter memorizza nella cache le offerte non disponibili per 3 minuti. L'ampliamento dei tipi di istanze e degli AZ consentiti NodePool aumenta le possibilità di atterraggio.

Nota

Le istanze Spot lanciate da Karpenter non vengono visualizzate nella console Spot Requests di EC2. Karpenter utilizza l'API EC2 CreateFleet con. type: instant Le istanze vengono visualizzate nella console EC2 Instances con un ciclo di vita. spot

Fase 4: Aggiungere capacità riservata a (opzionale) NodePool

Sebbene la GPU della Fase 2 NodePool esegua il provisioning di Spot o On-Demand delle istanze in modo dinamico, alcuni casi d'uso richiedono una capacità garantita. Puoi creare un On-Demand Capacity Reservation (ODCR) per assicurarti che la capacità della GPU sia disponibile quando necessario.

Con Terraform, un singolo comando crea l'ODCR, una personalizzazione NodeClass che fa riferimento alla prenotazione per tag e lo aggiorna NodePool per includerlo reserved come tipo di capacità. Terraform contrassegna l'ODCR con nodepool=reserved-spot-ondemand e poi lo NodeClass seleziona in base a quel tag.

avvertimento

Il comando seguente crea un ODCR che viene fatturato immediatamente e continua a fatturare finché non viene distrutto con terraform destroy o con lo script di pulizia, indipendentemente dal fatto che i nodi siano in esecuzione o meno.

Usa i valori predefiniti (g6e.4xlarge, 1 istanza, primo cluster AZ):

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

Scegli il tipo di istanza, il numero e la AZ:

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

L'reservationoggetto supporta i seguenti campi:

  • instance_type— Il tipo di istanza GPU da prenotare. Default: g6e.4xlarge.

  • instance_count— Il numero di istanze da prenotare. Default: 1.

  • az— La zona di disponibilità per la prenotazione. Predefinito: "" (utilizza il primo cluster AZ).

Importante

Le reserved-spot-ondemand strategie spot-ondemand e si escludono a vicenda. Puoi abilitarne al massimo una nella nodepools variabile. Se in precedenza lo si utilizzava spot-ondemand nel passaggio 2, il reserved-spot-ondemand comando lo sostituisce perché entrambi gestiscono la stessa cosa gpu-inf NodePool.

Se si InsufficientInstanceCapacity verifica un errore, la prenotazione non può essere soddisfatta nell'AZ specificato. Annulla l'operazione Terraform (Ctrl+C), quindi eseguila nuovamente con un valore diverso: az

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

Dopo l'applicazione, Terraform li aggiorna NodePool per includerereserved, e nei requisiti relativi al tipo di spot capacità. on-demand Karpenter considera l'opzione più conveniente e reserved la lancia per prima. Una volta completata, la prenotazione torna a Spot o. On-Demand

Nel percorso EKS Auto Mode, Terraform crea un codice personalizzato gpu-inf NodeClass (perché il pacchetto default NodeClass è di sola lettura) che fa riferimento all'ODCR tramite tag. capacityReservationSelectorTerms Sul percorso Karpenter autogestito, Terraform riapplica le impostazioni aggiunte e le aggiorna per includere. gpu-inf EC2NodeClass capacityReservationSelectorTerms NodePool reserved

Verifica che l'ODCR sia stato creato:

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)

Verifica i NodeClass riferimenti all'ODCR:

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

Output previsto:

id: cr-xxxxxxxxxxxxxxxxx
Self-managed Karpenter
kubectl get ec2nodeclasses gpu-inf -o yaml | grep 'id: cr-.*'

Output previsto:

id: cr-xxxxxxxxxxxxxxxxx

Verifica che NodePool sia pronto:

kubectl get nodepools gpu-inf

Output previsto:

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

Dopo aver applicato le modifiche, verifica che Karpenter dia la priorità alla capacità riservata e ritorni a Spot o. On-Demand Implementa una distribuzione con 2 repliche che richiede 1 GPU per pod. L'ODCR è per 1 istanza (1 GPU), quindi il primo Pod attiva Karpenter per avviare un nodo riservato. Il secondo Pod non può essere inserito nel nodo riservato e fa sì che Karpenter avvii un altro nodo da Spot o Capacity. 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

A differenza del Pod di nvidia-smi test di Step 3, che è stato eseguito e chiuso, questo Deployment mantiene i Pod in funzione (sleep infinity) in modo da trattenere la GPU e impedire il consolidamento del nodo.

Verifica i Pod pianificati su diversi nodi:

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

Output previsto:

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>

Controlla NodeClaims per vedere i tipi di capacità:

kubectl get nodeclaims

Output previsto:

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

Il nodo riservato viene avviato per primo, seguito da uno Spot o da un On-Demand nodo una volta completata la prenotazione.

Pulisci la distribuzione di prova:

kubectl delete deployment gpu-overflow-test

Monitoraggio

Terraform ha già fornito l'intero stack di monitoraggio durante la fase 1terraform apply. Lo stack include uno spazio di lavoro Amazon Managed Service for Prometheus (AMP), policy IAM e EKS Pod Identity Associations per l'accesso alla scrittura remota e alle query Grafana di Prometheus, il grafico Helm kube-prometheus-stack (Prometheus, Grafana, kube-state-metrics, node-exporter) e NVIDIA DCGM Exporter per le metriche GPU.

Questa sezione riguarda la verifica dei componenti di monitoraggio implementati.

Verifica i pod di monitoraggio

Attendi che tutti i pod di monitoraggio siano pronti:

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

Output previsto:

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

Accedi a Grafana

Grafana è esposta tramite un AWS Application Load Balancer (ALB) connesso a Internet, limitato al CIDR impostato. var.my_cidr Stampa l'URL del load balancer (attendi uno o due minuti per il provisioning dell'ALB):

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

Apri l'URL nel tuo browser. Accedi con nome utente admin e password con il seguente comando:

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

Verifica la pipeline delle metriche

Per verificare che la pipeline delle metriche funzioni integralmente:

  1. Vai a Connessioni > Origini dati e conferma che Amazon-Managed-Prometheus sia elencato come origine dati predefinita.

    Convalida l'origine dati AMP in Grafana

    La pagina Grafana Connections viene visualizzata come origine dati Amazon-Managed-Prometheus predefinita
  2. Vai a Drilldown > Metriche e cerca la metrica. up Dovresti vedere i risultati degli obiettivi di scrape del tuo cluster.

    Convalida la up metrica in Grafana

    Pagina Grafana Drilldown Metrics che mostra la metrica up con barre di stato verdi che indicano gli obiettivi di scrape attivi

Se up vengono visualizzati i risultati, la pipeline (cluster → Prometheus → AMP → Grafana) funziona.

Convalida le metriche della GPU DCGM

Il DCGM Exporter DaemonSet funziona su nodi GPU e riporta le metriche relative all'utilizzo della GPU, alla memoria, alla temperatura, al consumo energetico, alla larghezza di banda NVLink e all'attività tensoriale.

Verifica l'esportatore DCGM: DaemonSet

kubectl get daemonset dcgm-exporter -n monitoring

Una volta che un nodo GPU è in esecuzione (dal passaggio 2 o dal passaggio 4), dovresti vedere uno o più pod pronti. Per convalidare le metriche DCGM, accedi a Drilldown > Metrics in Grafana e cerca. DCGM_

Convalida le metriche DCGM in Grafana

Pagina Grafana Drilldown Metrics filtrata da DCGM_ che mostra le metriche GPU tra cui DCGM_FI_DEV_ECC_SBE_VOL_TOTAL, DCGM_FI_DEV_ENC_UTIL, DCGM_FI_DEV_DEV_FB_FREE e DCGM_FI_DEV_FB_USED

Per visualizzare la dashboard, vai su Dashboard > Monitoraggio GPU > NVIDIA DCGM Exporter Dashboard.

Dashboard di NVIDIA DCGM Exporter a Grafana

Grafana NVIDIA DCGM Exporter Dashboard che mostra l'utilizzo della GPU, la temperatura media della GPU, il framebuffer della GPU Mem usato e i pannelli GPU Power Total

Il modello pesa un secchio S3

Terraform ha già creato un bucket Amazon S3 per memorizzare i pesi dei modelli, uno model-storage-sa ServiceAccount nel default namespace, una policy IAM con ambito per il bucket e un'EKS Pod Identity Association che li collega. I Workload Pod impostati possono leggere e scrivere nel bucket. serviceAccountName: model-storage-sa

Verifica il bucket

Recupera il nome del bucket dagli output di Terraform:

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

Verifica che il bucket esista:

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

Output previsto:

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

Esegui un Pod singolo con l'immagine AWS CLI, utilizzando model-storage-sa ServiceAccount, per confermare che EKS Pod Identity sia cablato e che l'accesso S3 funzioni:

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

Attendi il completamento del Pod e controlla i log:

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

Output previsto:

=== 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

L'identità del chiamante conferma che il Pod ha assunto il ruolo di archiviazione del modello tramite EKS Pod Identity. I comandi S3 confermano l'accesso in lettura e scrittura.

Pulisci il pod di prova:

kubectl delete pod s3-test

Fasi successive

Con il cluster pronto, puoi passare a Load & Serve Model per implementare un modello linguistico di grandi dimensioni e interagire con l'endpoint di inferenza.

Pulizia

Suggerimento

Se intendi continuare con le sezioni successive di questa guida, salta la pulizia completa. Eseguila solo quando hai finito.

Elimina i carichi di lavoro di test in modo che nessun Pod contenga nodi GPU:

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

Se desideri solo rilasciare l'ODCR e tornare a Spot e On-Demand capacity, riporta la nodepools variabile alla spot-ondemand strategia:

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

Questo riduce reserved i requisiti relativi al NodePool tipo di capacità, distrugge l'ODCR e lascia il cluster, lo stack di monitoraggio e il bucket S3 al loro posto.

Importante

L'annullamento di una prenotazione non comporta la chiusura delle istanze già in esecuzione su di essa. Tali istanze continuano a funzionare alle On-Demand tariffe standard fino alla loro chiusura. Elimina prima i carichi di lavoro della GPU, come mostrato sopra, in modo che il nodo riservato si esaurisca prima del rilascio della prenotazione.

Svuota i Karpenter-managed nodi prima di distruggerli, in modo che nessun ciclo di vita in corso blocchi la distruzione. Elimina quelli PodDisruptionBudgets che potrebbero impedire un drenaggio, quindi elimina: NodeClaims

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

Quindi distruggi tutto ciò che Terraform ha creato, incluso il cluster EKS, il VPC, lo stack di monitoraggio, l' NodePools and NodeClasses, il bucket del modello S3 e qualsiasi ODCR:

terraform destroy
avvertimento

Il bucket S3 è stato creato con i pesi del modelloforce_destroy = true, quindi terraform destroy elimina il bucket insieme a tutti i pesi del modello che hai caricato su di esso. Copia prima tutto ciò che desideri conservare in un'altra posizione.

Nota

Il repository fornisce anche un scripts/cleanup.sh helper che esegue i passaggi di drenaggio e distruzione precedenti e quindi analizza tutti i volumi EBS orfani contrassegnati con il nome del cluster. Eseguilo dall'interno della terraform/<mode>/ directory da cui hai fatto la domanda e passa a saltare la richiesta di conferma --auto-approve di Terraform.

Conferma che non rimanga alcuna prenotazione di capacità attiva per il cluster:

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

Un risultato vuoto significa che nessuna prenotazione è attiva e non si applicano ulteriori costi.