View a markdown version of this page

Configura il cluster Amazon EKS per i AI/ML carichi di lavoro utilizzando le CLI - 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 le CLI

Suggerimento

https://events.eksworkshop.com/workshops/genai/Registrati AI/ML per i prossimi workshop Amazon EKS.

Questa sezione illustra i passaggi per creare l'infrastruttura necessaria per eseguire carichi di lavoro di formazione o inferenza su Amazon EKS tramite comandi CLI. 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 il cluster EKS con Karpenter NodeClass e lo stack di monitoraggio Grafana e NodePool Prometheus che scrive su Amazon Managed Service per Prometheus, un bucket Amazon S3 per i pesi dei modelli e le fasi numerate del flusso di lavoro

Il AWS diagramma mostra l'architettura di alto livello per la configurazione di questa sezione. I passaggi numerati sulla destra indicano l'ordine in cui si completa la configurazione nei passaggi seguenti.

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 la tua eksctl versione:

eksctl version

Se utilizzi una versione precedente alla 0.227.0, segui la guida all'installazione di eksctl per eseguire l'aggiornamento alla versione più recente.

Impostazione delle variabili di ambiente

Mantieni coerenti il nome e la AWS regione del cluster seguenti durante questi passaggi. La modifica può far sì che i comandi successivi indirizzino il cluster EKS sbagliato.

export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2

L'utilizzo di tutte le AZ disponibili migliora la tolleranza ai guasti e aumenta le possibilità di ottenere la capacità della GPU:

export AZS=$(aws ec2 describe-availability-zones \ --region ${AWS_REGION} \ --query "AvailabilityZones[?ZoneId!='use1-az3' && ZoneId!='usw1-az2' && ZoneId!='cac1-az3'].ZoneName" \ --output text | tr '\t' ',') echo $AZS
Importante

Le zone use1-az3 di disponibilità e cac1-az3 sono escluse perché Amazon EKS non supporta il posizionamento dei piani di controllo in tali zone. usw1-az2 La creazione di un cluster con sottoreti in una di queste zone comporta un. UnsupportedAvailabilityZoneException

Output previsto:

us-east-2a,us-east-2b,us-east-2c

Gli AZ nell'output varieranno in base alla regione. Questo esempio mostra gli AZ disponibili per la us-east-2 regione.

Crea cluster e GPU NodePool

Questa sezione fornisce due percorsi per creare il cluster e i GPU-enabled nodi EKS, mostrati nel diagramma seguente. Scegli una sola opzione in tutta la guida.

  • EKS 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 del dispositivo NVIDIA è incluso nell'AMI accelerata Bottlerocket che EKS Auto Mode utilizza per i nodi. GPU-enabled

  • Self-managed Karpenter — Su un cluster EKS senza EKS Auto Mode, sei responsabile dell'installazione e della configurazione dei 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.

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

In ognuno dei passaggi seguenti, scegli un percorso (EKS Auto Mode, Karpenter) e seguilo per tutto il tempo. Dopo aver completato i passaggi per il percorso scelto, avrai un cluster EKS con una GPU NodePool pronto per pianificare i carichi di lavoro della GPU.

Fase 1: Creazione del cluster

Inizia creando il tuo cluster EKS e installando i componenti del cluster necessari per i carichi di lavoro della GPU.

Con EKS Auto Mode, un singolo eksctl create cluster --enable-auto-mode comando esegue il provisioning di un cluster EKS pronto per i carichi di lavoro della GPU.

Con Karpenter autogestito, il eksctl create cluster comando fornisce i componenti aggiuntivi di rete principali, quindi sono necessari passaggi aggiuntivi per abilitare la riparazione automatica dei nodi tramite un feature gate di Karpenter, installare l'agente di monitoraggio dei nodi EKS e installare il plug-in del dispositivo NVIDIA.

EKS Auto Mode

Crea il cluster EKS Auto Mode

eksctl create cluster \ --name=$CLUSTER_NAME \ --region=$AWS_REGION \ --enable-auto-mode \ --version=1.36 \ --zones=$AZS

Il completamento di questo comando richiede alcuni minuti. Dopo il completamento, aggiorna eksctl automaticamente il file kubeconfig in modo che funzioni con il cluster appena eseguito il provisioning. Verifica che il cluster sia operativo:

kubectl get pods --all-namespaces

Output previsto:

NAMESPACE NAME READY STATUS RESTARTS AGE kube-system metrics-server-55cf976ddd-cz2mw 1/1 Running 0 3m kube-system metrics-server-55cf976ddd-wrjvv 1/1 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

Crea l'impostazione predefinita StorageClass

I carichi di lavoro della GPU richiedono spesso uno storage persistente, ad esempio per memorizzare nella cache i pesi dei modelli in modo che Kubernetes non li scarichi nuovamente a ogni riavvio del pod. EKS Auto Mode include una funzionalità di archiviazione a blocchi integrata, quindi non è necessario installare il driver Amazon EBS CSI. Creane uno StorageClass che faccia riferimento al provisioner Auto Mode:

cat << EOF | kubectl apply -f - apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: gp3 annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: ebs.csi.eks.amazonaws.com volumeBindingMode: WaitForFirstConsumer parameters: type: gp3 encrypted: "true" EOF

Questo comando crea un gp3 StorageClass e lo contrassegna come predefinito del cluster con l'storageclass.kubernetes.io/is-default-classannotazione. Tutti quelli PersistentVolumeClaim che omettono lo storageClassName usano. StorageClass L'volumeBindingMode: WaitForFirstConsumerimpostazione ritarda la creazione del volume fino a quando Kubernetes pianifica un pod, quindi il volume EBS arriva nella stessa zona di disponibilità del pod.

Self-managed Karpenter

Autentica Helm all'ECR pubblico

eksctlestrae il grafico Karpenter Helm da Amazon Public ECR. Effettua l'autenticazione prima di creare il cluster per evitare un errore 403 nella fase di installazione di Helm:

aws ecr-public get-login-password --region us-east-1 \ | helm registry login --username AWS --password-stdin public.ecr.aws

Public ECR è un servizio globale ospitato in. us-east-1 Usalo --region us-east-1 qui indipendentemente dalla regione in cui si trova il tuo cluster EKS.

Risultato previsto: Login Succeeded

Crea il cluster EKS con Karpenter

Memorizza la tua versione di Karpenter in una variabile di ambiente per un uso successivo. Per le versioni più recenti di Karpenter, consulta le versioni di Karpenter su. https://github.com/aws/karpenter-provider-aws/releases GitHub

export KARPENTER_VERSION=1.14.0
Esempio Configurazione del cluster: YAML
cat << EOF > /tmp/cluster-karpenter.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ${CLUSTER_NAME} region: ${AWS_REGION} version: "1.36" tags: karpenter.sh/discovery: ${CLUSTER_NAME} availabilityZones: [$(echo $AZS | sed 's/,/, /g')] autoModeConfig: enabled: false iam: withOIDC: true karpenter: version: "${KARPENTER_VERSION}" withSpotInterruptionQueue: true managedNodeGroups: - name: system instanceTypes: ["m6i.2xlarge", "m5.2xlarge", "m6a.2xlarge", "m5a.2xlarge", "m7i.2xlarge"] desiredCapacity: 2 minSize: 2 maxSize: 3 labels: node-role: system tags: karpenter.sh/discovery: ${CLUSTER_NAME} addons: - name: eks-pod-identity-agent - name: eks-node-monitoring-agent - name: aws-ebs-csi-driver EOF

Il gruppo di nodi system gestiti elenca diversi tipi di istanza della stessa dimensione (8 vCPU, 32 GiB) anziché un singolo tipo. Se un tipo è temporaneamente non disponibile in una zona di disponibilità, il gruppo Auto Scaling del gruppo di nodi ricorre a un altro tipo, il che evita InsufficientInstanceCapacity errori di avvio. Per un gruppo di nodi On-Demand gestito, tutti i tipi di istanza elencati devono avere la stessa vCPU e memoria in modo che la dimensione del nodo sia uniforme.

