Unterstützung für die Verbesserung dieser Seite beitragen
Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Um zu diesem Benutzerhandbuch beizutragen, wählen Sie den GitHub Link Diese Seite bearbeiten auf, der sich im rechten Bereich jeder Seite befindet.
Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Leitfaden für bewährte Methoden zur Cluster-Einrichtung für Echtzeit-Inferenz in Amazon EKS
Tipp
Melden Sie sich
Einführung
Dieser Leitfaden bietet eine praktische Anleitung zur Einrichtung eines Amazon Elastic Kubernetes Service (EKS) -Clusters, der für Online-Inferenz-Workloads in Echtzeit optimiert ist, und beinhaltet durchweg von Experten kuratierte Best Practices. AWS Es verwendet eine eigenwillige EKS-Schnellstart-Architektur — eine kuratierte Zusammenstellung von Treibern, Instance-Typen und Konfigurationen, die auf Best Practices für Modelle, Beschleuniger und Skalierung abgestimmt sind. AWS Dieser Ansatz erspart Ihnen die Auswahl der Cluster-Einstellungen, sodass Sie schnell einen funktionsfähigen, vorkonfigurierten Cluster in Betrieb nehmen können. Unterwegs stellen wir Beispiel-Workloads bereit, um Ihr Setup zu validieren, erklären wichtige Architekturkonzepte (wie die Entkopplung CPU-gebundener Aufgaben von GPU-intensiven Berechnungen) und gehen auf häufig gestellte Fragen ein (z. B. warum sollten Sie Bottlerocket AMI vorziehen?) AL2023 und skizzieren die nächsten Schritte zur Erweiterung der Funktionen Ihres Clusters.
Dieser Leitfaden wurde speziell für Ingenieure, Plattformadministratoren, Betreiber und data/AI Spezialisten für Machine Learning (ML) und künstliche Intelligenz (KI) entwickelt, die neu im EKS-Ökosystem sind. Er setzt Vertrautheit mit Kubernetes voraus, jedoch keine EKS-Vorkenntnisse. AWS Es soll Ihnen dabei helfen, die erforderlichen Schritte und Prozesse zu verstehen, um Echtzeit-Online-Inferenz-Workloads zum Laufen zu bringen. Der Leitfaden zeigt Ihnen die Grundlagen der Erstellung eines Inferenzclusters mit einem Knoten, einschließlich der Bereitstellung von GPU-Ressourcen, der Integration von Speicher für Modellartefakte, der Bereitstellung eines sicheren AWS Servicezugriffs und der Offenlegung von Inferenzendpunkten. Dabei wird durchgehend Wert auf ein latenzarme, ausfallsicheres Design für benutzerorientierte Anwendungen wie Betrugserkennung, Echtzeit-Chatbots und Stimmungsanalyse in Kundenfeedback-Systemen gelegt.
In diesem Leitfaden konzentrieren wir uns ausschließlich auf die Einrichtung eines grundlegenden, präskriptiven Ausgangspunkts mithilfe von G5-EC2-Instances. Wenn Sie nach AWS inferenzspezifischen Clusterkonfigurationen oder Workflows suchen, finden Sie unsere Workshops unter. end-to-end Verwenden Sie AWS Inferentia-Instances mit Amazon EKS für Machine Learning Ressourcen für den Einstieg in KI/ML in Amazon EKS
Bevor Sie beginnen
Stellen Sie zunächst sicher, dass Sie die folgenden Aufgaben durchgeführt haben:
Architektur
Echtzeit-Online-Inferenz bezeichnet den Prozess, bei dem ein trainiertes Machine-Learning-Modell verwendet wird, um mit minimaler Latenz Prognosen oder Ergebnisse zu eingehenden Datenströmen zu generieren. Dies ermöglicht beispielsweise die Echtzeit-Betrugserkennung, die Klassifizierung von Images oder die Erstellung von Wissensdiagrammen als Reaktion auf Benutzereingaben. Die Architektur eines Echtzeit-Online-Inferenzsystems ermöglicht Machine Learning-Prognosen mit niedriger Latenz in benutzerorientierten Anwendungen, indem sie die CPU-gebundene Verarbeitung des Web-Datenverkehrs von den GPU-intensiven KI-Berechnungen trennt. Dieser Prozess findet in der Regel innerhalb einer größeren Anwendungsumgebung statt und beinhaltet oft Backend-, Frontend-, Vektor- und Modell-Services. Der Fokus liegt dabei auf spezialisierten Komponenten, um eine unabhängige Skalierung, parallele Entwicklung und Ausfallsicherheit zu ermöglichen. Die Isolierung von Inferenzaufgaben auf dedizierter GPU-Hardware und die Nutzung von Schnittstellen wie z. B. WebSockets eine hohe Parallelität, eine schnelle Verarbeitung von Modellen wie Transformatoren APIs und Benutzerinteraktionen über das Frontend werden gewährleistet. Beachten Sie, dass Vektordatenbanken und Retrieval Augmented Generation (RAG)-Pipelines zwar häufig eine wichtige Rolle in Echtzeit-Inferenzsystemen spielen, diese Komponenten jedoch nicht in diesem Leitfaden behandelt werden. Eine typische Architektur umfasst in der Regel mindestens folgende Komponenten:
-
Frontend-Dienst: Dient als benutzerorientierte Schnittstelle, verwaltet die clientseitige Logik, rendert dynamische Inhalte und erleichtert Interaktionen in Echtzeit. Er kommuniziert mit dem Backend-Service, um Inferenzanfragen zu initiieren und Ergebnisse anzuzeigen, wobei häufig Anfragen an den Backend-Service initiiert werden, der WebSockets für Streaming-Updates oder APIs für den strukturierten Datenaustausch verwendet wird. Für diesen Dienst ist in der Regel kein dedizierter Load Balancer erforderlich, da er in Content Delivery Networks (CDNs) gehostet werden kann, z. B. AWS CloudFront für statische Ressourcen, oder direkt von Webservern aus bereitgestellt werden kann, wobei die Skalierung bei Bedarf für dynamische Inhalte über Gruppen mit auto-scaling erfolgt.
-
Backend-Service: Fungiert als Orchestrator der Anwendung und verwaltet die Geschäftslogik wie Benutzerauthentifizierung, Datenvalidierung und Dienstkoordination (z. B. über APIs für RESTful Endpunkte oder WebSockets für persistente Verbindungen). Es kommuniziert mit dem Inferenzdienst, skaliert unabhängig auf Multi-Core CPUs und RAM, um hohen Webverkehr zu bewältigen, ohne darauf angewiesen zu sein GPUs, und benötigt häufig einen Load Balancer (wie AWS Application Load Balancer oder Network Load Balancer), um eingehende Anfragen auf mehrere Instanzen zu verteilen, insbesondere in Szenarien mit hoher Parallelität. Ein Ingress-Controller kann externe Zugriffs- und Routing-Regeln für verbesserte Sicherheit und Datenverkehrsgestaltung verwalten.
-
Inference Service: Dient als Kern für KI-Berechnungen und läuft GPUs mit ausreichend VRAM (z. B. 8-12 GB für Modelle wie DistilBert), um Vektoreinbettungen, Wissensextraktion und Modellinferenz (z. B. APIs für Batch-Anfragen oder WebSockets für Echtzeit-Streaming) mithilfe von benutzerdefinierten oder Open-Source-Modellen durchzuführen. Diese Isolierung verhindert Abhängigkeitskonflikte, ermöglicht Modellaktualisierungen ohne Ausfallzeiten und ermöglicht eine horizontale Skalierung mit Lastausgleich für mehrere gleichzeitige Anfragen. Um den Modelldienst effektiv verfügbar zu machen, befindet er sich in der Regel hinter einem Load Balancer, um GPU-gebundene Workloads auf replizierte Instanzen zu verteilen, während eine Eingangsressource oder ein Controller (z. B. der ALB Ingress Controller in AWS) das externe Routing, die SSL-Terminierung und die pfadbasierte Weiterleitung übernimmt, um einen sicheren und effizienten Zugriff zu gewährleisten, ohne den Einzelnen zu überfordern GPUs.
Übersicht über die Lösung
Echtzeit-Online-Inferenzsysteme erfordern eine leistungsstarke, ausfallsichere Architektur, die extrem niedrige Latenzzeiten bietet und gleichzeitig unvorhersehbare, hohe Datenverkehrsausfälle bewältigen kann. In dieser Lösungsübersicht wird erklärt, wie die folgenden AWS Komponenten in dem Amazon EKS-Cluster zusammenarbeiten, den wir erstellen werden, um sicherzustellen, dass unser Cluster Modelle für maschinelles Lernen hosten und verwalten kann, die sofortige Vorhersagen zu Live-Daten mit minimaler Verzögerung für Endbenutzer liefern.
-
Amazon-G5-EC2-Instances
– Für GPU-intensive Inferenzaufgaben verwenden wir die G5-EC2-Instance-Typen g5.xlarge und g5.2xlarge, die über eine einzelne (1) NVIDIA A10G-GPU mit 24 GB Speicher verfügen (z. B. 8 Milliarden Parameter bei FP16). Diese GPUs basieren auf der NVIDIA Ampere-Architektur und werden von NVIDIA A10G Tensor Core GPUs und AMD EPYC-Prozessoren der 2. Generation angetrieben. Sie unterstützen 4–8 vCPUs, bis zu 10 Gbit/s Netzwerkbandbreite und 250–450 GB lokalen NVMe-SSD-Speicher. Dies gewährleistet schnelle Datenübertragung und Rechenleistung für komplexe Modelle und macht sie ideal für Inferenzaufgaben mit geringer Latenz und hohem Durchsatz. Die Auswahl eines EC2-Instance-Typs ist anwendungsspezifisch und hängt von Ihrem Modell (z. B. Image-, Video- oder Textmodell) sowie Ihren Anforderungen an Latenz und Durchsatz ab. Wenn Sie beispielsweise ein Image- und/oder Videomodell verwenden, empfehlen wir den Einsatz von P5-EC2-Instances , um eine optimale Echtzeit-Latenz zu erzielen. Wir empfehlen, zunächst mit G5-EC2-Instances zu beginnen, da diese einen guten Ausgangspunkt für eine schnelle Inbetriebnahme bieten. Anschließend können Sie anhand von Leistungsbenchmark-Tests beurteilen, ob sie für Ihre Workloads geeignet sind. Für anspruchsvollere Fälle sollten Sie G6-EC2-Instances in Betracht ziehen. -
Amazon-EC2-M7g-Instances
– Für rechenintensive Aufgaben wie Datenvorverarbeitung, API-Anfragenbearbeitung, Hosting des Karpenter-Controllers, Add-Ons und andere Systemkomponenten verwenden wir den EC2-Instance-Typ m5.xlarge M7g. M7g-Instances sind ARM-basierte Instances mit 4 VCPUs, 16 GB Arbeitsspeicher und bis zu 12,5 Gbit/s Netzwerkbandbreite, die von Graviton3-Prozessoren angetrieben werden. AWS Die Auswahl eines EC2-Instance-Typs ist anwendungsspezifisch und hängt von den Anforderungen Ihrer Workload hinsichtlich Rechenleistung, Arbeitsspeicher und Skalierbarkeit ab. Für rechenoptimierte Workloads können Sie C7g-EC2-Instances in Betracht ziehen, die ebenfalls mit Graviton3-Prozessoren ausgestattet sind, jedoch für bestimmte Anwendungsfälle auf eine höhere Rechenleistung als M7g-Instances optimiert sind. Alternativ bieten die neueren C8g-EC2-Instances (sofern verfügbar) eine um bis zu 30 % bessere Rechenleistung als C7g-Instances. Wir empfehlen den Einstieg mit M7g-EC2-Instances aufgrund ihrer Kosteneffizienz und Kompatibilität mit einer Vielzahl von Workloads (z. B. Anwendungsserver, Microservices, Gaming-Server, mittelgroße Datenspeicher). Anschließend sollten Sie durch Leistungsbenchmark-Tests prüfen, ob sie für Ihre Workloads geeignet sind. -
Mountpoint-CSI-Treiber für Amazon S3 – Für Workloads auf Einzel-GPU-Instances, bei denen mehrere Pods eine GPU gemeinsam nutzen (z. B. mehrere Pods, die auf demselben Knoten geplant sind, um dessen GPU-Ressourcen zu nutzen), verwenden wir den Mountpoint-S3-CSI-Treiber, um die Speichernutzung zu optimieren. Dies ist für Aufgaben wie die Inferenz großer Modelle in kostenbewussten, wenig komplexen Einrichtungen von entscheidender Bedeutung. Er stellt Amazon-S3-Buckets als POSIX-ähnliches Dateisystem zur Verfügung, das für den Kubernetes-Cluster verfügbar ist. Dadurch können Inferenz-Pods Modellartefakte (z. B. Modellgewichte) direkt in den Speicher lesen, ohne sie zuvor herunterladen zu müssen, und Datensätze mithilfe von Standard-Dateioperationen eingeben. Darüber hinaus verfügt S3 über praktisch unbegrenzte Speicherkapazität und beschleunigt datenintensive Inferenz-Workloads. Die Auswahl eines Speicher-CSI-Treibers ist anwendungsspezifisch und hängt von den Anforderungen Ihrer Workload hinsichtlich Durchsatz und Latenz ab. Obwohl der FSx für OpenZFS CSI Driver eine Latenz von unter einer Millisekunde für zufällige I/O oder vollständig POSIX-konforme, knotenübergreifende gemeinsame persistente Volumes bietet, empfehlen wir, mit dem Mountpoint S3 CSI-Treiber zu beginnen, da er Skalierbarkeit, geringere Kosten für große Datensätze und integrierte Integration mit S3-verwaltetem Objektspeicher für leseintensive Inferenzmuster (z. B. Streaming-Modelleingaben) bietet, und dann anhand von Performance-Benchmark-Tests zu prüfen, ob er für Ihre Workloads geeignet ist.
-
EKS Pod Identity Agent — Um den Zugriff auf AWS Dienste zu ermöglichen, verwenden wir den EKS Pod Identity Agent, der einen einzigen Dienstprinzipal verwendet und IAM-Rollenzuordnungen auf Pod-Ebene innerhalb des Amazon EKS-Clusters ermöglicht. EKS Pod Identity bietet eine optimierte Alternative zum herkömmlichen Ansatz derIAM-Rollen für Servicekonten (IRSA), indem es einen einzigen Service-Prinzipal (pods.eks.amazonaws.com) verwendet, anstatt sich auf einzelne OIDC-Anbieter für jeden Cluster zu verlassen, was die Zuweisung von Berechtigungen vereinfacht. Darüber hinaus ermöglicht es die Wiederverwendung von Rollen über mehrere Cluster hinweg und unterstützt erweiterte Features wie IAM- Rollensitzungs-Tags und Ziel-IAM-Rollen.
-
EKS-Knoten-Überwachungsagent – Um die kontinuierliche Verfügbarkeit und Zuverlässigkeit der Inferenz-Services sicherzustellen, setzen wir den EKS-Knotenüberwachungsagenten mit automatischer Reparatur ein, der fehlerhafte Knoten automatisch erkennt und ersetzt und so Ausfallzeiten minimiert. Er überwacht Knoten kontinuierlich auf Hardware-, Kernel-, Netzwerk- und Speicherprobleme mithilfe erweiterter Integritätsprüfungen (z. B., KernelReady). NetworkingReady Bei GPU-Knoten erkennt er beschleunigerspezifische Ausfälle und leitet eine effiziente Behebung ein. Hierzu werden fehlerhafte Knoten isoliert, 10 Minuten lang auf die Behebung vorübergehender GPU-Probleme gewartet und bei anhaltenden Ausfällen die Knoten nach 30 Minuten ersetzt.
-
Bottlerocket-AMI – Um eine sicherheitsoptimierte Grundlage für unseren EKS-Cluster zu schaffen, setzen wir das Bottlerocket-AMI ein, das ausschließlich die für den Betrieb von Containern erforderlichen Komponenten enthält und minimale Startzeiten für eine schnelle Skalierung bietet. Die Auswahl eines Knoten-AMI ist anwendungsspezifisch und hängt von den Anforderungen Ihrer Workload hinsichtlich Anpassung, Sicherheit und Skalierbarkeit ab. Das AL2023 AMI bietet zwar mehr Flexibilität für Installationen und Anpassungen auf Host-Ebene (z. B. die Angabe eines dedizierten Cache-Verzeichnisses PV/PVC ohne zusätzliche Knotenkonfigurationen), wir empfehlen jedoch, mit dem Bottlerocket-AMI zu beginnen, da es einen geringeren Platzbedarf und die integrierte Optimierung für containerisierte Workloads (z. B. Microservices, Inferenzserver, skalierbar APIs) bietet und dann anhand von Performance-Benchmarktests zu prüfen, ob es für Ihre Workloads geeignet ist.
-
AWS Load Balancer Controller (LBC) — Um Inferenzendpunkte in Echtzeit verfügbar zu machen, verwenden wir den Load AWS Balancer Controller, der automatisch Application Load Balancer () für Traffic und Network Load Balancer (ALBs) für HTTP/HTTPS Traffic auf Basis von Kubernetes Ingress- und Service-Ressourcen bereitstellt und verwaltet und so die Integration von Inferenzmodellen mit externen Clients ermöglicht. NLBs TCP/UDP Darüber hinaus unterstützt es Funktionen wie pfadbasiertes Routing zur Verteilung von Inferenzanfragen auf mehrere Pods oder Knoten, wodurch die Skalierbarkeit bei Verkehrsspitzen gewährleistet und die Latenz durch AWS native Optimierungen wie Verbindungsmultiplexing und Integritätsprüfungen minimiert wird.
1. Erstellen Ihres EKS-Clusters
In diesem Schritt erstellen wir einen Cluster mit CPU-Knoten und einer verwalteten Knotengruppe unter Verwendung einer eksctl-Vorlage mit -Unterstützung. AWS CloudFormation ClusterConfig
Standardmäßig erstellt eksctl eine dedizierte VPC für den Cluster mit einem CIDR-Block von 192.168.0.0/16. Die VPC umfasst drei öffentliche Subnetze und drei private Subnetze, die jeweils auf drei verschiedene Availability Zones (oder zwei AZs in der us-east-1 Region) verteilt sind. Dies ist die ideale Methode für die Bereitstellung von Kubernetes-Workloads. Die Vorlage stellt außerdem ein Internet-Gateway bereit, das den öffentlichen Subnetzen über Standard-Routen in ihren Routing-Tabellen und ein einzelnes NAT-Gateway in einem der öffentlichen Subnetze Internetzugang gewährt. Die Standard-Routen in den Routing-Tabellen der privaten Subnetze leiten den ausgehenden Datenverkehr über das NAT-Gateway zum Internetzugang weiter. Weitere Informationen zu dieser Konfiguration finden Sie unter Bereitstellen von Knoten in privaten Subnetzen.
Überprüfung Ihrer Anmeldeinformationen
Prüfen Sie, ob Ihre AWS CLI-Anmeldeinformationen gültig sind und sich bei AWS Diensten authentifizieren können:
aws sts get-caller-identity
Bei Erfolg gibt die CLI Details zu Ihrer AWS Identität (UserId, Ihrem Konto und Ihrem ARN) zurück.
Überprüfung der Verfügbarkeit von Instances
G5-Instance-Typen stehen in allen Regionen zur Verfügung. Überprüfen Sie Ihre nächstgelegene Region. Beispiel:
aws ec2 describe-instance-types --instance-types g5.xlarge g5.2xlarge --region us-east-1
Bei Erfolg ist der G5-Instance-Typ in der von Ihnen angegebenen Region verfügbar.
Das Bottlerocket-AMI ist nicht in allen Regionen verfügbar. Überprüfen Sie dies, indem Sie eine Bottlerocket-AMI-ID für Ihre nächstgelegene Region abrufen. Beispiel:
aws ssm get-parameter --name /aws/service/bottlerocket/aws-k8s-1.33/arm64/latest/image_id \ --region us-east-1 --query "Parameter.Value" --output text
Bei Erfolg ist das Bottlerocket-AMI in der von Ihnen angegebenen Region verfügbar.
Vorbereitung Ihrer Umgebung
Legen Sie zunächst die folgenden Umgebungsvariablen in einem neuen Terminalfenster fest. Hinweis: Ersetzen Sie die Platzhalterbeispiele unbedingt durch Ihre individuellen Werte, einschließlich Cluster-Name, gewünschte Region, Karpenter-Vorversion
Tipp
Einige Variablen (wie ${AWS_REGION} und ${K8S_VERSION}) werden früh im Block definiert und dann in späteren Befehlen referenziert, um Konsistenz zu gewährleisten und Wiederholungen zu vermeiden. Führen Sie die Befehle unbedingt nacheinander aus, damit diese Werte ordnungsgemäß exportiert werden und in nachfolgenden Definitionen zur Verfügung stehen.
export TEMPOUT="$(mktemp)" export K8S_VERSION=1.33 export KARPENTER_VERSION="1.5.0" export AWS_REGION="us-east-1" export EKS_CLUSTER_NAME="eks-rt-inference-${AWS_REGION}" export S3_BUCKET_NAME="eks-rt-inference-models-${AWS_REGION}-$(date +%s)" export NVIDIA_BOTTLEROCKET_AMI="$(aws ssm get-parameter --name /aws/service/bottlerocket/aws-k8s-${K8S_VERSION}-nvidia/x86_64/latest/image_id --query Parameter.Value --output text)" export STANDARD_BOTTLEROCKET_AMI="$(aws ssm get-parameter --name /aws/service/bottlerocket/aws-k8s-${K8S_VERSION}/arm64/latest/image_id --query Parameter.Value --output text)" export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)" export ALIAS_VERSION="$(aws ssm get-parameter --name "/aws/service/eks/optimized-ami/${K8S_VERSION}/amazon-linux-2023/x86_64/standard/recommended/image_id" --query Parameter.Value | xargs aws ec2 describe-images --query 'Images[0].Name' --image-ids | sed -r 's/^.*(v[[:digit:]]+).*$/\1/')"
Erstellung der erforderlichen Rollen und Richtlinien
Karpenter benötigt spezifische IAM-Rollen und -Richtlinien (z. B. Karpenter-Controller-IAM-Rolle, Instance-Profil und Richtlinien), um EC2-Instances als Kubernetes-Worker-Knoten zu verwalten. Sie verwendet diese Rollen, um Aktionen wie das Starten und Beenden von EC2-Instances, das Markieren von Ressourcen und die Interaktion mit anderen Diensten auszuführen. AWS Erstellen Sie die Karpenter-Rollen und -Richtlinien mithilfe der Datei cloudformation.yaml
curl -fsSL https://raw.githubusercontent.com/aws/karpenter-provider-aws/v${KARPENTER_VERSION}/website/content/en/preview/getting-started/getting-started-with-karpenter/cloudformation.yaml > "${TEMPOUT}" \ && aws cloudformation deploy \ --stack-name "Karpenter-${EKS_CLUSTER_NAME}" \ --template-file "${TEMPOUT}" \ --capabilities CAPABILITY_NAMED_IAM \ --parameter-overrides "ClusterName=${EKS_CLUSTER_NAME}"
Das AWS LBC benötigt die Erlaubnis, AWS Load Balancer bereitzustellen und zu verwalten, z. B. für die Erstellung von Ingress-Ressourcen oder ALBs für Dienste des Typs. NLBs LoadBalancer Diese Berechtigungsrichtlinie legen wir bei der Erstellung des Clusters fest. Während der Clustererstellung erstellen wir das Dienstkonto mit eksctl im. ClusterConfig Erstellen Sie die LBC-IAM-Richtlinie:
aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ --policy-document "$(curl -fsSL https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/install/iam_policy.json)"
Wenn der Mountpoint S3 CSI-Treiber installiert ist, sind seine DaemonSet Pods so konfiguriert, dass sie ein Dienstkonto für die Ausführung verwenden. Der Mountpoint für den Mountpoint-S3-CSI-Treiber benötigt die Berechtigung zur Interaktion mit dem Amazon-S3-Bucket, den Sie später in diesem Leitfaden erstellen. Diese Berechtigungsrichtlinie legen wir bei der Erstellung des Clusters fest. Während der Clustererstellung erstellen wir das Dienstkonto mit eksctl im. ClusterConfig Erstellen Sie die S3-IAM-Richtlinie:
aws iam create-policy \ --policy-name S3CSIDriverPolicy \ --policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:GetObject\", \"s3:PutObject\", \"s3:AbortMultipartUpload\", \"s3:DeleteObject\", \"s3:ListBucket\"], \"Resource\": [\"arn:aws:s3:::${S3_BUCKET_NAME}\", \"arn:aws:s3:::${S3_BUCKET_NAME}/*\"]}]}"
Hinweis: Sollte bereits eine Rolle mit diesem Namen vorhanden sein, benennen Sie die Rolle um. Die Rolle, die wir in diesem Schritt erstellen, ist spezifisch für Ihren Cluster und Ihren S3-Bucket.
Den Cluster erstellen
In dieser Vorlage erstellt eksctl automatisch ein Kubernetes-Servicekonto für EKS Pod Identity, Knoten-Überwachungsagent, CoreDNS, Kubeproxy und das VPC-CNI-Plugin. Derzeit ist der Mountpoint-S3-CSI-Treiber für EKS Pod Identity nicht verfügbar, daher erstellen wir eine IAM-Rolle für das Servicekonto (IRSA) und einen OIDC-Endpunkt. Darüber hinaus erstellen wir ein Dienstkonto für den Load AWS Balancer Controller (LBC). Für den Zugriff auf Bottlerocket-Knoten hängt eksctl automatisch Amazon SSMManaged InstanceCore for Bottlerocket an, um sichere Shell-Sitzungen über SSM zu ermöglichen.
Führen Sie in demselben Terminal, in dem Sie Ihre Umgebungsvariablen festgelegt haben, den folgenden Befehlsblock aus, um den Cluster zu erstellen:
eksctl create cluster -f - <<EOF --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ${EKS_CLUSTER_NAME} region: ${AWS_REGION} version: "${K8S_VERSION}" tags: karpenter.sh/discovery: ${EKS_CLUSTER_NAME} # Add more tags if needed for billing iam: # Creates an OIDC endpoint and IRSA service account for the Mountpoint S3 CSI Driver # Uses the S3 CSI Driver policy for permissions withOIDC: true podIdentityAssociations: # Creates the pod identity association and service account # Uses the Karpenter controller IAM policy for permissions - namespace: "kube-system" serviceAccountName: karpenter roleName: ${EKS_CLUSTER_NAME}-karpenter permissionPolicyARNs: - arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${EKS_CLUSTER_NAME} # Creates the pod identity association and service account # Uses the {aws} LBC policy for permissions - namespace: kube-system serviceAccountName: aws-load-balancer-controller createServiceAccount: true roleName: AmazonEKSLoadBalancerControllerRole permissionPolicyARNs: - arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy iamIdentityMappings: - arn: "arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${EKS_CLUSTER_NAME}" username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes managedNodeGroups: # Creates 2 CPU nodes for lightweight system tasks - name: ${EKS_CLUSTER_NAME}-m7-cpu instanceType: m7g.xlarge amiFamily: Bottlerocket desiredCapacity: 2 minSize: 1 maxSize: 10 labels: role: cpu-worker # Enable automatic Pod Identity associations for VPC CNI Driver, coreDNS, kube-proxy addonsConfig: autoApplyPodIdentityAssociations: true addons: # Installs the S3 CSI Driver addon and creates IAM role # Uses the S3 CSI Driver policy for IRSA permissions - name: aws-mountpoint-s3-csi-driver attachPolicyARNs: - "arn:aws:iam::${AWS_ACCOUNT_ID}:policy/S3CSIDriverPolicy" - name: eks-pod-identity-agent - name: eks-node-monitoring-agent - name: coredns - name: kube-proxy - name: vpc-cni EOF
Dieser Vorgang dauert einige Minuten. Wenn Sie den Status überwachen möchten, schauen Sie in der Konsole nach. AWS CloudFormation
2. Verifizierung des Zustands von Cluster-Knoten und Pods
Wir führen einige Zustandsprüfungen durch, um sicherzustellen, dass der Cluster einsatzbereit ist. Wenn der vorherige Befehl abgeschlossen ist, zeigen Sie die Instance-Typen an und überprüfen Sie mit dem folgenden Befehl, ob Ihre CPU-Systemknoten den Ready-Status erreicht haben:
kubectl get nodes -L node.kubernetes.io/instance-type
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
NAME STATUS ROLES AGE VERSION INSTANCE-TYPE ip-192-168-35-103.ec2.internal Ready <none> 12m v1.33.0-eks-802817d m7g.xlarge ip-192-168-7-15.ec2.internal Ready <none> 12m v1.33.0-eks-802817d m7g.xlarge
Überprüfen Sie alle Pod-Identity-Zuordnungen und wie diese eine Rolle einem Servicekonto in einem Namespace im Cluster zuordnen, mit dem folgenden Befehl:
eksctl get podidentityassociation --cluster ${EKS_CLUSTER_NAME} --region ${AWS_REGION}
In der Ausgabe sollten die IAM-Rollen für Karpenter („karpenter“) und AWS LBC (“ „) angezeigt werden. aws-load-balancer-controller
Stellen Sie sicher, dass sie verfügbar sind: DaemonSets
kubectl get daemonsets -n kube-system
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE aws-node 3 3 3 3 3 <none> 12m dcgm-server 0 0 0 0 0 kubernetes.io/os=linux 12m eks-node-monitoring-agent 3 3 3 3 3 kubernetes.io/os=linux 12m eks-pod-identity-agent 3 3 3 3 3 <none> 12m kube-proxy 3 3 3 3 3 <none> 12m s3-csi-node 2 2 2 2 2 kubernetes.io/os=linux 12m
Überprüfen Sie, ob alle Add-Ons auf dem Cluster installiert sind:
eksctl get addons --cluster ${EKS_CLUSTER_NAME} --region ${AWS_REGION}
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
NAME VERSION STATUS ISSUES IAMROLE UPDATE AVAILABLE CONFIGURATION VALUES POD IDENTITY ASSOCIATION ROLES aws-mountpoint-s3-csi-driver v1.15.0-eksbuild.1 ACTIVE 0 arn:aws:iam::143095308808:role/eksctl-eks-rt-inference-us-east-1-addon-aws-m-Role1-RAUjk4sJnc0L coredns v1.12.1-eksbuild.2 ACTIVE 0 eks-node-monitoring-agent v1.3.0-eksbuild.2 ACTIVE 0 eks-pod-identity-agent v1.3.7-eksbuild.2 ACTIVE 0 kube-proxy v1.33.0-eksbuild.2 ACTIVE 0 metrics-server v0.7.2-eksbuild.3 ACTIVE 0 vpc-cni v1.19.5-eksbuild.1 ACTIVE 0
3. Installation von Karpenter
Installieren Sie den Karpenter-Controller auf Ihren CPU-Worker-Knoten (cpu-worker), um Kosten zu optimieren und GPU-Ressourcen zu schonen. Wir installieren ihn im Namespace „kube-system“ und geben das Servicekonto „karpenter“ an, das wir bei der Erstellung des Clusters definiert haben. Darüber hinaus konfiguriert dieser Befehl den Cluster-Namen und eine Spot-Instance-Unterbrechungs-Warteschlange für CPU-Knoten. Karpenter wird IRSA verwenden, um diese IAM-Rolle zu übernehmen.
# Logout of helm registry before pulling from public ECR helm registry logout public.ecr.aws # Install Karpenter helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter --version "${KARPENTER_VERSION}" --namespace "kube-system" --create-namespace \ --set "settings.clusterName=${EKS_CLUSTER_NAME}" \ --set "settings.interruptionQueue=${EKS_CLUSTER_NAME}" \ --set controller.resources.requests.cpu=1 \ --set controller.resources.requests.memory=1Gi \ --set controller.resources.limits.cpu=1 \ --set controller.resources.limits.memory=1Gi \ --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"="arn:aws:iam::${AWS_ACCOUNT_ID}:role/${EKS_CLUSTER_NAME}-karpenter" \ --wait
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
Release "karpenter" does not exist. Installing it now. Pulled: public.ecr.aws/karpenter/karpenter:1.5.0 Digest: sha256:9a155c7831fbff070669e58500f68d7ccdcf3f7c808dcb4c21d3885aa20c0a1c NAME: karpenter LAST DEPLOYED: Thu Jun 19 09:57:06 2025 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None
Überprüfen Sie, ob Karpenter ausgeführt wird:
kubectl get pods -n kube-system -l app.kubernetes.io/name=karpenter
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
NAME READY STATUS RESTARTS AGE karpenter-555895dc-865bc 1/1 Running 0 5m58s karpenter-555895dc-j7tk9 1/1 Running 0 5m58s
4. Richten Sie Karpenter ein NodePools
In diesem Schritt konfigurieren wir die sich gegenseitig ausschließende CPU- und GPU-Karpenter. NodePoolslimits Feld in der NodePool Spezifikation schränkt die maximalen Gesamtressourcen (z. B. CPU, Speicher GPUs) ein, die jeder für alle bereitgestellten Knoten verbrauchen NodePool kann. Dadurch wird verhindert, dass zusätzliche Knoten bereitgestellt werden, wenn diese Grenzwerte überschritten werden. NodePools Unterstützt zwar breite Instanzkategorien (z. B.,g)c, aber die Angabe bestimmter Instanztypen, Kapazitätstypen
Richten Sie die GPU ein NodePool
Darin legen wir Ressourcenlimits fest NodePool, um die Bereitstellung von Knoten mit GPU-Fähigkeiten zu verwalten. Diese Beschränkungen dienen dazu, die Gesamtressourcen aller Knoten im Pool zu begrenzen, wobei insgesamt bis zu 10 Instances zulässig sind. Jede Instanz kann entweder g5.xlarge (4 VCPUs, 16 GiB Arbeitsspeicher, 1 GPU) oder g5.2xlarge (8 VCPUs, 32 GiB Speicher, 1 GPU) sein, solange die Summe v 80 CPUs nicht überschreitet, der Gesamtspeicher 320 GiB nicht überschreitet und die Summe 10 nicht überschreitet. GPUs Der Pool kann beispielsweise 10 g5.2xlarge-Instances (80 vCPUs, 320 GiB, 10 GPUs) oder 10 g5.xlarge-Instances (40 v, 160 GiBCPUs, 10 GPUs) oder eine Mischung wie 5 g5.xlarge- und 5 g5.2xlarge (60 v, 240 GiB, 10 GPUs) bereitstellenCPUs, wodurch Flexibilität je nach Workload-Anforderungen gewährleistet und gleichzeitig Ressourcenbeschränkungen eingehalten werden.
Darüber hinaus geben wir die ID der Nvidia-Variante der Bottlerocket-AMI an. Schließlich legen wir eine UnterbrechungsrichtlinieconsolidateAfter: 30m) zu entfernen, und legen eine maximale Lebensdauer der Knoten auf 30 Tage (expireAfter: 720h) fest, um die Kosten zu optimieren und die Knotenintegrität für GPU-intensive Aufgaben aufrechtzuerhalten. Weitere Informationen finden Sie unter Deaktivieren von Karpenter Consolidation für unterbrechungssensitive Workloads und Verwenden Sie ttlSecondsAfter Finished to Auto Clean-Up Kubernetes-Jobs.
cat <<EOF | envsubst | kubectl apply -f - apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-a10g-inference-g5 spec: template: metadata: labels: role: gpu-worker gpu-type: nvidia-a10g spec: requirements: - key: node.kubernetes.io/instance-type operator: In values: ["g5.xlarge", "g5.2xlarge"] - key: "karpenter.sh/capacity-type" operator: In values: ["on-demand"] taints: - key: nvidia.com/gpu value: "true" effect: NoSchedule nodeClassRef: name: gpu-a10g-inference-ec2 group: karpenter.k8s.aws kind: EC2NodeClass expireAfter: 720h limits: cpu: "80" memory: "320Gi" nvidia.com/gpu: "10" disruption: consolidationPolicy: WhenEmpty consolidateAfter: 30m --- apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: gpu-a10g-inference-ec2 spec: amiFamily: Bottlerocket amiSelectorTerms: - id: ${NVIDIA_BOTTLEROCKET_AMI} role: "KarpenterNodeRole-${EKS_CLUSTER_NAME}" subnetSelectorTerms: - tags: karpenter.sh/discovery: "${EKS_CLUSTER_NAME}" securityGroupSelectorTerms: - tags: karpenter.sh/discovery: "${EKS_CLUSTER_NAME}" tags: nvidia.com/gpu: "true" EOF
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
nodepool.karpenter.sh/gpu-a10g-inference-g5 created ec2nodeclass.karpenter.k8s.aws/gpu-a10g-inference-ec2 created
Stellen Sie sicher, dass das erstellt wurde und fehlerfrei ist: NodePool
kubectl get nodepool gpu-a10g-inference-g5 -o yaml
Suchen Sie nach „status.conditionslike“ ValidationSucceeded: TrueNodeClassReady: True, und bestätigen Ready: True Sie, dass der NodePool fehlerfrei ist.
Richten Sie die CPU ein NodePool
Dabei NodePool haben wir Grenzwerte für die Unterstützung von etwa 50 Instances festgelegt, die auf eine moderate CPU-Arbeitslast (z. B. 100-200 Pods) und typische AWS vCPU-Kontingente (z. B. 128-1152) abgestimmt sind. Die Grenzwerte werden unter der Annahme berechnet, dass bis zu 50 m7.xlarge-Instances skaliert werden NodePool sollten: CPU (4 V CPUs pro Instanz × 50 Instanzen = 200 VCPUs) und Arbeitsspeicher (16 GiB pro Instanz × 50 Instanzen = 800 GiB). Diese Grenzwerte sind so konzipiert, dass sie die Gesamtressourcen auf allen Knoten im Pool begrenzen, sodass bis zu 50 m7g.xlarge-Instances (jeweils mit 4 V CPUs und 16 GiB Speicher) zulässig sind, sofern die Gesamt-V 200 CPUs nicht überschreiten und der Gesamtspeicher 800 GiB nicht überschreitet.
Darüber hinaus geben wir die ID der Standardvariante der Bottlerocket-AMI an. Schließlich legen wir eine UnterbrechungsrichtlinieconsolidateAfter: 60m) zu entfernen, und legen eine maximale Lebensdauer der Knoten auf 30 Tage (expireAfter: 720h) fest, um die Kosten zu optimieren und die Knotenintegrität für GPU-intensive Aufgaben aufrechtzuerhalten. Weitere Informationen finden Sie unter Deaktivieren von Karpenter Consolidation für unterbrechungssensitive Workloads und Verwenden Sie Fertig, um Kubernetes-Jobs automatisch zu bereinigen. ttlSecondsAfter
cat <<EOF | envsubst | kubectl apply -f - apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: cpu-inference-m7gxlarge spec: template: metadata: labels: role: cpu-worker spec: requirements: - key: node.kubernetes.io/instance-type operator: In values: ["m7g.xlarge"] - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] taints: - key: role value: cpu-intensive effect: NoSchedule nodeClassRef: name: cpu-inference-m7gxlarge-ec2 group: karpenter.k8s.aws kind: EC2NodeClass expireAfter: 720h limits: cpu: "200" memory: "800Gi" disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m --- apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: cpu-inference-m7gxlarge-ec2 spec: amiFamily: Bottlerocket amiSelectorTerms: - id: ${STANDARD_BOTTLEROCKET_AMI} role: "KarpenterNodeRole-${EKS_CLUSTER_NAME}" subnetSelectorTerms: - tags: karpenter.sh/discovery: "${EKS_CLUSTER_NAME}" securityGroupSelectorTerms: - tags: karpenter.sh/discovery: "${EKS_CLUSTER_NAME}" EOF
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
nodepool.karpenter.sh/cpu-inference-m7gxlarge created ec2nodeclass.karpenter.k8s.aws/cpu-inference-m7gxlarge-ec2 created
Stellen Sie sicher, dass das erstellt wurde und fehlerfrei ist: NodePool
kubectl get nodepool cpu-inference-m7gxlarge -o yaml
Suchen Sie nach „status.conditionslike“ ValidationSucceeded: TrueNodeClassReady: True, und bestätigen Ready: True Sie, dass der NodePool fehlerfrei ist.
5. Bereitstellung eines GPU-Pods zur Freigabe einer GPU
Sie benötigen das Nvidia-Geräte-Plugin, damit Kubernetes GPU-Geräte für den Kubernetes-Cluster freigeben kann. In der Regel müssten Sie das Plug-in als DaemonSet bereitstellen. Das Bottlerocket-AMI installiert das Plugin jedoch als Teil des AMI vor. Das heißt, wenn Sie Bottlerocket verwenden AMIs, müssen Sie das Nvidia-Geräte-Plugin nicht bereitstellen. DaemonSet Weitere Informationen finden Sie unter Kubernetes Device Plugin to Expose. GPUs
Bereitstellung eines Beispiel-Pods
Karpenter agiert dynamisch: Es stellt GPU-Knoten bereit, wenn eine Workload (Pod) GPU-Ressourcen anfordert. Um zu überprüfen, ob Pods Anfragen stellen und verwenden können GPUs, stellen Sie einen Pod bereit, der die nvidia.com/gpu Ressource innerhalb ihrer Limits anfordert (z. B.nvidia.com/gpu: 1). Weitere Informationen zu diesen Bezeichnungen finden Sie unter Planen von Workloads mit GPU-Anforderungen unter Verwendung bekannter Bezeichnungen.
cat <<EOF | envsubst | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: gpu-nvidia-smi spec: restartPolicy: OnFailure tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" nodeSelector: role: gpu-worker # Matches GPU NodePool's label containers: - name: cuda-container image: nvidia/cuda:12.9.1-base-ubuntu20.04 command: ["nvidia-smi"] resources: limits: nvidia.com/gpu: 1 requests: nvidia.com/gpu: 1 EOF
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
pod/gpu-ndivia-smi created
Warten Sie eine Minute und überprüfen Sie dann, ob der Pod den Status „Ausstehend“ContainerCreating, „Wird ausgeführt“ und dann den Status „Abgeschlossen“ hat:
kubectl get pod gpu-nvidia-smi -w
Stellen Sie sicher, dass der Knoten für den Pod zur GPU gehört NodePool:
kubectl get node $(kubectl get pod gpu-nvidia-smi -o jsonpath='{.spec.nodeName}') -o custom-columns="Name:.metadata.name,Nodepool:.metadata.labels.karpenter\.sh/nodepool"
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
Name Nodepool ip-192-168-83-245.ec2.internal gpu-a10g-inference-g5
Überprüfen Sie die Pod-Protokolle:
kubectl logs gpu-nvidia-smi
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
Thu Jul 17 04:31:33 2025 +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.148.08 Driver Version: 570.148.08 CUDA Version: 12.9 | |-----------------------------------------+----------------------+----------------------+ | 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 A10G On | 00000000:00:1E.0 Off | 0 | | 0% 30C P8 9W / 300W | 0MiB / 23028MiB | 0% Default | | | | N/A | +---------------------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | No running processes found | +---------------------------------------------------------------------------------------+
6. (Optional) Modell-Artefakte für die Bereitstellung vorbereiten und hochladen
In diesem Schritt stellen Sie einen Modell-Service für die Echtzeit-Image-Klassifizierung bereit, beginnend mit dem Hochladen der Modellgewichte in einen Amazon-S3-Bucket. Zur Demonstration verwenden wir das Open-Source-Modell GPUNet-0
So richten Sie Ihre Umgebung ein
Um die Gewichte des Modells GPUNet -0 herunterzuladen In diesem Schritt benötigen Sie Zugriff auf den NGC-Katalog von NVIDIA und müssen Docker
-
Registrieren Sie sich für ein kostenloses NGC-Konto
und generieren Sie einen API-Schlüssel über das NGC-Dashboard (Benutzersymbol > Einstellungen > API-Schlüssel generieren > Persönlichen Schlüssel generieren > NGC-Katalog). -
Laden Sie die NGC-CLI (Linux/macOS/Windows) herunter, installieren
Sie sie und konfigurieren Sie die CLI mit: ngc config set. Geben Sie Ihren API-Schlüssel ein, wenn Sie dazu aufgefordert werden. Setzen Sie „org“ aufnvidiaund drücken Sie die Eingabetaste, um die Standardeinstellungen für andere zu akzeptieren. Bei erfolgreicher Eingabe sollte etwa Folgendes angezeigt werden:Successfully saved NGC configuration to /Users/your-username/.ngc/config.
Verifizierung der Berechtigungen für Servicekonten
Bevor wir beginnen, überprüfen Sie die Berechtigungen des Kubernetes-Servicekontos:
kubectl get serviceaccount s3-csi-driver-sa -n kube-system -o yaml
Bei der Clustererstellung haben wir die CSIDriver S3-Richtlinie einer IAM-Rolle zugeordnet und das Dienstkonto mit Anmerkungen versehen („s3-csi-driver-sa“). Die Mountpoint-S3-CSI-Treiber-Pods übernehmen die Berechtigungen der IAM-Rolle, wenn sie mit S3 interagieren. Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::143095308808:role/eksctl-eks-rt-inference-us-east-1-addon-aws-m-Role1-fpXXjRYdKN8r creationTimestamp: "2025-07-17T03:55:29Z" labels: app.kubernetes.io/component: csi-driver app.kubernetes.io/instance: aws-mountpoint-s3-csi-driver app.kubernetes.io/managed-by: EKS app.kubernetes.io/name: aws-mountpoint-s3-csi-driver name: s3-csi-driver-sa namespace: kube-system resourceVersion: "2278" uid: 50b36272-6716-4c68-bdc3-c4054df1177c
Toleranz hinzufügen
Der S3-CSI-Treiber wird DaemonSet auf allen Knoten als a ausgeführt. Pods verwenden den CSI-Treiber auf diesen Knoten, um S3-Volumes einzubinden. Damit er auf unseren GPU-Knoten, die Fehler aufweisen, zeitgesteuert werden kann, fügen Sie folgende Toleranzen hinzu: DaemonSet
kubectl patch daemonset s3-csi-node -n kube-system --type='json' -p='[{"op": "add", "path": "/spec/template/spec/tolerations/-", "value": {"key": "nvidia.com/gpu", "operator": "Exists", "effect": "NoSchedule"}}]'
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
daemonset.apps/s3-csi-node patched
Modellgewichte in S3 hochladen
In diesem Schritt erstellen Sie einen Amazon S3 S3-Bucket, laden die GPUNet -0 Modellgewichte von NVIDIA GPU Cloud (NGC) herunter und laden sie in den Bucket hoch. Auf diese Gewichte greift unsere Anwendung zur Laufzeit für die Inferenz zu.
Erstellen Sie Ihren Amazon-S3-Bucket:
aws s3 mb s3://${S3_BUCKET_NAME} --region ${AWS_REGION}
Aktivieren Sie die S3-Versionsverwaltung für den Bucket, um zu verhindern, dass versehentliche Löschungen und Überschreibungen zu sofortigem und dauerhaftem Datenverlust führen:
aws s3api put-bucket-versioning --bucket ${S3_BUCKET_NAME} --versioning-configuration Status=Enabled
Wenden Sie eine Lebenszyklusregel auf den Bucket an, um überschriebene oder gelöschte Objektversionen 14 Tage nach ihrer Veraltung zu entfernen, abgelaufene Löschmarkierungen zu entfernen und unvollständige mehrteilige Uploads nach 7 Tagen zu entfernen. Weitere Informationen finden Sie unter Beispiele für S3-Lebenszykluskonfigurationen.
aws s3api put-bucket-lifecycle-configuration --bucket $S3_BUCKET_NAME --lifecycle-configuration '{"Rules":[{"ID":"LifecycleRule","Status":"Enabled","Filter":{},"Expiration":{"ExpiredObjectDeleteMarker":true},"NoncurrentVersionExpiration":{"NoncurrentDays":14},"AbortIncompleteMultipartUpload":{"DaysAfterInitiation":7}}]}'
Laden Sie die Gewichte des Modells GPUNet -0 von NGC herunter. Zum Beispiel unter macOS:
ngc registry model download-version nvidia/dle/gpunet_0_pyt_ckpt:21.12.0_amp --dest ~/downloads
Anmerkung
Möglicherweise müssen Sie diesen Download-Befehl an Ihr Betriebssystem anpassen. Damit dieser Befehl auf einem Linux-System funktioniert, müssen Sie das Verzeichnis wahrscheinlich als Teil des Befehls erstellen (z. B. mkdir ~/downloads).
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
{ "download_end": "2025-07-18 08:22:39", "download_start": "2025-07-18 08:22:33", "download_time": "6s", "files_downloaded": 1, "local_path": "/Users/your-username/downloads/gpunet_0_pyt_ckpt_v21.12.0_amp", "size_downloaded": "181.85 MB", "status": "Completed", "transfer_id": "gpunet_0_pyt_ckpt[version=21.12.0_amp]" }
Benennen Sie die Checkpoint-Datei so um, dass sie der erwarteten Benennung in unserem Anwendungscode in späteren Schritten entspricht (es ist kein Extrahieren erforderlich, da es sich um einen standardmäßigen PyTorch *.pth.tar-Checkpoint handelt, der das Modellstatuswörterbuch enthält):
mv ~/downloads/gpunet_0_pyt_ckpt_v21.12.0_amp/0.65ms.pth.tar gpunet-0.pth
Aktivieren Sie die AWS Common Runtime
aws configure set s3.preferred_transfer_client crt
Laden Sie die Modellgewichte in Ihren S3-Bucket hoch:
aws s3 cp gpunet-0.pth s3://${S3_BUCKET_NAME}/gpunet-0.pth
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
upload: ./gpunet-0.pth to s3://eks-rt-inference-models-us-east-1-1752722786/gpunet-0.pth
Modell-Service erstellen
In diesem Schritt richten Sie eine FastAPI-Webanwendung für die GPU-beschleunigte Bildklassifizierung mithilfe des GPUNet -0 Vision-Modells ein. Die Anwendung lädt zur Laufzeit Modellgewichte von Amazon S3 herunter, ruft die Modellarchitektur zum Zwischenspeichern aus dem NVIDIA-Repository ab und lädt ImageNet Klassenbezeichnungen über HTTP herunter. Die Anwendung beinhaltet Image-Vorverarbeitungstransformationen und stellt zwei Endpunkte bereit: einen Root-GET-Endpunkt /predict für die Statusüberprüfung und einen POST-Endpunkt, der eine Bild-URL akzeptiert.
Wir bieten das Modell mithilfe von FastAPI an und laden Gewichte zur Laufzeit aus Amazon S3 in einem containerisierten Setup für schnelles Prototyping und Kubernetes-Bereitstellung. PyTorch Weitere Methoden wie optimiertes Batching oder Hochdurchsatz-Engines finden Sie unter Bereitstellen von ML-Modellen.
Erstellen der Anwendung
Erstellen Sie ein Verzeichnis für Ihre Anwendungsdateien, z. B. model-testing, wechseln Sie dann in dieses Verzeichnis und fügen Sie den folgenden Code zu einer neuen Datei mit dem Namen app.py hinzu:
import os import torch import json import requests from fastapi import FastAPI, HTTPException from PIL import Image from io import BytesIO, StringIO import torchvision.transforms as transforms from torch.nn.functional import softmax import warnings from contextlib import redirect_stdout, redirect_stderr import argparse import boto3 app = FastAPI() # Suppress specific warnings from the model code (quantization is optional and unused here) warnings.simplefilter("ignore", UserWarning) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Load model code from cache (if present) # Use backed cache directory torch.hub.set_dir('/cache/torch/hub') # Allowlist for secure deserialization (handles potential issues in older checkpoints) torch.serialization.add_safe_globals([argparse.Namespace]) # Load the model architecture only on container startup (changed to pretrained=False) # Precision (FP32 for full accuracy, could be 'fp16' for speed on Ampere+ GPUs) with redirect_stdout(StringIO()), redirect_stderr(StringIO()): gpunet = torch.hub.load('NVIDIA/DeepLearningExamples:torchhub', 'nvidia_gpunet', pretrained=False, model_type='GPUNet-0', model_math='fp32') # Download weights from S3 if not present, then load them model_path = os.getenv('MODEL_PATH', '/cache/torch/hub/checkpoints/gpunet-0.pth') os.makedirs(os.path.dirname(model_path), exist_ok=True) # Ensure checkpoints dir exists if not os.path.exists(model_path): s3 = boto3.client('s3') s3.download_file(os.getenv('S3_BUCKET_NAME'), 'gpunet-0.pth', model_path) checkpoint = torch.load(model_path, map_location=device, weights_only=True) gpunet.load_state_dict(checkpoint['state_dict']) # Move to GPU/CPU gpunet.to(device) gpunet.eval() # Preprocessing preprocess = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) # Load ImageNet labels labels_url = "https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json" response = requests.get(labels_url) json_data = json.loads(response.text) labels = [json_data[str(i)][1].replace('_', ' ') for i in range(1000)] # Required, FastAPI root @app.get("/") async def hello(): return {"status": "hello"} # Serve model requests @app.post("/predict") async def predict(image_url: str): try: response = requests.get(image_url) response.raise_for_status() img = Image.open(BytesIO(response.content)).convert("RGB") input_tensor = preprocess(img).unsqueeze(0).to(device) with torch.no_grad(): output = gpunet(input_tensor) probs = softmax(output, dim=1)[0] top5_idx = probs.topk(5).indices.cpu().numpy() top5_probs = probs.topk(5).values.cpu().numpy() results = [{ "label": labels[idx], "probability": float(prob) } for idx, prob in zip(top5_idx, top5_probs)] return {"predictions": results} except Exception as e: raise HTTPException(status_code=400, detail=str(e))
Docker-Datei erstellen
Das folgende Dockerfile erstellt ein Container-Image für unsere Anwendung unter Verwendung des GPUNet Modells aus dem Repository NVIDIA
Wir reduzieren die Größe des Container-Images, indem wir eine reine PyTorch Runtime-Basis verwenden, nur wichtige Pakete mit Cache-Bereinigung installieren, Modellcode vorab zwischenspeichern und vermeiden, dass Gewichte im Container-Image „überbacken“ werden, um schnellere Abrufe und Updates zu ermöglichen. Weitere Informationen finden Sie unter Reduzieren der Größe von Container-Images.
Erstellen Sie im selben Verzeichnis wie app.py die Dockerfile:
FROM pytorch/pytorch:2.4.0-cuda12.4-cudnn9-runtime # Install required system packages required for git cloning RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* # Install application dependencies RUN pip install --no-cache-dir fastapi uvicorn requests pillow boto3 timm==0.5.4 # Pre-cache the GPUNet code from Torch Hub (without weights) # Clone the repository containing the GPUNet code RUN mkdir -p /cache/torch/hub && \ cd /cache/torch/hub && \ git clone --branch torchhub --depth 1 https://github.com/NVIDIA/DeepLearningExamples NVIDIA_DeepLearningExamples_torchhub COPY app.py /app/app.py WORKDIR /app CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]
Testen der Anwendung
Erstellen Sie das Container-Image für die Inferenzanwendung aus demselben Verzeichnis wie Ihr app.py und Dockerfile erstellen Sie dabei die folgende Architektur: AMD64
docker build --platform linux/amd64 -t gpunet-inference-app .
Legen Sie Umgebungsvariablen für Ihre AWS Anmeldeinformationen und optional ein AWS Sitzungstoken fest. Beispiel:
export AWS_REGION="us-east-1" export AWS_ACCESS_KEY_ID=ABCEXAMPLESCUJFEIELSMUHHAZ export AWS_SECRET_ACCESS_KEY=123EXAMPLEMZREoQXr8XkiicsOgWDQ5TpUsq0/Z
Führen Sie den Container lokal aus und fügen Sie AWS Anmeldeinformationen als Umgebungsvariablen für den S3-Zugriff ein. Beispiel:
docker run --platform linux/amd64 -p 8080:80 \ -e S3_BUCKET_NAME=${S3_BUCKET_NAME} \ -e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ -e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ -e AWS_DEFAULT_REGION=${AWS_REGION} \ gpunet-inference-app
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
INFO: Started server process [1] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
Testen Sie in einem neuen Terminalfenster den Inferenz-Endpunkt, indem Sie eine Beispiel-POST-Anfrage mit einer öffentlichen Image-URL als Abfrageparameter senden:
curl -X POST "http://localhost:8080/predict?image_url=http://images.cocodataset.org/test-stuff2017/000000024309.jpg"
Die erwartete Ausgabe sollte eine JSON-Antwort mit den fünf besten Prognosen sein, ähnlich wie hier (die tatsächlichen Bezeichnungen und Wahrscheinlichkeiten können je nach Image und Modellgenauigkeit leicht variieren):
{"predictions":[{"label":"desk","probability":0.28885871171951294},{"label":"laptop","probability":0.24679335951805115},{"label":"notebook","probability":0.08539070934057236},{"label":"library","probability":0.030645888298749924},{"label":"monitor","probability":0.02989606373012066}]}
Beenden Sie die Anwendung mit „Strg + C“.
Übertragen des Containers an Amazon ECR
In diesem Schritt laden wir das Container-Image für den Service GPUNet -0 Model in Amazon Elastic Container Registry (ECR) hoch, sodass es für die Bereitstellung auf Amazon EKS verfügbar ist. Dieser Prozess umfasst die Erstellung eines neuen ECR-Repositorys zur Speicherung des Images, die Authentifizierung bei ECR sowie das Kennzeichnen und Übertragen des Container-Images in unsere Registry.
Navigieren Sie zunächst zurück zu dem Verzeichnis, in dem Sie zu Beginn dieser Anleitung Ihre Umgebungsvariablen festgelegt haben. Beispiel:
cd ..
Erstellen Sie ein Repository in Amazon ECR:
aws ecr create-repository --repository-name gpunet-inference-app --region ${AWS_REGION}
Melden Sie sich bei Amazon ECR an:
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
Login Succeeded
Kennzeichnen Sie das Image:
docker tag gpunet-inference-app:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/gpunet-inference-app:latest
Übertragen Sie das Image in Ihr Amazon-ECR-Repository:
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/gpunet-inference-app:latest
Dieser letzte Schritt kann einige Minuten in Anspruch nehmen.
7. (Optional) Modell-Service verfügbar machen
In diesem Schritt stellen Sie Ihren Echtzeit-Inferenzmodell-Service mithilfe des Load AWS Balancer Controllers (LBC) extern auf Amazon EKS zur Verfügung. Dazu gehört die Einrichtung des LBC, die Bereitstellung von Modellgewichten aus Amazon S3 als persistentes Volume mithilfe des Mountpoint-S3-CSI-Treibers, die Bereitstellung eines GPU-beschleunigten Anwendungs-Pods, die Erstellung eines Services und eines Ingresses zur Bereitstellung eines Application Load Balancer (ALB) sowie das Testen des Endpunkts.
Überprüfen Sie zunächst die Pod-Identity-Zuordnung für den AWS LBC und stellen Sie sicher, dass das Dienstkonto ordnungsgemäß mit der erforderlichen IAM-Rolle verknüpft ist:
eksctl get podidentityassociation --cluster ${EKS_CLUSTER_NAME} --namespace kube-system --service-account-name aws-load-balancer-controller
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
ASSOCIATION ARN NAMESPACE SERVICE ACCOUNT NAME IAM ROLE ARN OWNER ARN arn:aws:eks:us-east-1:143095308808:podidentityassociation/eks-rt-inference-us-east-1/a-buavluu2wp1jropya kube-system aws-load-balancer-controller arn:aws:iam::143095308808:role/AmazonEKSLoadBalancerControllerRole
Kennzeichnen Ihrer Cluster-Sicherheitsgruppe
Der Load AWS Balancer Controller unterstützt nur eine einzige Sicherheitsgruppe mit dem Tag-Schlüssel karpenter.sh/discovery: "${EKS_CLUSTER_NAME}" für die Sicherheitsgruppenauswahl von Karpenter. Beim Erstellen eines Clusters mit eksctl wird die Standard-Cluster-Sicherheitsgruppe (die das "kubernetes.io/cluster/<cluster-name>: owned"-Tag hat) nicht automatisch mit karpenter.sh/discovery-Tags versehen. Dieses Tag ist für Karpenter unerlässlich, um diese Sicherheitsgruppe zu erkennen und den bereitgestellten Knoten zuzuordnen. Durch das Anhängen dieser Sicherheitsgruppe wird die Kompatibilität mit dem Load AWS Balancer Controller (LBC) gewährleistet, sodass dieser automatisch Regeln für eingehenden Datenverkehr für Dienste verwalten kann, die über Ingress verfügbar gemacht werden, z. B. den Modelldienst in diesen Schritten.
Exportieren Sie die VPC-ID für Ihren Cluster:
CLUSTER_VPC_ID="$(aws eks describe-cluster --name ${EKS_CLUSTER_NAME} --query cluster.resourcesVpcConfig.vpcId --output text)"
Exportieren Sie die Standard-Sicherheitsgruppe für Ihren Cluster:
CLUSTER_SG_ID="$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=$CLUSTER_VPC_ID Name=tag-key,Values=kubernetes.io/cluster/${EKS_CLUSTER_NAME} --query 'SecurityGroups[].[GroupId]' --output text)"
Fügen Sie das karpenter.sh/discovery-Tag zur Standard-Cluster-Sicherheitsgruppe hinzu. Dadurch können unsere CPU- und EC2 NodeClass GPU-Selektoren sie verwenden:
aws ec2 create-tags --resources ${CLUSTER_SG_ID} --tags Key=karpenter.sh/discovery,Value=${EKS_CLUSTER_NAME}
Überprüfen Sie, ob das Tag hinzugefügt wurde:
aws ec2 describe-security-groups --group-ids ${CLUSTER_SG_ID} --query "SecurityGroups[].Tags"
Unter den Ergebnissen sollten Sie Folgendes mit dem Tag und Ihrem Cluster-Namen sehen. Beispiel:
{ "Key": "karpenter.sh/discovery", "Value": "eks-rt-inference-us-east-1" }
Den AWS Load Balancer Controller (LBC) einrichten
Der AWS LBC ist unverzichtbar für die Verwaltung des eingehenden Datenverkehrs zu AI/ML Workloads auf Amazon EKS und gewährleistet den Zugriff auf Inferenzendpunkte oder Datenverarbeitungspipelines. Durch die Integration mit AWS Application Load Balancers (ALB) und Network Load Balancers (NLB) leitet der LBC den Datenverkehr dynamisch an containerisierte Anwendungen weiter, z. B. solche, auf denen umfangreiche Sprachmodelle, Computer-Vision-Modelle oder Echtzeit-Inferenzdienste ausgeführt werden. Da wir das Servicekonto und die Pod-Identity-Zuordnung bereits bei der Erstellung des Clusters erstellt haben, legen wir den serviceAccount.name so fest, dass er mit der Definition in unserer Cluster-Konfiguration übereinstimmt (aws-load-balancer-controller).
Fügen Sie das Helm-Chart-Repository von -own eks-charts hinzu: AWS
helm repo add eks https://aws.github.io/eks-charts
Aktualisieren Sie Ihre lokalen Helm-Repositorys mit den neuesten Diagrammen:
helm repo update eks
Stellen Sie das AWS LBC mithilfe von Helm bereit, geben Sie den Namen des EKS-Clusters an und verweisen Sie auf das vorab erstellte Dienstkonto:
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ -n kube-system \ --set clusterName=${EKS_CLUSTER_NAME} \ --set serviceAccount.create=false \ --set serviceAccount.name=aws-load-balancer-controller
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
NAME: aws-load-balancer-controller LAST DEPLOYED: Wed Jul 9 15:03:31 2025 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: AWS Load Balancer controller installed!
Einbinden des Modells in ein persistentes Volume
In diesem Schritt mounten Sie Modellgewichte aus Ihrem Amazon S3-Bucket mithilfe eines PersistentVolume (PV), das vom Mountpoint for Amazon S3 CSI-Treiber unterstützt wird. Dadurch können Kubernetes-Pods auf S3-Objekte als lokale Dateien zugreifen, wodurch ressourcenintensive Downloads in flüchtige Pod-Speicher oder Init-Container vermieden werden – ideal für große Modellgewichte mit mehreren Gigabyte.
Die PV bindet die gesamte Bucket-Root ein (kein Pfad in volumeAttributes angegeben), unterstützt den gleichzeitigen Lesezugriff durch mehrere Pods und macht Dateien wie die Modellgewichte (/models/gpunet-0.pth) innerhalb des Containers für die Inferenz verfügbar. Dadurch wird sichergestellt, dass der Fallback-„Download“ in unserer Anwendung (app.py) nicht ausgelöst wird, da die Datei über das Mount vorhanden ist. Durch die Entkopplung des Modells vom Container-Image werden der gemeinsame Zugriff und unabhängige Modellversionsaktualisierungen ohne Image-Neuerstellung ermöglicht.
Erstellen Sie den PersistentVolume (PV)
Erstellen Sie eine PersistentVolume (PV-) Ressource, um den S3-Bucket zu mounten, der Ihre Modellgewichte enthält, und ermöglichen Sie so den schreibgeschützten Zugriff für mehrere Pods, ohne dass Dateien zur Laufzeit heruntergeladen werden müssen:
cat <<EOF | envsubst | kubectl apply -f - apiVersion: v1 kind: PersistentVolume metadata: name: s3-model-pv spec: capacity: storage: 5Gi # Ignored by the driver; can be any value accessModes: - ReadOnlyMany # Read only persistentVolumeReclaimPolicy: Retain storageClassName: "" # Required for static provisioning claimRef: namespace: default # Adjust if you prefer a different namespace name: s3-model-pvc mountOptions: - allow-other # Enables multi-user access (useful for non-root pods) - region ${AWS_REGION} # Optional, include if your bucket is in a different region than the cluster csi: driver: s3.csi.aws.com volumeHandle: gpunet-model-volume # Must be unique across all PVs volumeAttributes: bucketName: ${S3_BUCKET_NAME} EOF
Erstellen Sie das PersistentVolumeClaim (PVC)
Erstellen Sie ein PersistentVolumeClaim (PVC), das an das PV gebunden werden soll, und fordern Sie schreibgeschützten Zugriff auf die Daten des bereitgestellten S3-Modells an:
cat <<EOF | envsubst | kubectl apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: s3-model-pvc spec: accessModes: - ReadOnlyMany storageClassName: "" # Required for static provisioning resources: requests: storage: 5Gi # Ignored, match PV capacity volumeName: s3-model-pv # Bind to the PV created above EOF
Bereitstellen der Anwendung
Stellen Sie die Inferenz-Anwendung als Kubernetes-Bereitstellung bereit, indem Sie das S3-gestützte persistente Volume für den Modellzugriff mounten, GPU-Knotenselektoren und Toleranzen anwenden und Umgebungsvariablen für den Modellpfad festlegen. Diese Bereitstellung legt den Modellpfad (Umgebungsvariable von "/models/gpunet-0.pth") fest, sodass unsere Anwendung (in app.py) standardmäßig diesen Pfad verwendet Wenn das Volume der Bereitstellung in /models (schreibgeschützt) eingebunden ist, wird der Modell-Download nicht ausgelöst, wenn die Datei bereits über das PVC vorhanden ist.
cat <<EOF | envsubst | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: gpunet-inference-app spec: replicas: 1 selector: matchLabels: app: gpunet-inference-app template: metadata: labels: app: gpunet-inference-app spec: tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" nodeSelector: role: gpu-worker containers: - name: inference image: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/gpunet-inference-app:latest ports: - containerPort: 80 env: - name: MODEL_PATH value: "/models/gpunet-0.pth" resources: limits: nvidia.com/gpu: 1 requests: nvidia.com/gpu: 1 volumeMounts: - name: model-volume mountPath: /models readOnly: true volumes: - name: model-volume persistentVolumeClaim: claimName: s3-model-pvc EOF
Es kann einige Minuten dauern, bis Karpenter einen GPU-Knoten bereitstellt, falls noch keiner verfügbar ist. Überprüfen Sie, ob sich der Inferenz-Pod im Status „Ausgeführt“ befindet:
kubectl get pods -l app=gpunet-inference-app
Die erwartete Ausgabe sollte in etwa wie folgt aussehen:
NAME READY STATUS RESTARTS AGE gpunet-inference-app-5d4b6c7f8-abcde 1/1 Running 0 2m
Service mit Ingress und Load Balancer verfügbar machen
Erstellen Sie einen ClusterIP- Service, um die Inferenz-Bereitstellung intern innerhalb des EKS-Clusters freizugeben, wobei Sie den Port der Anwendung als Ziel angeben:
cat <<EOF | envsubst | kubectl apply -f - apiVersion: v1 kind: Service metadata: name: gpunet-model-service spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: app: gpunet-inference-app EOF
Erstellen Sie eine Ingress-Ressource, um einen mit dem Internet verbundenen Application Load Balancer (ALB) über den AWS LBC bereitzustellen und externen Datenverkehr an den Inferenzdienst weiterzuleiten:
cat <<EOF | envsubst | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gpunet-model-ingress annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: ingressClassName: alb rules: - http: paths: - path: / pathType: Prefix backend: service: name: gpunet-model-service port: number: 80 EOF
Warten Sie einige Minuten, bis der Application Load Balancer (ALB) die Bereitstellung abgeschlossen hat. Überwachen Sie den Status der Ingress-Ressource, um sicherzustellen, dass der ALB bereitgestellt wurde:
kubectl get ingress gpunet-model-ingress
Die erwartete Ausgabe sollte wie folgt aussehen (mit ausgefülltem Feld ADRESSE):
NAME CLASS HOSTS ADDRESS PORTS AGE gpunet-model-ingress alb * k8s-default-gpunetmo-183de3f819-516310036.us-east-1.elb.amazonaws.com 80 6m58s
Extrahieren und exportieren Sie den ALB-Host-Namen aus dem Ingress-Status zur Verwendung in nachfolgenden Tests:
export ALB_HOSTNAME=$(kubectl get ingress gpunet-model-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
Modell-Service testen
Validieren Sie den freigegebenen Inferenzendpunkt, indem Sie eine POST-Anfrage mit einer Beispielbild-URL (z. B. aus dem COCO-Datensatz) senden und so eine Echtzeit-Prognose simulieren:
curl -X POST "http://${ALB_HOSTNAME}/predict?image_url=http://images.cocodataset.org/test-stuff2017/000000024309.jpg"
Die erwartete Ausgabe sollte eine JSON-Antwort mit den fünf besten Prognosen sein, ähnlich wie hier (die tatsächlichen Bezeichnungen und Wahrscheinlichkeiten können je nach Image und Modellgenauigkeit leicht variieren):
{"predictions":[{"label":"desk","probability":0.2888975441455841},{"label":"laptop","probability":0.2464350312948227},{"label":"notebook","probability":0.08554483205080032},{"label":"library","probability":0.030612602829933167},{"label":"monitor","probability":0.029896672815084457}]}
Optional können Sie in einer neuen POST-Anfrage mit dem Testen anderer Images fortfahren. Beispiel:
http://images.cocodataset.org/test-stuff2017/000000024309.jpg http://images.cocodataset.org/test-stuff2017/000000028117.jpg http://images.cocodataset.org/test-stuff2017/000000006149.jpg http://images.cocodataset.org/test-stuff2017/000000004954.jpg
Schlussfolgerung
In diesem Handbuch richten Sie einen Amazon-EKS-Cluster ein, der für GPU-beschleunigte Echtzeit-Inferenz-Workloads optimiert ist. Sie haben einen Cluster mit G5 EC2-Instances
Bereinigen
Um future Gebühren zu vermeiden, müssen Sie den zugehörigen CloudFormation Stack manuell löschen, um alle in diesem Handbuch erstellten Ressourcen, einschließlich des VPC-Netzwerks, zu löschen.
Löschen Sie den CloudFormation Stack mithilfe des --wait Flags mit eksctl:
eksctl delete cluster --region ${AWS_REGION} --name ${EKS_CLUSTER_NAME} --wait
Nach Abschluss des Vorgangs sollte die folgende Antwort angezeigt werden:
2025-07-29 13:03:55 [✔] all cluster resources were deleted
Löschen Sie den in dieser Anleitung erstellten Amazon-S3-Bucket mithilfe der Amazon-S3-Konsole