Crea il cluster con il file di configurazione:

eksctl create cluster -f /tmp/cluster-karpenter.yaml

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. Karpenter è installato con la coda di interruzione Spot abilitata in modo da poter gestire i consigli relativi alle interruzioni e al ribilanciamento di Spot. L'autoModeConfig.enabled: falseimpostazione rende esplicito che questo cluster non utilizza la modalità automatica EKS, pertanto i componenti Karpenter installati in questo percorso sono responsabili della gestione dei nodi.

Il cluster ottiene anche l'EKS Pod Identity Agent, l'agente di monitoraggio dei nodi EKS e il driver Amazon EBS CSI installati come componenti aggiuntivi EKS. EKS Pod Identity viene utilizzato più avanti nella guida. L'agente di monitoraggio dei nodi EKS viene eseguito su ogni nodo e legge i log del kernel per impostare condizioni del nodo AcceleratedHardwareReadyKernelReady, ad esempioNetworkingReady, e, che Karpenter utilizza per decidere quando sostituire un nodo non integro.

Verifica che il cluster sia operativo:

kubectl get pods --all-namespaces

L'output previsto include Karpenter, CoreDNS, kube-proxy, aws-node (VPC CNI), EKS Pod Identity Agent e l'agente di monitoraggio dei nodi EKS.

NAMESPACE NAME READY STATUS RESTARTS AGE karpenter karpenter-567547464c-s6vkx 1/1 Running 0 3m40s karpenter karpenter-567547464c-x7gmw 1/1 Running 0 3m40s kube-system aws-node-b6gf2 2/2 Running 0 12m kube-system aws-node-lcphh 2/2 Running 0 12m kube-system coredns-7d4dcbf4fb-ccvrr 1/1 Running 0 16m kube-system coredns-7d4dcbf4fb-qbhk2 1/1 Running 0 16m kube-system eks-node-monitoring-agent-h79vm 1/1 Running 0 9m45s kube-system eks-node-monitoring-agent-tf4dw 1/1 Running 0 9m45s kube-system eks-pod-identity-agent-5jbtc 1/1 Running 0 12m kube-system eks-pod-identity-agent-rwcrc 1/1 Running 0 12m kube-system kube-proxy-p4bmq 1/1 Running 0 12m kube-system kube-proxy-v5nwr 1/1 Running 0 12m kube-system metrics-server-5b966ff79c-hr58p 1/1 Running 0 9m22s kube-system metrics-server-5b966ff79c-szs2d 1/1 Running 0 9m22s

Abilita le porte delle funzionalità di Karpenter

La modalità automatica EKS consente la riparazione automatica dei nodi e la capacità statica per impostazione predefinita. Su Karpenter autogestito, è necessario abilitare esplicitamente il NodeRepair feature gate e il StaticCapacity gate for static NodePools, che mantengono un numero fisso di nodi spec.replicas anziché ridimensionarsi in risposta ai pod in sospeso. Entrambi i gate sono Alpha e sono disattivati per impostazione predefinita in Karpenter. Il comando seguente corregge la distribuzione di Karpenter per abilitare entrambi i gate. L'aggiornamento dell'ambiente di distribuzione attiva il rollout dei pod Karpenter:

kubectl set env deployment/karpenter -n karpenter \ FEATURE_GATES=NodeRepair=true,StaticCapacity=true

Output previsto:

deployment.apps/karpenter env updated

Attendi il lancio dei pod Karpenter:

kubectl rollout status deployment/karpenter -n karpenter

Installa il plug-in del dispositivo NVIDIA

L'AMI EKS-optimized AL2023 non include il plug-in del dispositivo NVIDIA (a differenza dell'AMI Bottlerocket utilizzata da EKS Auto Mode). Installalo tramite Helm per rendere le risorse GPU utilizzabili con i Pods sul cluster.

helm repo add nvdp https://nvidia.github.io/k8s-device-plugin helm repo update
cat << 'EOF' > /tmp/nvdp-values.yaml mofedEnabled: false nodeSelector: amiFamily: al2023 gfd: enabled: true nfd: worker: tolerations: - operator: "Exists" EOF
helm install nvidia-device-plugin nvdp/nvidia-device-plugin \ --namespace kube-system \ -f /tmp/nvdp-values.yaml
  • mofedEnabled: false: disabilita il controllo di Mellanox OFED (), che non utilizza InfiniBand AWS

  • nodeSelector.amiFamily: al2023: applica solo i DaemonSet nodi AL2023 (Bottlerocket ha già il plugin integrato)

  • gfd.enabled: true: abilita le etichette GPU Feature Discovery (,, ecc.) nvidia.com/gpu.product nvidia.com/gpu.memory

Verifica che il plug-in del dispositivo NVIDIA sia installato. L'aspettativa è che non ci siano plug-in Pod per dispositivi finché non viene fornita una GPU NodePool con l'etichetta 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 2m5s

Quindi, creane uno per uso generico. NodePool Il gruppo di nodi system gestiti esegue i componenti aggiuntivi e i controller. Aggiungi un Karpenter generico in modo che i carichi di lavoro non basati su GPU NodePool possano essere scalati su richiesta senza dover passare ai nodi. system La GPU viene creata più avanti nel passaggio 2NodePool. Fase 2: Creare una GPU dinamica NodePool

General-purpose EC2NodeClass e NodePool YAML

cat << EOF | kubectl apply -f - apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: general-purpose spec: role: "eksctl-KarpenterNodeRole-${CLUSTER_NAME}" amiSelectorTerms: - alias: al2023@latest subnetSelectorTerms: - tags: karpenter.sh/discovery: ${CLUSTER_NAME} securityGroupSelectorTerms: - tags: karpenter.sh/discovery: ${CLUSTER_NAME} tags: karpenter.sh/discovery: ${CLUSTER_NAME} --- apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: general-purpose spec: template: spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: general-purpose requirements: - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] - key: karpenter.k8s.aws/instance-category operator: In values: ["c", "m", "r"] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["4"] - key: kubernetes.io/arch operator: In values: ["amd64"] limits: cpu: 1000 memory: 1000Gi EOF

Questo non NodePool ha contaminazioni, quindi qualsiasi Pod che non tollera la contaminazione della GPU può programmarlo.

Crea l'impostazione predefinita StorageClass

I carichi di lavoro della GPU richiedono spesso uno storage persistente, ad esempio per memorizzare nella cache i pesi dei modelli in modo che Kubernetes non li scarichi nuovamente a ogni riavvio del pod. Il driver Amazon EBS CSI è già installato dal addons: blocco nella configurazione del cluster all'inizio di questo passaggio, quindi devi solo creare: StorageClass

cat << EOF | kubectl apply -f - apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: gp3 annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: ebs.csi.aws.com volumeBindingMode: WaitForFirstConsumer parameters: type: gp3 encrypted: "true" EOF

Questo comando crea un cluster gp3 StorageClass e lo contrassegna come predefinito del cluster con l'annotazione. storageclass.kubernetes.io/is-default-class Tutti quelli PersistentVolumeClaim che omettono lo storageClassName usano. StorageClass L'volumeBindingMode: WaitForFirstConsumerimpostazione ritarda la creazione del volume fino a quando Kubernetes pianifica un pod, quindi il volume EBS arriva nella stessa zona di disponibilità del pod.

avvertimento

Sia per i percorsi EKS Auto Mode che per i percorsi Karpenter autogestiti, la riparazione automatica dei nodi si comporta allo stesso modo per i nodi forniti da. NodePools La riparazione automatica dei nodi in EKS Auto Mode e Karpenter è un potente metodo di interruzione che bypassa, annota e. PodDisruptionBudgets karpenter.sh/do-not-disrupt terminationGracePeriod La riparazione automatica dei nodi richiede 10 minuti prima di sostituire un nodo con la AcceleratedHardwareReady condizione impostata su e 30 minuti per le altre condizioni di False riparazione. https://docs.aws.amazon.com/eks/latest/userguide/node-repair.html

Configura il bilanciamento del carico

I passaggi successivi di questa guida espongono Grafana (e, nella procedura dettagliata di inferenza, un endpoint del modello) tramite un AWS Application Load Balancer (ALB). Configura ora i prerequisiti per il bilanciamento del carico in modo che tali sezioni possano crearne uno senza ulteriori configurazioni. Ingress

L'ALB viene inserito nelle sottoreti VPC in base ai tag delle risorse. AWS Le sottoreti pubbliche utilizzate per i load balancer connessi a Internet devono essere contrassegnate con = e le sottoreti private utilizzate per i load balancer interni devono essere contrassegnate con kubernetes.io/role/elb =1. kubernetes.io/role/internal-elb 1 Poiché hai creato questo cluster con, questi tag esistono già nelle sottoreti create. eksctl eksctl Se utilizzi il tuo VPC o le tue sottoreti importate, contrassegnale manualmente. Per informazioni dettagliate, vedi Assegnazione di tag alle sottoreti per la modalità automatica EKS.

Crea il sistema di bilanciamento del carico IngressClass

Il resto della configurazione differisce in base al percorso. EKS Auto Mode include un controller ALB integrato, quindi puoi crearne uno IngressClass tu stesso. Self-managed Karpenter richiede l'installazione del AWS Load Balancer Controller con Helm, e il diagramma Helm lo crea per te. IngressClass

EKS Auto Mode

EKS Auto Mode include un controller ALB integrato, quindi non è necessario installare componenti aggiuntivi. IngressClassCreate un nome alb che punti al controller integrato. Ciascuno Ingress creato successivamente fa riferimento a questa classe per nome e imposta il proprio schema e altre opzioni tramite annotazioni.

cat << EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: alb spec: controller: eks.amazonaws.com/alb EOF
Self-managed Karpenter

Il AWS Load Balancer Controller non è un EKS-managed componente aggiuntivo, quindi non può entrare nel addons: blocco di configurazione del eksctl cluster come fa il driver EBS CSI. Installalo con Helm.

Scarica la policy IAM

Il controller necessita delle autorizzazioni IAM per creare e gestire gli ALB. Scarica il JSON della policy IAM ufficiale:

curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json

Crea la policy IAM:

aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ --policy-document file://iam_policy.json

Crea l'associazione Pod Identity

Il cluster installa già l'eks-pod-identity-agentadd-on nel passaggio 1, quindi EKS Pod Identity è disponibile. Crea un'associazione Pod Identity che associ la policy IAM all'account di servizio del controller:

eksctl create podidentityassociation \ --cluster ${CLUSTER_NAME} \ --region ${AWS_REGION} \ --namespace kube-system \ --service-account-name aws-load-balancer-controller \ --permission-policy-arns arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):policy/AWSLoadBalancerControllerIAMPolicy

Installa con Helm

Aggiungi il repository Helm di EKS charts:

helm repo add eks https://aws.github.io/eks-charts helm repo update

Cerca l'ID VPC del tuo cluster. I valori Helm ne hanno bisogno affinché il controller possa scoprire le sottoreti:

VPC_ID=$(aws eks describe-cluster \ --name ${CLUSTER_NAME} \ --region ${AWS_REGION} \ --query 'cluster.resourcesVpcConfig.vpcId' \ --output text)

Installare il controller. La tolleranza nodeSelector e la tolleranza collocano il controller nel gruppo di nodi system gestiti accanto all'infrastruttura critica del cluster, anziché competere con le GPU o i nodi generici in termini di capacità: Karpenter-launched

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ --namespace kube-system \ --version 3.4.2 \ --set clusterName=${CLUSTER_NAME} \ --set region=${AWS_REGION} \ --set vpcId=${VPC_ID} \ --set serviceAccount.create=true \ --set serviceAccount.name=aws-load-balancer-controller \ --set "nodeSelector.node-role=system" \ --set "tolerations[0].key=CriticalAddonsOnly" \ --set "tolerations[0].operator=Exists"

Verifica che il controller sia in funzione. Dovrebbe riportare due repliche disponibili:

kubectl get deployment aws-load-balancer-controller -n kube-system

Verifica il IngressClass

Il diagramma Helm crea un IngressClass nome alb come parte dell'installazione del controller, che punta al controller autogestito. ingress.k8s.aws/alb Non è necessario crearlo manualmente. Conferma che esiste:

kubectl get ingressclass alb

Output previsto:

NAME CONTROLLER PARAMETERS AGE alb ingress.k8s.aws/alb <none> 22s

Entrambi i percorsi ora hanno un albIngressClass. Le sezioni Grafana e Inference fanno riferimento ingressClassName: alb e impostano lo schema ALB, la lista consentita Source-IP e altri comportamenti tramite preannotazioni. Ingress

Fase 2: Creare una GPU dinamica NodePool

Definisci una NodePool che esegua il provisioning dinamico delle istanze G-family GPU con una generazione superiore a 4 e inferiore a 7, utilizzando la capacità Spot con On-Demand come riserva. I percorsi EKS Auto Mode e Karpenter utilizzano entrambi la stessa NodePool API con l'unica differenza che fa riferimento. NodeClass In EKS Auto Mode, il bundle seleziona default NodeClass già l'AMI corretta e configura il pull parallelo SOCI, quindi NodePool è l'unico oggetto che si crea. In Karpenter autogestito, è inoltre necessaria una personalizzazione EC2NodeClass che aggiunga l'AMI e ottimizzi il SOCI.

Importante

Il tipo di istanza G7 EC2 richiede il driver NVIDIA versione 595 o successiva. Le AMI EKS-optimized accelerate attualmente includono il driver NVIDIA versione 580, che non supporta le istanze G7. NodePool In questo passaggio vincola la generazione dell'istanza a meno di 7 in modo che Karpenter non selezioni un'istanza G7. Per utilizzare le istanze G7 con Amazon EKS, devi creare un'AMI personalizzata con il driver NVIDIA versione 595. Per ulteriori informazioni, consulta Usa AMI EKS-optimized accelerate per istanze GPU.

EKS Auto Mode

Nella modalità EKS Auto, il pacchetto seleziona default NodeClass automaticamente l'AMI Bottlerocket per le istanze GPU, che include i driver NVIDIA preinstallati, il plug-in del dispositivo NVIDIA e il pull parallelo SOCI. È NodePool sufficiente applicare default NodeClass un codice che faccia riferimento a:

cat << 'EOF' | kubectl apply -f - apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inf spec: template: metadata: labels: guide: ai-eks-docs spec: nodeClassRef: group: eks.amazonaws.com kind: NodeClass name: default taints: - key: nvidia.com/gpu effect: NoSchedule requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot", "on-demand"] - key: eks.amazonaws.com/instance-category operator: In values: ["g"] - key: eks.amazonaws.com/instance-generation operator: Gt values: ["4"] - key: eks.amazonaws.com/instance-generation operator: Lt values: ["7"] - key: kubernetes.io/arch operator: In values: ["amd64"] limits: cpu: 1000 memory: 5000Gi EOF

Ciò NodePool fornisce istanze G-family GPU con una generazione superiore a 4 e inferiore a 7 (G5, G6e, ecc.). EKS Auto Mode sceglie un tipo di istanza all'interno di questi vincoli.

Self-managed Karpenter

Self-managed Karpenter non include un valore predefinito. NodeClass Per prima cosa si crea un modulo EC2NodeClass che inserisce l'alias EKS-optimized NVIDIA AL2023 AMI, abilita SOCI tramite il FastImagePull feature gate e si configura instanceStorePolicy: RAID0 per spostare la cache delle immagini contenuta su NVMe locali. Quindi si crea quello NodePool che fa riferimento ad esso.

Crea il EC2NodeClass

Esempio
cat << EOF | kubectl apply -f - apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: gpu-inf labels: guide: ai-eks-docs spec: role: "eksctl-KarpenterNodeRole-${CLUSTER_NAME}" amiSelectorTerms: - alias: al2023@latest subnetSelectorTerms: - tags: karpenter.sh/discovery: ${CLUSTER_NAME} securityGroupSelectorTerms: - tags: karpenter.sh/discovery: ${CLUSTER_NAME} tags: karpenter.sh/discovery: ${CLUSTER_NAME} instanceStorePolicy: RAID0 userData: | apiVersion: node.eks.aws/v1alpha1 kind: NodeConfig spec: featureGates: FastImagePull: true EOF

instanceStorePolicy: RAID0assembla i dischi NVMe locali in un array. RAID-0 L'alias al2023@latest AMI si risolve nell'AMI AL2023. EKS-optimized Quando Karpenter avvia un tipo di istanza GPU, seleziona automaticamente la variante accelerata AL2023_x86_64_NVIDIA, che include il driver NVIDIA preinstallato.

Il feature gate abilita la modalità pull parallela SOCI snapshotter, che scarica e decomprime i livelli di immagine contemporaneamente. FastImagePull Ciò corrisponde al comportamento della modalità automatica EKS sulle famiglie di istanze G, P e Trn.

Per ulteriori opzioni di ottimizzazione SOCI (download simultanei per immagine, dimensione dei blocchi, ecc.), consultate il progetto SOCI di Karpenter. https://github.com/aws-samples/karpenter-blueprints/tree/main/blueprints/soci-snapshotter

EC2NodeClassConvalida:

kubectl get ec2nodeclass gpu-inf

Risultato previsto:READY True. SeFalse, esegui kubectl describe ec2nodeclass gpu-inf e controlla le condizioni per i tag di sottorete o gruppo di sicurezza mancanti.

Crea la GPU NodePool

Esempio
cat << EOF | kubectl apply -f - apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inf spec: template: metadata: labels: guide: ai-eks-docs amiFamily: al2023 spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: gpu-inf taints: - key: nvidia.com/gpu effect: NoSchedule requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot", "on-demand"] - key: karpenter.k8s.aws/instance-category operator: In values: ["g"] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["4"] - key: karpenter.k8s.aws/instance-generation operator: Lt values: ["7"] - key: kubernetes.io/arch operator: In values: ["amd64"] limits: cpu: 1000 memory: 5000Gi EOF

L'amiFamily: al2023etichetta sul modello di nodo è quella DaemonSet utilizzata dal plug-in del dispositivo NVIDIA per selezionare questi nodi. Karpenter sceglie un tipo di istanza all'interno di questi vincoli. La nvidia.com/gpu:NoSchedule contaminazione garantisce che solo i GPU-eligible Pod siano pianificati su questi nodi.

Convalida che è stato creato NodePool :

kubectl get nodepool gpu-inf

Output previsto:

NAME NODECLASS NODES READY AGE gpu-inf default 0 True 8s

Nel percorso Karpenter autogestito, la colonna NODECLASS mostra invece di. gpu-inf default

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: 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 restartPolicy: OnFailure EOF

Verifica che il Pod sia pianificato e completato correttamente.

kubectl get pods

Output previsto:

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

Lo STATO: Completato indica che il comando nvidia-smi è 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:35:00.0 Off | 0 | | N/A 42C P8 16W / 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. 42°C è la temperatura attuale della GPU e P8 è uno stato di inattività a basso consumo, previsto perché nessun carico di lavoro utilizza la GPU. I valori da 16 W/72 W mostrano l'assorbimento di corrente rispetto alla capacità massima e 0 MiB/23034 MiB mostra la memoria GPU attualmente utilizzata rispetto al totale disponibile. Poiché il Pod ha appena eseguito nvidia-smi ed è uscito, la GPU non utilizza alcun carico di lavoro, quindi la memoria è a 0 e l'alimentazione è inattiva. La versione del driver della GPU NVIDIA (580.159.03) proviene dall'AMI Bottlerocket, mentre la versione CUDA (13.0) proviene dall'immagine del contenitore. Il modello e la memoria della GPU varieranno 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 po nvidia-smi

Output previsto:

Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 60s default-scheduler 0/2 nodes are available: 2 node(s) had untolerated taint(s). no new claims to deallocate, preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. Normal Nominated 59s eks-auto-mode/compute Pod should schedule on: nodeclaim/gpu-inf-vxcnj Normal Scheduled 24s default-scheduler Successfully assigned default/nvidia-smi to i-0fb17a09bc4203164 Warning FailedCreatePodSandBox 21s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "7f85e25b220c8fb245187758dbbbc8efb3d40f3e49e13054404880daf4c3b2f0": plugin type="aws-cni" name="aws-cni" failed (add): add cmd: failed to setup network policy Normal Pulling 7s kubelet spec.containers{nvidia-smi}: Pulling image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal" Normal Pulled 5s kubelet spec.containers{nvidia-smi}: Successfully pulled image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal" in 1.237s (1.237s including waiting). Image size: 37442701 bytes. Normal Created 5s kubelet spec.containers{nvidia-smi}: Container created Normal Started 5s 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 NodeClaim (Nominato), lo scheduler assegna il Pod una volta che il nodo è pronto (Scheduled), quindi l'immagine del contenitore viene estratta e avviata. EKS Auto Mode viene fornito con il pull parallelo SOCI (Seekable OCI) installato e configurato immediatamente sulle istanze G, P e Trn. Nota: grazie al pull parallelo SOCI, l'immagine del contenitore è stata estratta dall'ECR in meno di 2 secondi (1,237 secondi).

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

NodeClaim Risultato previsto:

NAME            TYPE         CAPACITY   ZONE         NODE                  READY   AGE
gpu-inf-vxcnj   g6.4xlarge   spot       us-east-2c   i-0fb17a09bc4203164   True    51s

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

L'FailedCreatePodSandBoxavviso in arrivo kubectl describe pod nvidia-smi è temporaneo e previsto. Il VPC CNI si inizializza in modo asincrono dopo l'unione del nodo e il kubelet riprova automaticamente. Se il Pod rimane acceso, controlla gli eventi del nodo con. ContainerCreating kubectl describe node <node-name>

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 verranno visualizzate nella console Spot Requests di EC2. Karpenter utilizza l'API EC2 con. CreateFleet type: instant Le istanze vengono visualizzate nella console EC2 Instances con un ciclo di vita. spot

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

Per utilizzare innanzitutto la capacità riservata con Spot/On-Demand riserva, crea un On-Demand Capacity Reservation (ODCR) e collegalo al tuo NodeClass, quindi aggiorna la dinamica NodePool del passaggio 2 per consentire reserved anche la capacità. La chiamata all'API di prenotazione è la stessa per entrambi i percorsi; l' NodeClass allegato è diverso perché EKS Auto Mode e Karpenter autogestito ne utilizzano tipi diversi. NodeClass

avvertimento

Il comando seguente comporta un addebito per il tipo di istanza riservata fino a quando non viene annullato con. aws ec2 cancel-capacity-reservation --capacity-reservation-id <id>

Crea la prenotazione della capacità:

CR_AZ="us-east-2a" INSTANCE_TYPE="g6e.4xlarge" aws ec2 create-capacity-reservation \ --instance-type $INSTANCE_TYPE \ --instance-platform Linux/UNIX \ --availability-zone "$CR_AZ" \ --instance-count 1 \ --instance-match-criteria open \ --end-date-type unlimited

Se ricevi un InsufficientInstanceCapacity errore, passa CR_AZ a un altro AZ e riprova.

Cerca l'ID di prenotazione della capacità e memorizzalo in una variabile di shell per i seguenti passaggi:

CAPACITY_RESERVATION_ID=$(aws ec2 describe-capacity-reservations \ --filters "Name=state,Values=active" "Name=instance-type,Values=${INSTANCE_TYPE}" \ --query 'CapacityReservations[0].CapacityReservationId' \ --output text \ --region ${AWS_REGION}) echo "Capacity reservation ID: ${CAPACITY_RESERVATION_ID}"

Quindi applica le NodePool modifiche NodeClass e al tuo percorso:

EKS Auto Mode

In EKS Auto Mode, il pacchetto default NodeClass è di sola lettura, quindi crea una personalizzazione NodeClass che faccia riferimento alla prenotazione, quindi aggiorna il NodePool punto in alto NodeClass e aggiungi reserved capacità all'elenco. capacity-type

Esempio YAML personalizzato NodeClass
NODE_ROLE=$(kubectl get nodeclass default -o jsonpath='{.spec.role}') cat << EOF | kubectl apply -f - apiVersion: eks.amazonaws.com/v1 kind: NodeClass metadata: name: gpu-inf labels: guide: ai-eks-docs spec: role: "$NODE_ROLE" subnetSelectorTerms: - tags: alpha.eksctl.io/cluster-name: "$CLUSTER_NAME" kubernetes.io/role/internal-elb: "1" securityGroupSelectorTerms: - tags: aws:eks:cluster-name: "$CLUSTER_NAME" capacityReservationSelectorTerms: - id: "$CAPACITY_RESERVATION_ID" EOF

Il kubernetes.io/role/internal-elb: "1" tag garantisce l'avvio dei nodi solo in sottoreti private.

Aggiorna il NodePool file per utilizzare ODCR-backed NodeClass e includere reserved come tipo di capacità:

Esempio NodePool YAML aggiornato
cat << EOF | kubectl apply -f - apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inf spec: template: metadata: labels: guide: ai-eks-docs spec: nodeClassRef: group: eks.amazonaws.com kind: NodeClass name: gpu-inf taints: - key: nvidia.com/gpu effect: NoSchedule requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot", "on-demand", "reserved"] - key: eks.amazonaws.com/instance-category operator: In values: ["g"] - key: eks.amazonaws.com/instance-generation operator: Gt values: ["4"] - key: eks.amazonaws.com/instance-generation operator: Lt values: ["7"] - key: kubernetes.io/arch operator: In values: ["amd64"] limits: cpu: 1000 memory: 5000Gi EOF
Self-managed Karpenter

Per Karpenter autogestito, riapplica quello che EC2NodeClass hai creato nel passaggio 2 con l'aggiunta. capacityReservationSelectorTerms Il nome e la forma del campo corrispondono alla modalità automatica EKS NodeClass mostrata nell'altra scheda.

Esempio EC2NodeClass YAML aggiornato
cat << EOF | kubectl apply -f - apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: gpu-inf labels: guide: ai-eks-docs spec: role: "eksctl-KarpenterNodeRole-${CLUSTER_NAME}" amiSelectorTerms: - alias: al2023@latest subnetSelectorTerms: - tags: karpenter.sh/discovery: ${CLUSTER_NAME} securityGroupSelectorTerms: - tags: karpenter.sh/discovery: ${CLUSTER_NAME} tags: karpenter.sh/discovery: ${CLUSTER_NAME} instanceStorePolicy: RAID0 capacityReservationSelectorTerms: - id: "$CAPACITY_RESERVATION_ID" userData: | apiVersion: node.eks.aws/v1alpha1 kind: NodeConfig spec: featureGates: FastImagePull: true EOF

L'unica modifica rispetto al passaggio 2 è il nuovo capacityReservationSelectorTerms campo. Tutti gli altri campi rimangono invariati.

Aggiorna il NodePool file per includere reserved come tipo di capacità:

Esempio NodePool YAML aggiornato
cat << EOF | kubectl apply -f - apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inf spec: template: metadata: labels: guide: ai-eks-docs amiFamily: al2023 spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: gpu-inf taints: - key: nvidia.com/gpu effect: NoSchedule requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot", "on-demand", "reserved"] - key: karpenter.k8s.aws/instance-category operator: In values: ["g"] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["4"] - key: karpenter.k8s.aws/instance-generation operator: Lt values: ["7"] - key: kubernetes.io/arch operator: In values: ["amd64"] limits: cpu: 1000 memory: 5000Gi EOF

Karpenter considera l'opzione più conveniente reserved e la lancia per prima. Una volta che la prenotazione è completa, torna a Spot o. On-Demand

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, quindi il primo Pod attiva Karpenter per avviare un nodo riservato. Il secondo Pod non può entrare 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 che trattengano la GPU e non rilasciino il 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-59b97944fb-lq56c   1/1     Running   0          2m42s   192.168.186.240   i-057692590480155da   <none>           <none>
gpu-overflow-test-59b97944fb-z4zcx   1/1     Running   0          2m42s   192.168.130.64    i-0521ecd1849fa0578   <none>           <none>

I due pod sono in esecuzione, ciascuno su un nodo diverso.

Seleziona NodeClaims per vedere i tipi di capacità:

kubectl get nodeclaims

Output previsto:

NAME            TYPE          CAPACITY    ZONE         NODE                  READY   AGE
gpu-inf-shg5w   g6e.xlarge    reserved    us-east-2a   i-0ea91fdeef65b8cb6   True    2m2s
gpu-inf-ssnqf   g6e.2xlarge   spot        us-east-2b   i-00ccf7ce65cf3f6ca   True    112s

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

Installa uno stack di monitoraggio che raccolga le metriche di cluster, nodi e GPU in Amazon Managed Service for Prometheus (AMP) e visualizzale con Grafana. Il grafico Helm kube-prometheus-stack utilizza Prometheus per lo scraping e la scrittura remota delle metriche in AMP, oltre a un Grafana autogestito per le dashboard. NVIDIA DCGM Exporter aggiunge metriche (utilizzo, memoria, temperatura, potenza, NVLink, attività tensoriale). GPU-specific

Prometheus, Grafana e l'operatore atterrano su nodi non GPU per impostazione predefinita perché i nodi GPU sono portatori della contaminazione. nvidia.com/gpu:NoSchedule Node-exporter e il DCGM Exporter funzionano entrambi su nodi GPU, in modo da poter analizzare le metriche relative a host e GPU a livello di parco macchine.

Se hai aperto un nuovo terminale, imposta il nome e la regione del cluster:

export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2

Crea lo spazio di lavoro AMP

Crea uno spazio di lavoro AMP per archiviare le metriche:

aws amp create-workspace \ --alias "amp-ws-${CLUSTER_NAME}" \ --region ${AWS_REGION}

Ottieni l'ID dello spazio di lavoro:

AMP_WORKSPACE_ID=$(aws amp list-workspaces \ --alias "amp-ws-${CLUSTER_NAME}" \ --query 'workspaces[0].workspaceId' \ --output text \ --region ${AWS_REGION}) echo "AMP Workspace ID: ${AMP_WORKSPACE_ID}"

Ottieni l'endpoint di scrittura remota:

AMP_ENDPOINT=$(aws amp describe-workspace \ --workspace-id ${AMP_WORKSPACE_ID} \ --query 'workspace.prometheusEndpoint' \ --output text \ --region ${AWS_REGION}) echo "AMP Endpoint: ${AMP_ENDPOINT}"

Crea policy IAM e associazioni EKS Pod Identity

Crea una policy IAM che consenta a Prometheus di scrivere metriche in remoto e a Grafana di interrogarle:

ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) AMP_POLICY_ARN=$(aws iam create-policy \ --policy-name "${CLUSTER_NAME}-amp-grafana-policy" \ --policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Sid\": \"AllowAMPReadWrite\", \"Effect\": \"Allow\", \"Action\": [\"aps:ListWorkspaces\", \"aps:DescribeWorkspace\", \"aps:GetMetricMetadata\", \"aps:GetSeries\", \"aps:QueryMetrics\", \"aps:RemoteWrite\", \"aps:GetLabels\"], \"Resource\": \"arn:aws:aps:${AWS_REGION}:${ACCOUNT_ID}:workspace/*\"}, {\"Sid\": \"AllowCloudWatchMetrics\", \"Effect\": \"Allow\", \"Action\": [\"cloudwatch:DescribeAlarmsForMetric\", \"cloudwatch:ListMetrics\", \"cloudwatch:GetMetricData\", \"cloudwatch:GetMetricStatistics\"], \"Resource\": \"*\"}]}" \ --query 'Policy.Arn' \ --output text) echo "AMP Policy ARN: ${AMP_POLICY_ARN}"

Crea il namespace di monitoraggio e gli account di servizio per Prometheus e Grafana:

kubectl create namespace monitoring kubectl create serviceaccount amp-iamproxy-ingest-service-account -n monitoring kubectl create serviceaccount grafana-sa -n monitoring

Crea EKS Pod Identity Associations per collegare gli account di servizio alla policy IAM:

eksctl create podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name amp-iamproxy-ingest-service-account \ --role-name "${CLUSTER_NAME}-amp-ingest-role" \ --permission-policy-arns ${AMP_POLICY_ARN} \ --region ${AWS_REGION} eksctl create podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name grafana-sa \ --role-name "${CLUSTER_NAME}-grafana-role" \ --permission-policy-arns ${AMP_POLICY_ARN} \ --region ${AWS_REGION}

Verifica che entrambe le associazioni EKS Pod Identity siano state create:

eksctl get podidentityassociation --cluster ${CLUSTER_NAME} --region ${AWS_REGION}

L'output previsto dovrebbe includere entrambi amp-iamproxy-ingest-service-account e grafana-sa nel monitoring namespace.

Installa kube-prometheus-stack

Aggiungi il repository Helm:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update

Questo file di valori omette un NodeSelector per Prometheus, Grafana e l'operatore: la contaminazione dei nodi GPU li tiene lontani dai nodi della GPU, quindi per impostazione predefinita nvidia.com/gpu:NoSchedule finiscono nel sistema o nel pool generico. Node-exporter utilizza una tolleranza jolly, quindi viene eseguito su tutti i nodi, inclusi i nodi GPU, per raccogliere le metriche a livello di flotta.

Il file dei valori configura anche un Grafana in Ingress modo che il grafico fornisca un ALB rivolto a Internet per l'accesso al browser, utilizzando quello creato in Set up load balancing. alb IngressClass Configura il bilanciamento del carico L'alb.ingress.kubernetes.io/inbound-cidrsannotazione limita il load balancer al tuo indirizzo IP, quindi impostalo prima dell'installazione.

Grafana è accessibile pubblicamente tramite HTTP con credenziali predefinite

Grafana include le credenziali di amministratore predefinite e fornisce l'accesso amministrativo completo ai dati di monitoraggio. Un sistema di bilanciamento del carico con connessione a Internet colloca questa interfaccia sulla rete Internet pubblica tramite HTTP in testo semplice. Gli scanner automatici scoprono i sistemi di bilanciamento del carico pubblici in pochi minuti. È necessario limitare l'accesso con l'alb.ingress.kubernetes.io/inbound-cidrsannotazione e considerare l'elenco degli indirizzi IP di origine come una protezione minima, non completa. Cambia anche la password amministratore predefinita di Grafana. Per una postura più sicura, utilizza uno schema interno (raggiungibile solo dall'interno del tuo VPC o da una VPN connessa) impostando lo schema su e aggiungi un certificato internal TLS.

Trova il tuo indirizzo IP pubblico e memorizzalo come CIDR. /32 Il file dei valori legge questo dalla variabile di MY_CIDR ambiente:

export MY_CIDR="$(curl -s https://checkip.amazonaws.com)/32" echo $MY_CIDR

Il risultato è simile203.0.113.4/32. Se la tua rete assegna gli indirizzi in modo dinamico, il tuo indirizzo IP potrebbe cambiare nel tempo, quindi valuta la possibilità di impostare un intervallo più ampio come. 203.0.113.0/24

Crea il file dei valori:

Esempio file di valori kube-prometheus-stack
cat << EOF > /tmp/kube-prometheus-values.yaml alertmanager: enabled: false prometheus-adapter: enabled: false prometheus: serviceAccount: create: false name: amp-iamproxy-ingest-service-account prometheusSpec: serviceAccountName: amp-iamproxy-ingest-service-account enableRemoteWriteReceiver: true retention: 2h scrapeInterval: 30s evaluationInterval: 30s podMonitorSelectorNilUsesHelmValues: false serviceMonitorSelectorNilUsesHelmValues: false resources: requests: cpu: 500m memory: 1Gi limits: memory: 8Gi remoteWrite: - url: "${AMP_ENDPOINT}api/v1/remote_write" sigv4: region: "${AWS_REGION}" queueConfig: maxSamplesPerSend: 1000 maxShards: 200 capacity: 2500 prometheusOperator: resources: requests: cpu: 100m memory: 128Mi limits: memory: 256Mi kube-state-metrics: resources: requests: cpu: 50m memory: 128Mi limits: memory: 512Mi grafana: enabled: true ingress: enabled: true ingressClassName: alb labels: guide: ai-eks-docs annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/inbound-cidrs: ${MY_CIDR} alb.ingress.kubernetes.io/load-balancer-name: grafana-ai-eks-docs alb.ingress.kubernetes.io/healthcheck-path: /api/health serviceAccount: create: false name: grafana-sa resources: requests: cpu: 100m memory: 256Mi limits: memory: 1Gi grafana.ini: auth.sigv4: enabled: true sidecar: datasources: defaultDatasourceEnabled: false plugins: - grafana-amazonprometheus-datasource additionalDataSources: - name: Amazon-Managed-Prometheus type: grafana-amazonprometheus-datasource access: proxy url: "${AMP_ENDPOINT}" isDefault: true jsonData: sigV4Auth: true defaultRegion: "${AWS_REGION}" sigV4Region: "${AWS_REGION}" editable: true dashboardProviders: dashboardproviders.yaml: apiVersion: 1 providers: - name: default orgId: 1 folder: 'GPU Monitoring' type: file disableDeletion: false editable: true options: path: /var/lib/grafana/dashboards/default dashboards: default: nvidia-dcgm: gnetId: 25261 revision: 1 datasource: - name: DS_PROMETHEUS value: Amazon-Managed-Prometheus vllm: gnetId: 25263 revision: 1 datasource: - name: DS_PROMETHEUS value: Amazon-Managed-Prometheus vllm-load-analysis: gnetId: 25494 revision: 1 datasource: - name: DS_PROMETHEUS value: Amazon-Managed-Prometheus prometheus-node-exporter: resources: requests: cpu: 50m memory: 64Mi limits: memory: 128Mi tolerations: - operator: Exists EOF

Convalida che le variabili siano state compilate correttamente:

grep -E "url:|region:" /tmp/kube-prometheus-values.yaml

Dovresti vedere l'URL completo dell'endpoint AMP (che inizia conhttps://aps-workspaces…​) e la tua regione. Se una delle due è vuota, riesporta le variabili e ricrea il file.

Installa il grafico:

helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \ --namespace monitoring \ -f /tmp/kube-prometheus-values.yaml

Verifica che i pod siano in funzione:

kubectl get pods -n monitoring

Output previsto:

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

Lo stack distribuisce i seguenti componenti:

  • Prometheus (StatefulSet): analizza le metriche e le scrive in remoto in AMP

  • Grafana: dashboard e visualizzazione, preconfigurate con l'origine dati AMP

  • kube-state-metrics: genera metriche sullo stato degli oggetti Kubernetes (stato del pod, risorsa, stati) requests/limits NodeClaim

  • node-exporter (DaemonSet, una per nodo): raccoglie le metriche a livello di host (CPU, memoria, disco, rete)

  • operatore: gestisce le risorse personalizzate Prometheus e Alertmanager

Alertmanager è disabilitato in questa configurazione.

Accedi a Grafana

È possibile accedere a Grafana tramite un AWS Application Load Balancer (ALB) connesso a Internet. Non lo crei qui. Il grafico kube-prometheus-stack lo fornisce dalla grafana.ingress configurazione nel file dei valori, utilizzando la sezione Set up load balancing. alb IngressClass Configura il bilanciamento del carico Il grafico Grafana Helm è dotato di supporto integrato, quindi non è necessario alcun manifest separato. Ingress L'ALB è denominatografana-ai-eks-docs, riporta l'etichetta guide: ai-eks-docs ed è limitato all'indirizzo IP impostato MY_CIDR al momento dell'installazione.

Il percorso di controllo dello stato di salute è obbligatorio per il gruppo target di Grafana ALB

L'alb.ingress.kubernetes.io/healthcheck-pathannotazione nel file dei valori indica i controlli di integrità del load balancer all'endpoint Grafana/api/health, che restituisce. 200 In caso contrario, i controlli di integrità ALB vengono impostati come predefiniti/, a cui Grafana risponde con un 302 reindirizzamento/login, facendo sì che il gruppo target segnali l'endpoint come non integro.

Stampa l'URL del load balancer. Il load balancer viene creato in modo asincrono, quindi attendi uno o due minuti:

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

Per verificare che la pipeline delle metriche funzioni dall'inizio alla fine:

  1. Vai a Connessioni > Origini dati e conferma Amazon-Managed-Prometheus che 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.

Implementa le metriche DCGM Exporter for GPU

Lo stack kube-prometheus-stack raccoglie le metriche di CPU e memoria a livello di nodo ma non le metriche della GPU. NVIDIA DCGM Exporter aggiunge l'utilizzo della GPU, l'utilizzo della memoria, la temperatura, il consumo energetico, la larghezza di banda NVLink e l'attività tensoriale.

helm repo add gpu-helm-charts https://nvidia.github.io/dcgm-exporter/helm-charts helm repo update

Imposta la chiave di selezione del nodo GPU per il tuo percorso. EKS Auto Mode e Karpenter autogestito utilizzano chiavi di etichetta diverse per il produttore della GPU.

EKS Auto Mode
GPU_NODE_SELECTOR_KEY="eks.amazonaws.com/instance-gpu-manufacturer"
Self-managed Karpenter
GPU_NODE_SELECTOR_KEY="karpenter.k8s.aws/instance-gpu-manufacturer"

Crea il file dei valori dell'esportatore DCGM:

Esempio file di valori dcgm-exporter
cat << EOF > /tmp/dcgm-exporter-values.yaml resources: requests: memory: "512Mi" cpu: "100m" limits: memory: "1Gi" cpu: "500m" serviceMonitor: enabled: true additionalLabels: release: kube-prometheus-stack nodeSelector: ${GPU_NODE_SELECTOR_KEY}: nvidia tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" customMetrics: | # Clocks DCGM_FI_DEV_SM_CLOCK, gauge, SM clock frequency (in MHz). DCGM_FI_DEV_MEM_CLOCK, gauge, Memory clock frequency (in MHz). # Temperature DCGM_FI_DEV_MEMORY_TEMP, gauge, Memory temperature (in C). DCGM_FI_DEV_GPU_TEMP, gauge, GPU temperature (in C). # Power DCGM_FI_DEV_POWER_USAGE, gauge, Power draw (in W). DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION, counter, Total energy consumption since boot (in mJ). # PCIe DCGM_FI_PROF_PCIE_TX_BYTES, counter, Number of bytes transmitted through PCIe TX (in KB) via NVML. DCGM_FI_PROF_PCIE_RX_BYTES, counter, Number of bytes received through PCIe RX (in KB) via NVML. DCGM_FI_DEV_PCIE_REPLAY_COUNTER, counter, Total number of PCIe retries. # Utilization (the sample period varies depending on the product) DCGM_FI_DEV_GPU_UTIL, gauge, GPU utilization (in %). DCGM_FI_DEV_MEM_COPY_UTIL, gauge, Memory utilization (in %). DCGM_FI_DEV_ENC_UTIL, gauge, Encoder utilization (in %). DCGM_FI_DEV_DEC_UTIL, gauge, Decoder utilization (in %). # Errors and violations DCGM_FI_DEV_XID_ERRORS, gauge, Value of the last XID error encountered. DCGM_EXP_XID_ERRORS_COUNT, gauge, Value of count of XID errors encountered. DCGM_FI_DEV_POWER_VIOLATION, counter, Throttling duration due to power constraints (in us). DCGM_FI_DEV_THERMAL_VIOLATION, counter, Throttling duration due to thermal constraints (in us). DCGM_FI_DEV_SYNC_BOOST_VIOLATION, counter, Throttling duration due to sync-boost constraints (in us). DCGM_FI_DEV_BOARD_LIMIT_VIOLATION, counter, Throttling duration due to board limit constraints (in us). DCGM_FI_DEV_LOW_UTIL_VIOLATION, counter, Throttling duration due to low utilization (in us). DCGM_FI_DEV_RELIABILITY_VIOLATION, counter, Throttling duration due to reliability constraints (in us). # Memory usage DCGM_FI_DEV_FB_FREE, gauge, Framebuffer memory free (in MiB). DCGM_FI_DEV_FB_USED, gauge, Framebuffer memory used (in MiB). # Retired pages DCGM_FI_DEV_RETIRED_SBE, counter, Total number of retired pages due to single-bit errors. DCGM_FI_DEV_RETIRED_DBE, counter, Total number of retired pages due to double-bit errors. DCGM_FI_DEV_RETIRED_PENDING, counter, Total number of pages pending retirement. # NVLink DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL, counter, Total number of NVLink bandwidth counters for all lanes. DCGM_FI_PROF_NVLINK_TX_BYTES, counter, The rate of data transmitted over NVLink not including protocol headers in bytes per second. DCGM_FI_PROF_NVLINK_RX_BYTES, counter, The rate of data received over NVLink not including protocol headers in bytes per second. # DCP metrics DCGM_FI_PROF_GR_ENGINE_ACTIVE, gauge, Ratio of time the graphics engine is active (in %). DCGM_FI_PROF_SM_ACTIVE, gauge, The ratio of cycles an SM has at least 1 warp assigned (in %). DCGM_FI_PROF_SM_OCCUPANCY, gauge, The ratio of number of warps resident on an SM (in %). DCGM_FI_PROF_PIPE_TENSOR_ACTIVE, gauge, Ratio of cycles the tensor (HMMA) pipe is active (in %). DCGM_FI_PROF_DRAM_ACTIVE, gauge, Ratio of cycles the device memory interface is active sending or receiving data (in %). DCGM_FI_DEV_CLOCK_THROTTLE_REASONS, gauge, Current clock throttle reasons (bitmask of DCGM_CLOCKS_THROTTLE_REASON_*). DCGM_FI_DEV_GPU_NVLINK_ERRORS, gauge, Identifies a GPU NVLink error type returned by DCGM_FI_DEV_GPU_NVLINK_ERRORS. ## NVLink DCGM_FI_DEV_NVLINK_BANDWIDTH_L0, counter, The number of bytes of active NVLink rx or tx data including both header and payload. ## Remapped rows DCGM_FI_DEV_UNCORRECTABLE_REMAPPED_ROWS, counter, Number of remapped rows for uncorrectable errors. DCGM_FI_DEV_CORRECTABLE_REMAPPED_ROWS, counter, Number of remapped rows for correctable errors. DCGM_FI_DEV_ROW_REMAP_FAILURE, gauge, whether remapping of rows has failed. ## Profiling metrics DCGM_FI_PROF_PIPE_FP64_ACTIVE, gauge, Ratio of cycles the fp64 pipes are active (in %). DCGM_FI_PROF_PIPE_FP32_ACTIVE, gauge, Ratio of cycles the fp32 pipes are active (in %). DCGM_FI_PROF_PIPE_FP16_ACTIVE, gauge, Ratio of cycles the fp16 pipes are active (in %). # ECC DCGM_FI_DEV_ECC_SBE_VOL_TOTAL, counter, Total number of single-bit volatile ECC errors. DCGM_FI_DEV_ECC_DBE_VOL_TOTAL, counter, Total number of double-bit volatile ECC errors. EOF

Il customMetrics campo sostituisce il set di metriche predefinito dell'esportatore DCGM con uno esteso che include larghezza di banda NVLink, attività tensoriale, throughput PCIe, errori ECC e limitazione termica. Per i carichi di lavoro di inferenza, aiutano a capire se le unità di elaborazione GPU sono completamente utilizzate, se la GPU è inattiva tra una richiesta e l'altra a causa delle dimensioni ridotte dei batch, se il trasferimento di dati tra CPU e GPU è un collo di bottiglia, se la limitazione termica sta causando picchi di latenza e quanto spazio di memoria della GPU rimane per batch più grandi.

Installa l'esportatore DCGM:

helm install dcgm-exporter gpu-helm-charts/dcgm-exporter \ --namespace monitoring \ -f /tmp/dcgm-exporter-values.yaml

tolerationsConsenti all'esportatore di funzionare sui GPU-tainted nodi di cui hai effettuato il provisioning nel passaggio 2. L'serviceMonitorrelease: kube-prometheus-stacketichetta assicura che Prometheus lo scopra e lo scarti automaticamente.

Verifica l'esportatore DCGM: DaemonSet

kubectl get daemonset dcgm-exporter -n monitoring

Una volta che un nodo GPU è in esecuzione, dovresti vedere un Pod pronto. 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

Crea un bucket Amazon S3 per memorizzare i pesi dei modelli e configura una EKS Pod Identity Association in modo che i workload pod possano leggervi e scrivere.

Se hai aperto un nuovo terminale, imposta il nome e la regione del cluster:

export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2

Crea il bucket S3

Crea il bucket con un suffisso casuale per evitare conflitti di nomi:

BUCKET_SUFFIX=$(head -c 4 /dev/urandom | od -An -tx1 | tr -d ' \n') MODEL_BUCKET="${CLUSTER_NAME}-models-${BUCKET_SUFFIX}" aws s3 mb s3://${MODEL_BUCKET} --region ${AWS_REGION}

I bucket S3 creati dopo gennaio 2023 hanno la crittografia lato server (AES256) e il blocco dell'accesso pubblico abilitati per impostazione predefinita.

Configura EKS Pod Identity per l'accesso a S3

Crea uno model-storage-sa ServiceAccount spazio dei default nomi, una policy IAM con ambito al bucket del modello e un'EKS Pod Identity Association che li colleghi. I workload pod impostati serviceAccountName: model-storage-sa saranno in grado di leggere e scrivere nel bucket.

kubectl create serviceaccount model-storage-sa

Crea la policy IAM:

POLICY_ARN=$(aws iam create-policy \ --policy-name "${CLUSTER_NAME}-model-storage-policy" \ --policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:GetObject\", \"s3:PutObject\", \"s3:ListBucket\", \"s3:DeleteObject\"], \"Resource\": [\"arn:aws:s3:::${MODEL_BUCKET}\", \"arn:aws:s3:::${MODEL_BUCKET}/*\"]}]}" \ --query 'Policy.Arn' \ --output text) echo "Policy ARN: ${POLICY_ARN}"
Nota

Questa policy garantisce s3:DeleteObject e s3:PutObject per la fase di convalida. Per i pod di inferenza di produzione che leggono solo i pesi dei modelli, s3:PutObject rimuovili e segui il privilegio minimo. s3:DeleteObject

Crea l'EKS Pod Identity Association. eksctlcrea il ruolo IAM con la corretta policy di fiducia e lo collega a ServiceAccount:

eksctl create podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace default \ --service-account-name model-storage-sa \ --role-name "${CLUSTER_NAME}-model-storage-role" \ --permission-policy-arns ${POLICY_ARN} \ --region ${AWS_REGION}

Verifica l'associazione:

eksctl get podidentityassociation --cluster ${CLUSTER_NAME} --region ${AWS_REGION}

L'output deve includere l'model-storage-saassociazione nel default namespace.

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-model-storage-role/eks-ai-eks-docs-model-s-..."
}

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

=== S3 List Test ===
2026-05-04 12:00:00         19 test.txt

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

L'identità del chiamante conferma che il Pod ha assunto il ${CLUSTER_NAME}-model-storage-role ruolo 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.

export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2
kubectl delete pod nvidia-smi --ignore-not-found kubectl delete deployment gpu-overflow-test --ignore-not-found

Se hai creato un ODCR, cancellalo prima. Cerca l'ID della prenotazione:

INSTANCE_TYPE="g6e.4xlarge" CAPACITY_RESERVATION_ID=$(aws ec2 describe-capacity-reservations \ --filters "Name=state,Values=active" "Name=instance-type,Values=${INSTANCE_TYPE}" \ --query 'CapacityReservations[0].CapacityReservationId' \ --output text \ --region ${AWS_REGION}) echo "Capacity reservation ID: ${CAPACITY_RESERVATION_ID}"

Cancella la prenotazione:

aws ec2 cancel-capacity-reservation --capacity-reservation-id ${CAPACITY_RESERVATION_ID}
Importante

L'annullamento di una prenotazione non interrompe le istanze in esecuzione. Continuano a essere applicate le On-Demand tariffe standard fino al termine. Elimina prima la distribuzione per svuotare il nodo riservato prima dell'annullamento.

Cerca l'ARN della policy IAM:

AMP_POLICY_ARN=$(aws iam list-policies \ --scope Local \ --query "Policies[?PolicyName=='${CLUSTER_NAME}-amp-grafana-policy'].Arn" \ --output text) echo "AMP Policy ARN: ${AMP_POLICY_ARN}"

Cerca l'ID dello spazio di lavoro AMP:

AMP_WORKSPACE_ID=$(aws amp list-workspaces \ --alias "amp-ws-${CLUSTER_NAME}" \ --query 'workspaces[0].workspaceId' \ --output text \ --region ${AWS_REGION}) echo "AMP Workspace ID: ${AMP_WORKSPACE_ID}"

Disinstalla la versione Helm dell'esportatore DCGM:

helm uninstall dcgm-exporter -n monitoring

Disinstallare la versione Kube-prometheus-stack Helm:

helm uninstall kube-prometheus-stack -n monitoring

Elimina l'associazione EKS Pod Identity per l'account del servizio di acquisizione Prometheus:

eksctl delete podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name amp-iamproxy-ingest-service-account \ --region ${AWS_REGION}

Elimina l'associazione EKS Pod Identity per l'account del servizio Grafana:

eksctl delete podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name grafana-sa \ --region ${AWS_REGION}

Elimina la policy IAM utilizzata da Prometheus e Grafana:

aws iam delete-policy --policy-arn ${AMP_POLICY_ARN}

Elimina lo spazio di lavoro AMP:

aws amp delete-workspace --workspace-id ${AMP_WORKSPACE_ID} --region ${AWS_REGION}

Elimina lo spazio dei nomi di monitoraggio:

kubectl delete namespace monitoring

Cerca il nome del bucket del modello:

MODEL_BUCKET=$(aws s3api list-buckets \ --query "Buckets[?starts_with(Name, '${CLUSTER_NAME}-models-')].Name | [0]" \ --output text) echo "Model bucket: ${MODEL_BUCKET}"

Cerca l'ARN della policy IAM:

POLICY_ARN=$(aws iam list-policies \ --scope Local \ --query "Policies[?PolicyName=='${CLUSTER_NAME}-model-storage-policy'].Arn" \ --output text) echo "Policy ARN: ${POLICY_ARN}"

Elimina il bucket del modello S3 e tutti i suoi oggetti:

aws s3 rb s3://${MODEL_BUCKET} --force

Elimina l'associazione EKS Pod Identity:

eksctl delete podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace default \ --service-account-name model-storage-sa \ --region ${AWS_REGION}

Elimina la policy IAM:

aws iam delete-policy --policy-arn ${POLICY_ARN}

Elimina Kubernetes: ServiceAccount

kubectl delete serviceaccount model-storage-sa
kubectl delete nodepool gpu-inf --ignore-not-found kubectl delete nodeclass gpu-inf --ignore-not-found kubectl delete ec2nodeclass gpu-inf --ignore-not-found eksctl delete cluster --name=$CLUSTER_NAME --region=$AWS_REGION