

 **Bantu tingkatkan halaman ini** 

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Untuk berkontribusi pada panduan pengguna ini, pilih **Edit halaman ini pada GitHub** tautan yang terletak di panel kanan setiap halaman.

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Panduan Pengaturan Kluster Praktik Terbaik untuk Inferensi Waktu Nyata di Amazon EKS
<a name="ml-realtime-inference-cluster"></a>

**Tip**  
 [Daftar](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el) untuk AI/ML lokakarya Amazon EKS mendatang.

## Pengantar
<a name="_introduction"></a>

Panduan ini menawarkan panduan langsung untuk menyiapkan kluster Amazon Elastic Kubernetes Service (EKS) Amazon Elastic yang dioptimalkan untuk beban kerja inferensi online real-time, menggabungkan praktik terbaik yang dikuratori oleh para ahli di seluruh dunia. AWS Ini menggunakan Arsitektur EKS Quickstart yang berpendirian — serangkaian driver, tipe instans, dan konfigurasi yang dikuratori yang selaras dengan AWS praktik terbaik untuk model, akselerator, dan penskalaan. Pendekatan ini membantu Anda melewati tugas memilih pengaturan cluster, memungkinkan Anda untuk mendapatkan cluster fungsional yang telah dikonfigurasi sebelumnya dan berjalan dengan cepat. Sepanjang jalan, kami akan menerapkan contoh beban kerja untuk memvalidasi penyiapan Anda, menjelaskan konsep arsitektur utama (seperti memisahkan tugas terikat CPU dari komputasi intensif GPU), menjawab pertanyaan umum (misalnya, mengapa memilih Bottlerocket AMI di atas?) AL2023 , dan uraikan langkah selanjutnya untuk memperluas kemampuan cluster Anda.

Dirancang khusus untuk insinyur Machine Learning dan Artificial Intelligence (AI), administrator platform, operator, dan data/AI spesialis yang baru mengenal ekosistem AWS dan EKS, panduan ini mengasumsikan keakraban dengan Kubernetes tetapi tidak memiliki pengalaman EKS sebelumnya. Ini dirancang untuk membantu Anda memahami langkah-langkah dan proses yang diperlukan untuk mendapatkan beban kerja inferensi online real-time dan berjalan. Panduan ini menunjukkan kepada Anda hal-hal penting dalam membuat cluster inferensi simpul tunggal, termasuk penyediaan sumber daya GPU, mengintegrasikan penyimpanan untuk artefak model, mengaktifkan akses layanan yang aman, dan mengekspos titik akhir inferensi. AWS Secara keseluruhan, ini menekankan latensi rendah, desain tangguh untuk aplikasi yang dihadapi pengguna seperti deteksi penipuan, chatbot waktu nyata, dan analisis sentimen dalam sistem umpan balik pelanggan.

Dalam panduan ini, kami fokus secara eksklusif pada pengaturan titik awal yang mendasar dan preskriptif menggunakan instans G5 EC2. Jika Anda mencari konfigurasi atau end-to-end alur kerja klaster AWS khusus Inferensia, lihat [Menggunakan instans AWS Inferentia dengan Amazon EKS untuk Machine Learning](inferentia-support.md) atau lokakarya kami di. [Sumber daya untuk memulai AI/ML di Amazon EKS](ml-resources.md)

## Sebelum Anda mulai
<a name="_before_you_begin"></a>

Sebelum memulai, pastikan Anda telah melakukan tugas-tugas berikut:
+  [Siapkan lingkungan Anda untuk Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/setting-up.html) 
+  [Instal versi terbaru eksctl](https://eksctl.io/installation/) 
+  [Instal Helm](https://helm.sh/docs/intro/install/) 
+  [(Opsional) Instal Docker](https://docs.docker.com/get-started/) 
+  [(Opsional) Instal NGC CLI](https://org.ngc.nvidia.com/setup/installers/cli) 

## Arsitektur
<a name="_architecture"></a>

Inferensi online real-time mengacu pada proses menggunakan model pembelajaran mesin terlatih untuk menghasilkan prediksi atau output pada aliran data yang masuk dengan latensi minimal. Misalnya, memungkinkan deteksi penipuan real-time, klasifikasi gambar, atau pembuatan grafik pengetahuan dalam menanggapi input pengguna. Arsitektur sistem inferensi online real-time memberikan prediksi pembelajaran mesin latensi rendah dalam aplikasi yang dihadapi pengguna dengan memisahkan penanganan lalu lintas web terikat CPU dari komputasi AI intensif GPU. Proses ini biasanya hidup dalam ekosistem aplikasi yang lebih besar, dan seringkali mencakup layanan backend, frontend, vektor, dan model, dengan fokus pada komponen khusus untuk memungkinkan penskalaan independen, pengembangan paralel, dan ketahanan terhadap kegagalan. Mengisolasi tugas inferensi pada perangkat keras GPU khusus dan memanfaatkan antarmuka seperti APIs dan WebSockets memastikan konkurensi tinggi, pemrosesan model yang cepat seperti transformator, dan interaksi pengguna melalui frontend. Perhatikan bahwa meskipun database vektor dan pipeline Retrieval Augmented Generation (RAG) sering memainkan peran besar dalam sistem inferensi waktu nyata, komponen ini tidak tercakup dalam panduan ini. Minimal, arsitektur khas sering kali mencakup:
+  **Layanan Frontend**: Berfungsi sebagai antarmuka yang menghadap pengguna, menangani logika sisi klien, merender konten dinamis, dan memfasilitasi interaksi waktu nyata, berkomunikasi dengan layanan backend untuk memulai permintaan inferensi dan menampilkan hasil, sering kali memulai permintaan ke layanan backend yang digunakan untuk streaming pembaruan atau untuk pertukaran data terstruktur. WebSockets APIs Layanan ini biasanya tidak memerlukan penyeimbang beban khusus, karena dapat di-host di jaringan pengiriman konten (CDNs) seperti AWS CloudFront untuk aset statis atau disajikan langsung dari server web, dengan penskalaan ditangani melalui grup auto-scaling jika diperlukan untuk konten dinamis.
+  **Layanan Backend**: Bertindak sebagai orkestrator aplikasi, mengelola logika bisnis seperti otentikasi pengguna, validasi data, dan koordinasi layanan (misalnya, melalui APIs untuk titik akhir atau untuk RESTful koneksi persisten). WebSockets Ini berkomunikasi dengan layanan inferensi, menskalakan secara independen pada multi-core CPUs dan RAM untuk menangani lalu lintas web yang tinggi tanpa mengandalkan GPUs, dan seringkali memerlukan penyeimbang beban (seperti AWS Application Load Balancer atau Network Load Balancer) untuk mendistribusikan permintaan masuk di beberapa instance, terutama dalam skenario konkurensi tinggi. Pengontrol ingress selanjutnya dapat mengelola akses eksternal dan aturan perutean untuk meningkatkan keamanan dan pembentukan lalu lintas.
+  **Layanan Inferensi**: Berfungsi sebagai inti untuk perhitungan AI, berjalan GPUs dengan VRAM yang cukup (misalnya, 8-12 GB untuk model seperti DistiLbert) untuk melakukan penyematan vektor, ekstraksi pengetahuan, dan inferensi model (misalnya, diekspos melalui permintaan batch atau APIs untuk streaming waktu nyata) menggunakan model kustom atau WebSockets sumber terbuka. Isolasi ini mencegah konflik ketergantungan, memungkinkan pembaruan model tanpa waktu henti, dan memungkinkan penskalaan horizontal dengan penyeimbangan beban untuk beberapa permintaan bersamaan. Untuk mengekspos layanan model secara efektif, biasanya berada di belakang penyeimbang beban untuk mendistribusikan beban kerja terikat GPU di seluruh instance yang direplikasi, sementara sumber daya masuk atau pengontrol (seperti ALB Ingress Controller in AWS) menangani perutean eksternal, penghentian SSL, dan penerusan berbasis jalur untuk memastikan akses yang aman dan efisien tanpa membebani individu. GPUs

## Ikhtisar Solusi
<a name="_solution_overview"></a>

Sistem inferensi online real-time membutuhkan kinerja tinggi, arsitektur tangguh yang dapat memberikan latensi ultra-rendah sambil menangani ledakan lalu lintas volume tinggi yang tidak dapat diprediksi. Ikhtisar solusi ini menjelaskan bagaimana AWS komponen berikut bekerja sama di klaster Amazon EKS yang akan kami buat untuk memastikan klaster kami dapat meng-host dan mengelola model pembelajaran mesin yang memberikan prediksi langsung pada data langsung dengan penundaan minimal bagi pengguna akhir.
+  [Instans Amazon G5 EC2 — Untuk tugas inferensi intensif GPU, kami menggunakan tipe instans](https://aws.amazon.com/ec2/instance-types/g5/) G5 EC2 g5.xlarge dan g5.2xlarge, yang menampilkan satu (1) GPU NVIDIA A10G dengan memori 24GB (mis., 8 miliar parameter di FP16). Berdasarkan Arsitektur NVIDIA Ampere, GPU ini ditenagai oleh GPU NVIDIA A10G Tensor Core dan prosesor AMD EPYC generasi ke-2, mendukung 4-8 VCPU, bandwidth jaringan hingga 10 Gbps, dan penyimpanan SSD NVMe lokal 250-450 GB, memastikan pergerakan data cepat dan daya komputasi untuk model yang kompleks, menjadikannya ideal untuk tugas inferensi latensi rendah dan throughput tinggi. Memilih jenis instans EC2 adalah spesifik aplikasi, tergantung pada model Anda (misalnya, gambar, video, model teks), serta persyaratan latensi dan throughput Anda. Misalnya, jika menggunakan model gambar dan atau video, Anda mungkin ingin menggunakan [instans P5 EC2](https://aws.amazon.com/ec2/instance-types/p5/) untuk latensi real-time yang optimal. Kami merekomendasikan memulai dengan [instans G5 EC2](https://aws.amazon.com/ec2/instance-types/g5/) karena menyediakan titik awal yang baik untuk bangun dan berjalan dengan cepat, kemudian mengevaluasi apakah itu cocok untuk beban kerja Anda melalui pengujian benchmark kinerja. Untuk kasus yang lebih lanjut, pertimbangkan instans [G6 EC2](https://aws.amazon.com/ec2/instance-types/g6/).
+  [Instans Amazon EC2 M7g](https://aws.amazon.com/ec2/instance-types/m7g/) - Untuk tugas intensif CPU seperti pra-pemrosesan data, penanganan permintaan API, hosting pengontrol Karpenter, add-on, dan komponen sistem lainnya, kami menggunakan tipe instans m5.xlarge m7g EC2. Instans M7g adalah instance berbasis ARM yang memiliki memori 4 vCPUs, 16 GB, bandwidth jaringan hingga 12,5 Gbps, dan didukung oleh prosesor Graviton3. AWS Memilih jenis instans EC2 adalah spesifik aplikasi dan bergantung pada persyaratan komputasi, memori, dan skalabilitas beban kerja Anda. Untuk beban kerja yang dioptimalkan komputasi, Anda dapat mempertimbangkan instans [C7g EC2, yang juga menggunakan prosesor Graviton3 tetapi dioptimalkan untuk kinerja komputasi yang lebih tinggi daripada instans](https://aws.amazon.com/ec2/instance-types/c7g/) M7g untuk kasus penggunaan tertentu. Atau, instans [C8g EC2 yang lebih baru (jika tersedia) memberikan kinerja komputasi hingga 30% lebih baik daripada instans](https://aws.amazon.com/ec2/instance-types/c8g/) C7g. Kami merekomendasikan memulai dengan instans M7g EC2 untuk efisiensi biaya dan kompatibilitasnya dengan berbagai beban kerja (misalnya, server aplikasi, layanan mikro, server game, penyimpanan data ukuran sedang), kemudian mengevaluasi apakah itu cocok untuk beban kerja Anda melalui pengujian benchmark kinerja.
+  [Driver CSI Amazon S3 Mountpoint](https://docs.aws.amazon.com/eks/latest/userguide/s3-csi.html) — Untuk beban kerja pada instans GPU tunggal di mana beberapa pod berbagi GPU (misalnya, beberapa pod yang dijadwalkan pada node yang sama untuk memanfaatkan sumber daya GPU-nya), kami menggunakan Driver CSI Mountpoint S3 untuk mengoptimalkan penggunaan memori—penting untuk tugas-tugas seperti inferensi model besar dalam pengaturan yang sensitif biaya dan kompleksitas rendah. Ini mengekspos bucket Amazon S3 sebagai sistem file seperti POSIX yang tersedia untuk cluster Kubernetes, yang memungkinkan pod inferensi untuk membaca artefak model (misalnya, bobot model) langsung ke memori tanpa harus mengunduhnya terlebih dahulu, dan memasukkan kumpulan data menggunakan operasi file standar. Selain itu, S3 memiliki kapasitas penyimpanan yang hampir tidak terbatas dan mempercepat beban kerja inferensi intensif data. Memilih driver CSI penyimpanan adalah aplikasi khusus, dan tergantung pada throughput beban kerja dan persyaratan latensi Anda. Meskipun [FSx untuk OpenZFS CSI Driver](https://docs.aws.amazon.com/eks/latest/userguide/fsx-openzfs-csi.html) menawarkan latensi sub-milidetik untuk volume persisten bersama yang acak I/O atau sepenuhnya sesuai POSIX di seluruh node, kami merekomendasikan untuk memulai dengan Driver Mountpoint S3 CSI karena skalabilitasnya, biaya yang lebih rendah untuk kumpulan data besar, dan integrasi bawaan dengan penyimpanan objek yang dikelola S3 untuk pola inferensi baca-berat (misalnya, input model streaming), kemudian mengevaluasi apakah itu cocok untuk pekerjaan Anda beban melalui pengujian benchmark kinerja.
+  [Agen Identitas Pod EKS](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html) — Untuk mengaktifkan akses ke AWS layanan, kami menggunakan Agen Identitas Pod EKS, yang menggunakan prinsip layanan tunggal dan memfasilitasi asosiasi peran IAM tingkat pod dalam klaster Amazon EKS. EKS Pod Identity menawarkan alternatif yang efisien untuk pendekatan [IAM Roles for Service Accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) tradisional dengan memanfaatkan prinsip layanan tunggal (pods.eks.amazonaws.com) alih-alih mengandalkan penyedia OIDC individual untuk setiap cluster, yang membuatnya lebih mudah untuk menetapkan izin. Selain itu, ini memungkinkan peran untuk digunakan kembali di beberapa cluster dan mendukung fitur-fitur canggih seperti [tag sesi peran IAM dan peran](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html) IAM [Target](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-assign-target-role.html).
+  [Agen Pemantauan Node EKS](https://docs.aws.amazon.com/eks/latest/userguide/node-health.html) — Untuk memastikan ketersediaan dan keandalan layanan inferensi yang berkelanjutan, kami menggunakan Agen Pemantauan Node EKS dengan Perbaikan Otomatis, yang secara otomatis mendeteksi dan menggantikan node yang tidak sehat, meminimalkan waktu henti. Ini terus memantau node untuk masalah perangkat keras, kernel, jaringan, dan penyimpanan menggunakan pemeriksaan kesehatan yang ditingkatkan (misalnya, KernelReady, NetworkingReady). Untuk node GPU, ia mendeteksi kegagalan khusus akselerator, memulai remediasi yang anggun dengan menutup node yang tidak sehat, menunggu 10 menit untuk menyelesaikan masalah GPU sementara, dan mengganti node setelah 30 menit untuk kegagalan persisten.
+  [Bottlerocket AMI](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami-bottlerocket.html) — Untuk memberikan fondasi keamanan yang diperkuat untuk cluster EKS kami, kami menggunakan AMI Bottlerocket, yang hanya mencakup komponen penting yang diperlukan untuk menjalankan kontainer dan menawarkan waktu boot minimal untuk penskalaan cepat. Memilih node AMI bersifat spesifik untuk aplikasi dan bergantung pada persyaratan penyesuaian, keamanan, dan skalabilitas beban kerja Anda. Meskipun [AL2023 AMI](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html) memberikan fleksibilitas yang lebih besar untuk instalasi dan penyesuaian tingkat host (misalnya, menentukan direktori cache khusus dalam PV/PVC tanpa konfigurasi node tambahan), kami sarankan memulai dengan AMI Bottlerocket untuk footprint yang lebih kecil dan pengoptimalan bawaan untuk beban kerja kontainer (misalnya, layanan mikro, server inferensi, dapat APIs diskalakan), kemudian mengevaluasi apakah itu cocok untuk beban kerja Anda melalui benchmark kinerja pengujian.
+  [AWS Load Balancer Controller (LBC)](https://docs.aws.amazon.com/eks/latest/userguide/lbc-helm.html) — Untuk mengekspos endpoint inferensi real-time, kami menggunakan Load Balancer Controller, yang secara otomatis menyediakan dan mengelola Application AWS Load Balancers () untuk lalu lintas dan Network Load Balancers (ALBs) untuk HTTP/HTTPS lalu TCP/UDP lintas berdasarkan sumber daya Ingress dan Service Kubernetes, memungkinkan integrasi model inferensi dengan klien eksternal. NLBs Selain itu, ia mendukung fitur seperti routing berbasis jalur untuk mendistribusikan permintaan inferensi di beberapa pod atau node, memastikan skalabilitas selama lonjakan lalu lintas dan meminimalkan latensi melalui optimasi AWS-native seperti multiplexing koneksi dan pemeriksaan kesehatan.

## 1. Buat kluster EKS Anda
<a name="_1_create_your_eks_cluster"></a>

Pada langkah ini, kita membuat cluster dengan node CPU dan grup node terkelola menggunakan template AWS CloudFormation [ClusterConfig](https://eksctl.io/usage/creating-and-managing-clusters/)eksctl -powered. Menginisialisasi cluster dengan hanya node CPU memungkinkan kita untuk menggunakan Karpenter secara eksklusif untuk mengelola CPU-intensif dan node GPU untuk alokasi sumber daya yang dioptimalkan menggunakan NodePools Karpenter yang kita buat di langkah selanjutnya. [https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html](https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html) Instans m7g.xlarge akan digunakan untuk tugas-tugas sistem CPU, termasuk hosting kontroler Karpenter, add-on, dan komponen sistem lainnya.

Secara default, `eksctl` akan membuat VPC khusus untuk cluster dengan blok CIDR. `192.168.0.0/16` VPC mencakup tiga subnet publik dan tiga subnet pribadi, masing-masing didistribusikan di tiga Availability Zone yang berbeda (atau dua AZs di `us-east-1` wilayah tersebut) yang merupakan metode ideal untuk menerapkan beban kerja Kubernetes. Template ini juga menyebarkan gateway internet, menyediakan akses internet ke subnet publik melalui rute default di tabel rute mereka dan gateway NAT tunggal di salah satu subnet publik, dengan rute default di tabel rute subnet pribadi mengarahkan lalu lintas keluar melalui gateway NAT untuk akses internet. Untuk mempelajari lebih lanjut tentang pengaturan ini, lihat [Menerapkan Node ke Subnet Pribadi](https://docs.aws.amazon.com/eks/latest/best-practices/subnets.html#_deploy_nodes_to_private_subnets).

### Periksa kredensyal Anda
<a name="_check_your_credentials"></a>

Periksa apakah AWS kredensi CLI Anda valid dan dapat mengautentikasi dengan layanan: AWS 

```
aws sts get-caller-identity
```

Jika berhasil, CLI akan mengembalikan detail tentang AWS identitas Anda (UserId, Akun, dan Arn).

### Periksa ketersediaan instans
<a name="_check_instance_availability"></a>

Jenis instans G5 tidak tersedia di semua wilayah. Periksa wilayah terdekat Anda. Contoh:

```
aws ec2 describe-instance-types --instance-types g5.xlarge g5.2xlarge --region us-east-1
```

Jika berhasil, jenis instans G5 tersedia di wilayah yang Anda tentukan.

The Bottlerocket AMI tidak tersedia di semua wilayah. Periksa dengan mengambil ID AMI Bottlerocket untuk wilayah terdekat Anda. Contoh:

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

Jika berhasil, AMI Bottlerocket tersedia di wilayah yang Anda tentukan.

### Persiapkan lingkungan Anda
<a name="_prepare_your_environment"></a>

Pertama, atur variabel lingkungan berikut di jendela terminal baru. **Catatan**[: Pastikan untuk mengganti placeholder sampel dengan nilai unik Anda, termasuk nama cluster, wilayah yang Anda inginkan, [versi rilis Karpenter, dan versi](https://github.com/kubernetes-sigs/karpenter/releases) Kubernetes.](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)

**Tip**  
Beberapa variabel (seperti `${AWS_REGION}` dan`${K8S_VERSION}`) didefinisikan di awal blok dan kemudian direferensikan dalam perintah selanjutnya untuk konsistensi dan untuk menghindari pengulangan. Pastikan untuk menjalankan perintah secara berurutan sehingga nilai-nilai ini diekspor dengan benar dan tersedia untuk digunakan dalam definisi berikutnya.

```
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/')"
```

### Buat peran dan kebijakan yang diperlukan
<a name="_create_required_roles_and_policies"></a>

Karpenter membutuhkan peran dan kebijakan IAM tertentu (misalnya, peran IAM controller Karpenter, profil instance, dan kebijakan) untuk mengelola instans EC2 sebagai node pekerja Kubernetes. Ini menggunakan peran ini untuk melakukan tindakan seperti meluncurkan dan menghentikan instans EC2, menandai sumber daya, dan berinteraksi dengan layanan lain. AWS [Buat peran dan kebijakan Karpenter menggunakan cloudformation.yaml Karpenter:](https://raw.githubusercontent.com/aws/karpenter-provider-aws/v1.5.0/website/content/en/preview/getting-started/getting-started-with-karpenter/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}"
```

 AWS LBC memerlukan izin untuk menyediakan dan mengelola penyeimbang AWS beban, seperti membuat sumber daya Ingress atau ALBs NLBs untuk jenis layanan. `LoadBalancer` Kami akan menentukan kebijakan izin ini selama pembuatan klaster. Selama pembuatan cluster, kami akan membuat akun layanan dengan eksctl di. ClusterConfig Buat kebijakan IAM LBC:

```
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)"
```

Ketika Driver Mountpoint S3 CSI diinstal, DaemonSet podnya dikonfigurasi untuk menggunakan akun layanan untuk dieksekusi. Driver Mountpoint untuk Mountpoint S3 CSI memerlukan izin untuk berinteraksi dengan bucket Amazon S3 yang Anda buat nanti dalam panduan ini. Kami akan menentukan kebijakan izin ini selama pembuatan klaster. Selama pembuatan cluster, kami akan membuat akun layanan dengan eksctl di. ClusterConfig Buat kebijakan IAM S3:

```
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}/*\"]}]}"
```

 **Catatan**: jika peran sudah ada dengan nama ini, beri peran nama yang berbeda. Peran yang kami buat dalam langkah ini khusus untuk cluster dan bucket S3 Anda.

### Buat cluster
<a name="_create_the_cluster"></a>

Dalam template ini, eksctl secara otomatis membuat akun layanan Kubernetes untuk EKS Pod Identity, Node Monitoring Agent, CoreDNS, Kubeproxy, Plugin VPC CNI. [Sampai hari ini, Driver Mountpoint S3 CSI tidak tersedia untuk EKS Pod Identity, jadi kami membuat IAM Roles for Service Account (IRSA) dan endpoint OIDC.](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html) Selain itu, kami membuat akun layanan untuk AWS Load Balancer Controller (LBC). Untuk akses ke node Bottlerocket, eksctl secara otomatis melampirkan SSMManaged InstanceCore Amazon untuk Bottlerocket untuk memungkinkan sesi shell aman melalui SSM.

Di terminal yang sama tempat Anda mengatur variabel lingkungan, jalankan blok perintah berikut untuk membuat cluster:

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

Proses ini membutuhkan waktu beberapa menit untuk menyelesaikannya. Jika Anda ingin memantau status, lihat [AWS CloudFormation](https://console.aws.amazon.com/cloudformation)konsol.

## 2. Verifikasi Kesehatan Node dan Pod Cluster
<a name="_2_verify_cluster_node_and_pod_health"></a>

Mari kita lakukan beberapa pemeriksaan kesehatan untuk memastikan cluster siap. Ketika perintah sebelumnya selesai, lihat jenis instance dan verifikasi bahwa node sistem CPU Anda telah mencapai `Ready` status dengan perintah berikut:

```
kubectl get nodes -L node.kubernetes.io/instance-type
```

Output yang diharapkan akan terlihat seperti ini:

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

Verifikasi semua asosiasi Identitas Pod dan bagaimana mereka memetakan peran ke akun layanan di namespace di klaster dengan perintah berikut:

```
eksctl get podidentityassociation --cluster ${EKS_CLUSTER_NAME} --region ${AWS_REGION}
```

Output harus menunjukkan peran IAM untuk Karpenter (“karpenter”) dan AWS LBC (” “). aws-load-balancer-controller

Verifikasi DaemonSets yang tersedia:

```
kubectl get daemonsets -n kube-system
```

Output yang diharapkan akan terlihat seperti ini:

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

Verifikasi semua addons diinstal pada cluster:

```
eksctl get addons --cluster ${EKS_CLUSTER_NAME} --region ${AWS_REGION}
```

Output yang diharapkan akan terlihat seperti ini:

```
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. Instal Karpenter
<a name="_3_install_karpenter"></a>

Instal pengontrol Karpenter pada node pekerja CPU Anda (`cpu-worker`) untuk mengoptimalkan biaya dan menghemat sumber daya GPU. Kami akan menginstalnya di namespace “kube-system” dan menentukan akun layanan “karpenter” yang kami tentukan selama pembuatan cluster. Selain itu, perintah ini mengonfigurasi nama cluster dan antrian interupsi Instance Spot untuk node CPU. Karpenter akan menggunakan IRSA untuk mengambil peran IAM ini.

```
# 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
```

Output yang diharapkan akan terlihat seperti ini:

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

Verifikasi bahwa Karpenter sedang berjalan:

```
kubectl get pods -n kube-system -l app.kubernetes.io/name=karpenter
```

Output yang diharapkan akan terlihat seperti ini:

```
NAME                       READY   STATUS    RESTARTS   AGE
karpenter-555895dc-865bc   1/1     Running   0          5m58s
karpenter-555895dc-j7tk9   1/1     Running   0          5m58s
```

## 4. Pengaturan Karpenter NodePools
<a name="_4_setup_karpenter_nodepools"></a>

[Pada langkah ini, kami mengkonfigurasi CPU dan GPU Karpenter yang saling eksklusif. NodePools](https://karpenter.sh/docs/concepts/nodepools/) `limits`Bidang dalam NodePool spesifikasi membatasi total sumber daya maksimum (misalnya, CPU, memori, GPUs) yang NodePool dapat dikonsumsi masing-masing di semua node yang disediakan, mencegah penyediaan node tambahan jika batas ini terlampaui. Sementara NodePools mendukung kategori instans luas (misalnya,`c`,`g`), menentukan [jenis instans tertentu, jenis](https://karpenter.sh/docs/concepts/nodepools/#instance-types) [kapasitas](https://karpenter.sh/docs/concepts/nodepools/#capacity-type), dan [batasan](https://karpenter.sh/docs/concepts/nodepools/#speclimits) sumber daya membantu Anda memperkirakan biaya untuk beban kerja sesuai permintaan dengan lebih mudah. Dalam hal ini NodePools, kami menggunakan beragam jenis instance dalam keluarga instance G5. Hal ini memungkinkan Karpenter untuk secara otomatis memilih jenis instance yang paling tepat berdasarkan permintaan sumber daya pod, mengoptimalkan pemanfaatan sumber daya sambil menghormati batas total. NodePool Untuk mempelajari lebih lanjut, lihat [Membuat NodePools](https://docs.aws.amazon.com/eks/latest/best-practices/karpenter.html#_creating_nodepools).

### Siapkan GPU NodePool
<a name="_setup_the_gpu_nodepool"></a>

Dalam hal ini NodePool, kami menetapkan batas sumber daya untuk mengelola penyediaan node dengan kemampuan GPU. Batas ini dirancang untuk membatasi total sumber daya di semua node di pool, memungkinkan hingga 10 instance secara total. Setiap instance dapat berupa g5.xlarge (4 v, memori CPUs 16 GiB, 1 GPU) atau g5.2xlarge (8 vCPUs, memori 32 GiB, 1 GPU), selama total CPUs v tidak melebihi 80, total memori tidak melebihi 320GiB, dan total tidak melebihi 10. GPUs Misalnya, kumpulan dapat menyediakan 10 instans g5.2xlarge (80 v, CPUs 320 GiB, 10), atau 10 instans g5.xlarge (40 v, 160 GiB, 10 GPUs)CPUs, atau campuran seperti 5 g5.xlarge dan 5 g5.2xlarge (60 v, 240 GiB, GPUs 10), memastikan fleksibilitas berdasarkan tuntutan beban kerja sambil menghormati kendala sumber daya. CPUs GPUs

Selain itu, kami menentukan ID varian Nvidia dari AMI Bottlerocket. Akhirnya, kami menetapkan [kebijakan gangguan](https://karpenter.sh/docs/concepts/disruption/#nodepool-disruption-budgets) untuk menghapus node kosong setelah 30 menit (`consolidateAfter: 30m`) dan menetapkan masa pakai node maksimum 30 hari (`expireAfter: 720h`) untuk mengoptimalkan biaya dan menjaga kesehatan node untuk tugas-tugas intensif GPU. Untuk mempelajari lebih lanjut, lihat [Menonaktifkan Konsolidasi Karpenter untuk beban kerja sensitif interupsi](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-compute.html#_disable_karpenter_consolidation_for_interruption_sensitive_workloads), dan [Gunakan Pekerjaan Kubernetes yang ttlSecondsAfter Selesai untuk](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-compute.html#_use_ttlsecondsafterfinished_to_auto_clean_up_kubernetes_jobs) Membersihkan Otomatis.

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

Output yang diharapkan akan terlihat seperti ini:

```
nodepool.karpenter.sh/gpu-a10g-inference-g5 created
ec2nodeclass.karpenter.k8s.aws/gpu-a10g-inference-ec2 created
```

Verifikasi NodePool dibuat dan sehat:

```
kubectl get nodepool gpu-a10g-inference-g5 -o yaml
```

Carilah `status.conditions` suka`ValidationSucceeded: True`,`NodeClassReady: True`, dan `Ready: True` untuk memastikan bahwa NodePool itu sehat.

### Siapkan CPU NodePool
<a name="_setup_the_cpu_nodepool"></a>

Dalam hal ini NodePool, kami menetapkan batas untuk mendukung sekitar 50 instance, menyelaraskan dengan beban kerja CPU moderat (misalnya, 100-200 pod) dan kuota AWS vCPU tipikal (misalnya, 128-1152). Batas dihitung dengan asumsi skala NodePool harus hingga 50 m7.xlarge instance: CPU (4 v CPUs per instance × 50 instance = 200 v) CPUs dan memori (16 GiB per instance × 50 instance = 800 GiB). Batas ini dirancang untuk membatasi total sumber daya di semua node di kolam, memungkinkan hingga 50 m7g.xlarge instance (masing-masing dengan memori 4 v dan CPUs 16 GiB), selama total v tidak melebihi 200 dan total memori CPUs tidak melebihi 800GiB.

Selain itu, kami menentukan ID varian standar AMI Bottlerocket. Akhirnya, kami menetapkan [kebijakan gangguan](https://karpenter.sh/docs/concepts/disruption/#nodepool-disruption-budgets) untuk menghapus node kosong setelah 60 menit (`consolidateAfter: 60m`) dan menetapkan masa pakai node maksimum 30 hari (`expireAfter: 720h`) untuk mengoptimalkan biaya dan menjaga kesehatan node untuk tugas-tugas intensif GPU. Untuk mempelajari lebih lanjut, lihat [Menonaktifkan Konsolidasi Karpenter untuk beban kerja sensitif interupsi](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-compute.html#_disable_karpenter_consolidation_for_interruption_sensitive_workloads), dan [Gunakan Pekerjaan Kubernetes yang ttlSecondsAfter Selesai untuk](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-compute.html#_use_ttlsecondsafterfinished_to_auto_clean_up_kubernetes_jobs) Membersihkan Otomatis.

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

Output yang diharapkan akan terlihat seperti ini:

```
nodepool.karpenter.sh/cpu-inference-m7gxlarge created
ec2nodeclass.karpenter.k8s.aws/cpu-inference-m7gxlarge-ec2 created
```

Verifikasi NodePool dibuat dan sehat:

```
kubectl get nodepool cpu-inference-m7gxlarge -o yaml
```

Carilah `status.conditions` suka`ValidationSucceeded: True`,`NodeClassReady: True`, dan `Ready: True` untuk memastikan bahwa NodePool itu sehat.

## 5. Menerapkan Pod GPU untuk Mengekspos GPU
<a name="_5_deploy_a_gpu_pod_to_expose_a_gpu"></a>

Anda memerlukan Plugin Perangkat Nvidia untuk mengaktifkan Kubernetes mengekspos perangkat GPU ke cluster Kubernetes. Biasanya, Anda perlu menerapkan plugin sebagai DaemonSet; Namun, AMI Bottlerocket melakukan pra-instal plugin sebagai bagian dari AMI. Itu berarti saat menggunakan Bottlerocket AMIs, tidak perlu menggunakan plugin perangkat Nvidia. DaemonSet Untuk mempelajari lebih lanjut, lihat [Plugin Perangkat Kubernetes](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-compute.html#_use_kubernetes_device_plugin_for_exposing_gpus) untuk mengekspos. GPUs

### Menerapkan pod sampel
<a name="_deploy_a_sample_pod"></a>

Karpenter bertindak secara dinamis: ia menyediakan node GPU ketika beban kerja (pod) meminta sumber daya GPU. Untuk memverifikasi bahwa pod dapat meminta dan menggunakan GPUs, gunakan pod yang meminta `nvidia.com/gpu` sumber daya dalam batasnya (misalnya,`nvidia.com/gpu: 1`). Untuk mempelajari lebih lanjut tentang label ini, lihat [Menjadwalkan beban kerja dengan persyaratan GPU menggunakan label Terkenal](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-compute.html#_schedule_workloads_with_gpu_requirements_using_well_known_labels).

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

Output yang diharapkan akan terlihat seperti ini:

```
pod/gpu-nvidia-smi created
```

Beri waktu sebentar kemudian periksa apakah Pod memiliki status “Pending”, “ContainerCreating,” “Running,” lalu status “Completed”:

```
kubectl get pod gpu-nvidia-smi -w
```

Verifikasi node untuk pod milik GPU 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"
```

Output yang diharapkan akan terlihat seperti ini:

```
Name                             Nodepool
ip-192-168-83-245.ec2.internal   gpu-a10g-inference-g5
```

Periksa log pod:

```
kubectl logs gpu-nvidia-smi
```

Output yang diharapkan akan terlihat seperti ini:

```
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. (Opsional) Siapkan dan Unggah Artefak Model untuk Penerapan
<a name="_6_optional_prepare_and_upload_model_artifacts_for_deployment"></a>

Pada langkah ini, Anda akan menerapkan layanan model untuk klasifikasi gambar real-time, dimulai dengan mengunggah bobot model ke bucket Amazon S3. Untuk demonstrasi, kami menggunakan bagian model visi open-source [GPUNet-0](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/dle/models/gpunet_0_pyt_ckpt) dari NVIDIA [GPUNet](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/dle/resources/gpunet_pyt), yang mendukung inferensi latensi rendah pada gambar menggunakan NVIDIA dan TensorRT. GPUs Model ini sudah dilatih sebelumnya [ImageNet](https://www.image-net.org/), memungkinkan kita untuk mengklasifikasikan objek dalam foto atau aliran video dengan cepat, dan dianggap sebagai model kecil dengan 11, 9 juta parameter.

### Siapkan lingkungan Anda
<a name="_set_up_your_environment"></a>

Untuk mengunduh bobot model GPUNet -0 Pada langkah ini, Anda memerlukan akses ke katalog NGC NVIDIA dan [Docker](https://docs.docker.com/get-started/) yang diinstal pada mesin lokal Anda. Ikuti langkah-langkah ini untuk menyiapkan akun gratis dan mengonfigurasi CLI NGC:
+  [Daftar untuk mendapatkan akun NGC gratis](https://ngc.nvidia.com/signup) dan buat kunci API dari dasbor NGC (Ikon Pengguna> Pengaturan > Hasilkan Kunci API> Hasilkan Kunci Pribadi > Katalog NGC).
+  [Unduh dan instal NGC CLI](https://org.ngc.nvidia.com/setup/installers/cli) Linux/macOS/Windows () dan konfigurasikan CLI menggunakan:. `ngc config set` Masukkan kunci API Anda saat diminta; atur org ke `nvidia` dan tekan Enter untuk menerima default untuk orang lain. Jika berhasil, Anda akan melihat sesuatu seperti:`Successfully saved NGC configuration to /Users/your-username/.ngc/config`.

### Verifikasi izin akun layanan
<a name="_verify_service_account_permissions"></a>

Sebelum kita mulai, periksa izin akun layanan Kubernetes:

```
kubectl get serviceaccount s3-csi-driver-sa -n kube-system -o yaml
```

Selama pembuatan klaster, kami melampirkan CSIDriver Kebijakan S3 ke peran IAM dan membuat anotasi akun layanan (“s3- “). csi-driver-sa Pod driver Mountpoint S3 CSI mewarisi izin peran IAM saat berinteraksi dengan S3. Output yang diharapkan akan terlihat seperti ini:

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

### Tambahkan toleransi
<a name="_add_a_toleration"></a>

Driver S3 CSI berjalan sebagai DaemonSet pada semua node. Pod menggunakan driver CSI pada node tersebut untuk memasang volume S3. Untuk memungkinkannya menjadwalkan pada node GPU kami yang memiliki noda, tambahkan toleransi ke: 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"}}]'
```

Output yang diharapkan akan terlihat seperti ini:

```
daemonset.apps/s3-csi-node patched
```

### Unggah bobot model ke S3
<a name="_upload_model_weights_to_s3"></a>

Pada langkah ini, Anda akan membuat bucket Amazon S3, mengunduh bobot model GPUNet -0 dari NVIDIA GPU Cloud (NGC), dan mengunggahnya ke bucket. Bobot ini akan diakses oleh aplikasi kami saat runtime untuk inferensi.

Buat bucket Amazon S3 Anda:

```
aws s3 mb s3://${S3_BUCKET_NAME} --region ${AWS_REGION}
```

Aktifkan [Pembuatan Versi S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html) untuk bucket, untuk mencegah penghapusan dan penimpaan yang tidak disengaja menyebabkan kehilangan data langsung dan permanen:

```
aws s3api put-bucket-versioning --bucket ${S3_BUCKET_NAME} --versioning-configuration Status=Enabled
```

Terapkan aturan siklus hidup ke bucket untuk menghapus versi objek yang ditimpa atau dihapus 14 hari setelah tidak berlaku, hapus penanda hapus kedaluwarsa, dan hapus unggahan multi-bagian yang tidak lengkap setelah 7 hari. Untuk mempelajari lebih lanjut, lihat [Contoh konfigurasi Siklus Hidup S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-configuration-examples.html).

```
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}}]}'
```

Unduh bobot model GPUNet -0 dari NGC. Misalnya, di macOS:

```
ngc registry model download-version nvidia/dle/gpunet_0_pyt_ckpt:21.12.0_amp --dest ~/downloads
```

**catatan**  
Anda mungkin perlu menyesuaikan perintah unduhan ini untuk sistem operasi Anda. Agar perintah ini bekerja pada sistem Linux, Anda mungkin perlu membuat direktori sebagai bagian dari perintah (misalnya,`mkdir ~/downloads`).

Output yang diharapkan akan terlihat seperti ini:

```
{
  "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]"
}
```

Ganti nama file pos pemeriksaan agar sesuai dengan penamaan yang diharapkan dalam kode aplikasi kami di langkah selanjutnya (tidak diperlukan ekstraksi, karena ini adalah pos pemeriksaan standar PyTorch \*.pth.tar yang berisi kamus status model):

```
mv ~/downloads/gpunet_0_pyt_ckpt_v21.12.0_amp/0.65ms.pth.tar gpunet-0.pth
```

Aktifkan [Runtime AWS Umum](https://aws.amazon.com/blogs/storage/improving-amazon-s3-throughput-for-the-aws-cli-and-boto3-with-the-aws-common-runtime/) di AWS CLI untuk mengoptimalkan throughput S3:

```
aws configure set s3.preferred_transfer_client crt
```

Unggah bobot model ke bucket S3 Anda:

```
aws s3 cp gpunet-0.pth s3://${S3_BUCKET_NAME}/gpunet-0.pth
```

Output yang diharapkan akan terlihat seperti ini:

```
upload: ./gpunet-0.pth to s3://eks-rt-inference-models-us-east-1-1752722786/gpunet-0.pth
```

### Buat Layanan Model
<a name="_create_the_model_service"></a>

Pada langkah ini, Anda akan menyiapkan aplikasi web FasTapi untuk klasifikasi gambar yang dipercepat GPU menggunakan model visi GPUNet -0. Aplikasi mengunduh bobot model dari Amazon S3 saat runtime, mengambil arsitektur model dari repositori NVIDIA untuk caching, dan mengunduh label kelas melalui HTTP. ImageNet Aplikasi ini mencakup transformasi prapemrosesan gambar dan mengekspos dua titik akhir: GET root untuk pemeriksaan status dan `/predict` titik akhir POST yang menerima URL gambar.

Kami melayani model menggunakan FastAP dengan PyTorch, memuat bobot dari Amazon S3 saat runtime dalam pengaturan kontainer untuk pembuatan prototipe cepat dan penerapan Kubernetes. Untuk metode lain seperti batching yang dioptimalkan atau engine throughput tinggi, lihat [Melayani](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-performance.html#_serving_ml_models) Model ML.

#### Buat aplikasi
<a name="_create_the_application"></a>

Buat direktori untuk file aplikasi Anda seperti`model-testing`, lalu ubah direktori ke dalamnya dan tambahkan kode berikut ke file baru bernama`app.py`:

```
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))
```

#### Buat Dockerfile
<a name="_create_the_dockerfile"></a>

Dockerfile berikut membuat gambar kontainer untuk aplikasi kami menggunakan GPUNet model dari [NVIDIA Deep Learning Examples for Tensor](https://github.com/NVIDIA/DeepLearningExamples) Cores repositori. GitHub 

Kami mengurangi ukuran gambar kontainer dengan menggunakan PyTorch basis runtime saja, menginstal hanya paket penting dengan pembersihan cache, kode model pra-caching, dan menghindari bobot “memanggang” dalam gambar kontainer untuk memungkinkan penarikan dan pembaruan yang lebih cepat. Untuk mempelajari lebih lanjut, lihat [Mengurangi Ukuran Gambar Kontainer](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-performance.html#_reducing_container_image_sizes).

Di direktori yang sama dengan`app.py`, buat`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"]
```

#### Uji aplikasi
<a name="_test_the_application"></a>

Dari direktori yang sama dengan Anda `app.py` dan`Dockerfile`, buat image kontainer untuk aplikasi inferensi, menargetkan arsitektur AMD64 :

```
docker build --platform linux/amd64 -t gpunet-inference-app .
```

Tetapkan variabel lingkungan untuk AWS kredensil Anda, dan secara opsional token sesi. AWS Contoh:

```
export AWS_REGION="us-east-1"
export AWS_ACCESS_KEY_ID=ABCEXAMPLESCUJFEIELSMUHHAZ
export AWS_SECRET_ACCESS_KEY=123EXAMPLEMZREoQXr8XkiicsOgWDQ5TpUsq0/Z
```

Jalankan kontainer secara lokal, menyuntikkan AWS kredensil sebagai variabel lingkungan untuk akses S3. Contoh:

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

Output yang diharapkan akan terlihat seperti ini:

```
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)
```

Di jendela terminal baru, uji titik akhir inferensi dengan mengirimkan contoh permintaan POST dengan URL gambar publik sebagai parameter kueri:

```
curl -X POST "http://localhost:8080/predict?image_url=http://images.cocodataset.org/test-stuff2017/000000024309.jpg"
```

Output yang diharapkan harus berupa respons JSON dengan prediksi 5 teratas, mirip dengan ini (label dan probabilitas aktual mungkin sedikit berbeda berdasarkan presisi gambar dan model):

```
{"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}]}
```

Keluar dari aplikasi menggunakan “Ctrl\+C”.

### Dorong wadah ke Amazon ECR
<a name="_push_the_container_to_amazon_ecr"></a>

Pada langkah ini, kami mengunggah gambar penampung untuk layanan model GPUNet -0 ke [Amazon Elastic Container Registry (ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html), membuatnya tersedia untuk penyebaran di Amazon EKS. Proses ini melibatkan pembuatan repositori ECR baru untuk menyimpan gambar, mengautentikasi dengan ECR, lalu menandai dan mendorong gambar kontainer ke registri kami.

Pertama, navigasikan kembali ke direktori tempat Anda mengatur variabel lingkungan di awal panduan ini. Contoh:

```
cd ..
```

Buat repositori di Amazon ECR:

```
aws ecr create-repository --repository-name gpunet-inference-app --region ${AWS_REGION}
```

Masuk ke Amazon ECR:

```
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
```

Output yang diharapkan akan terlihat seperti ini:

```
Login Succeeded
```

Tandai gambar:

```
docker tag gpunet-inference-app:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/gpunet-inference-app:latest
```

Dorong gambar ke repositori Amazon ECR Anda:

```
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/gpunet-inference-app:latest
```

Langkah terakhir ini membutuhkan waktu beberapa menit untuk menyelesaikannya.

## 7. (Opsional) Paparkan Layanan Model
<a name="_7_optional_expose_the_model_service"></a>

Pada langkah ini, Anda akan mengekspos layanan model inferensi real-time Anda secara eksternal di Amazon EKS menggunakan Load AWS Balancer Controller (LBC). Ini melibatkan pengaturan LBC, memasang bobot model dari Amazon S3 sebagai volume persisten menggunakan Driver CSI Mountpoint S3, menerapkan pod aplikasi yang dipercepat GPU, membuat layanan dan ingress untuk menyediakan Application Load Balancer (ALB), dan menguji titik akhir.

Pertama, verifikasi asosiasi Pod Identity untuk AWS LBC, dengan mengonfirmasi bahwa akun layanan ditautkan dengan benar ke peran IAM yang diperlukan:

```
eksctl get podidentityassociation --cluster ${EKS_CLUSTER_NAME} --namespace kube-system --service-account-name aws-load-balancer-controller
```

Output yang diharapkan akan terlihat seperti ini:

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

### Tandai grup keamanan klaster Anda
<a name="_tag_your_cluster_security_group"></a>

 AWS Load Balancer Controller hanya mendukung satu grup keamanan dengan kunci tag `karpenter.sh/discovery: "${EKS_CLUSTER_NAME}"` untuk pemilihan grup keamanan Karpenter. Saat membuat cluster dengan eksctl, grup keamanan cluster default (yang memiliki `"kubernetes.io/cluster/<cluster-name>: owned"` tag) tidak secara otomatis ditandai dengan tag. `karpenter.sh/discovery` Tag ini penting bagi Karpenter untuk menemukan dan melampirkan grup keamanan ini ke node yang disediakannya. Melampirkan grup keamanan ini memastikan kompatibilitas dengan AWS Load Balancer Controller (LBC), memungkinkannya untuk secara otomatis mengelola aturan lalu lintas masuk untuk layanan yang diekspos melalui Ingress, seperti layanan model dalam langkah-langkah ini.

Ekspor ID VPC untuk klaster Anda:

```
CLUSTER_VPC_ID="$(aws eks describe-cluster --name ${EKS_CLUSTER_NAME} --query cluster.resourcesVpcConfig.vpcId --output text)"
```

Ekspor grup keamanan default untuk klaster Anda:

```
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)"
```

Tambahkan `karpenter.sh/discovery` tag ke grup keamanan klaster default. Ini akan memungkinkan EC2 NodeClass pemilih CPU dan GPU kami untuk menggunakannya:

```
aws ec2 create-tags --resources ${CLUSTER_SG_ID} --tags Key=karpenter.sh/discovery,Value=${EKS_CLUSTER_NAME}
```

Verifikasi tag telah ditambahkan:

```
aws ec2 describe-security-groups --group-ids ${CLUSTER_SG_ID} --query "SecurityGroups[].Tags"
```

Di antara hasilnya, Anda akan melihat yang berikut dengan tag dan nama cluster Anda. Contoh:

```
{
  "Key": "karpenter.sh/discovery",
  "Value": "eks-rt-inference-us-east-1"
}
```

### Siapkan AWS Load Balancer Controller (LBC)
<a name="setup_the_shared_aws_load_balancer_controller_lbc"></a>

 AWS LBC sangat penting untuk mengelola lalu lintas masuk ke beban AI/ML kerja di Amazon EKS, memastikan akses ke titik akhir inferensi atau saluran pemrosesan data. Dengan mengintegrasikan dengan AWS Application Load Balancers (ALB) dan Network Load Balancers (NLB), LBC secara dinamis merutekan lalu lintas ke aplikasi kontainer, seperti yang menjalankan model bahasa besar, model visi komputer, atau layanan inferensi real-time. Karena kami telah membuat akun layanan dan Asosiasi Identitas Pod selama pembuatan klaster, kami menetapkan `serviceAccount.name` untuk mencocokkan apa yang didefinisikan dalam konfigurasi klaster kami (`aws-load-balancer-controller`).

Tambahkan repositori AWS**bagan Helm eks-charts** milik:

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

Segarkan repositori Helm lokal Anda dengan bagan terbaru:

```
helm repo update eks
```

Terapkan AWS LBC menggunakan Helm, tentukan nama cluster EKS dan referensikan akun layanan yang telah dibuat sebelumnya:

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

Output yang diharapkan akan terlihat seperti ini:

```
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!
```

### Pasang model dalam volume persisten
<a name="_mount_the_model_in_a_persistent_volume"></a>

Pada langkah ini, Anda akan memasang bobot model dari bucket Amazon S3 Anda menggunakan (PV) PersistentVolume yang didukung oleh driver Mountpoint untuk Amazon S3 CSI. Hal ini memungkinkan pod Kubernetes untuk mengakses objek S3 sebagai file lokal, menghilangkan unduhan intensif sumber daya ke penyimpanan pod sementara atau kontainer init—ideal untuk bobot model multi-gigabyte yang besar.

PV memasang seluruh root bucket (tidak ada jalur yang ditentukan`volumeAttributes`), mendukung akses hanya-baca bersamaan oleh beberapa pod, dan mengekspos file seperti model weights (`/models/gpunet-0.pth`) di dalam container untuk inferensi. Ini memastikan fallback “download” di aplikasi kami (`app.py`) tidak terpicu karena file ada melalui mount. Dengan memisahkan model dari gambar kontainer, ini memungkinkan akses bersama dan pembaruan versi model independen tanpa pembuatan ulang gambar.

#### Buat PersistentVolume (PV)
<a name="_create_the_persistentvolume_pv"></a>

Buat sumber daya PersistentVolume (PV) untuk memasang bucket S3 yang berisi bobot model Anda, memungkinkan akses hanya-baca untuk beberapa pod tanpa mengunduh file saat runtime:

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

#### Buat PersistentVolumeClaim (PVC)
<a name="_create_the_persistentvolumeclaim_pvc"></a>

Buat PersistentVolumeClaim (PVC) untuk mengikat ke PV, meminta akses hanya-baca ke data model S3 yang dipasang:

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

#### Deploy aplikasi
<a name="_deploy_the_application"></a>

Menerapkan aplikasi inferensi sebagai Deployment Kubernetes, memasang volume persisten yang didukung S3 untuk akses model, menerapkan pemilih dan toleransi node GPU, dan mengatur variabel lingkungan untuk jalur model. Deployment ini menetapkan jalur model (env var of`"/models/gpunet-0.pth"`), jadi aplikasi kita (in`app.py`) akan menggunakan jalur ini secara default. Dengan pemasangan volume Deployment di `/models` (hanya-baca), unduhan model tidak akan terpicu jika file sudah ada melalui PVC.

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

Ini akan memakan waktu beberapa menit bagi Karpenter untuk menyediakan node GPU jika belum tersedia. Verifikasi bahwa pod inferensi berada dalam status “Running”:

```
kubectl get pods -l app=gpunet-inference-app
```

Output yang diharapkan akan terlihat seperti ini:

```
NAME                               READY   STATUS    RESTARTS   AGE
gpunet-inference-app-5d4b6c7f8-abcde        1/1     Running   0          2m
```

### Mengekspos Layanan dengan Ingress dan Load Balancer
<a name="_expose_the_service_with_ingress_and_load_balancer"></a>

Buat Layanan ClusterIP untuk mengekspos penyebaran inferensi secara internal dalam kluster EKS, menargetkan port aplikasi:

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

Buat sumber daya Ingress untuk menyediakan Application Load Balancer (ALB) yang menghadap internet melalui LBC, merutekan lalu AWS lintas eksternal ke layanan inferensi:

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

Berikan beberapa menit agar Application Load Balancer (ALB) menyelesaikan penyediaan. Pantau status sumber daya Ingress untuk mengonfirmasi bahwa ALB telah disediakan:

```
kubectl get ingress gpunet-model-ingress
```

Output yang diharapkan akan terlihat seperti ini (dengan bidang ADDRESS terisi):

```
NAME                   CLASS   HOSTS   ADDRESS                                         PORTS   AGE
gpunet-model-ingress   alb     *       k8s-default-gpunetmo-183de3f819-516310036.us-east-1.elb.amazonaws.com   80      6m58s
```

Ekstrak dan ekspor nama host ALB dari status Ingress untuk digunakan dalam pengujian berikutnya:

```
export ALB_HOSTNAME=$(kubectl get ingress gpunet-model-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
```

### Uji Layanan Model
<a name="_test_the_model_service"></a>

Validasi titik akhir inferensi terbuka dengan mengirimkan permintaan POST dengan URL gambar sampel (misalnya, dari kumpulan data COCO), mensimulasikan prediksi waktu nyata:

```
curl -X POST "http://${ALB_HOSTNAME}/predict?image_url=http://images.cocodataset.org/test-stuff2017/000000024309.jpg"
```

Output yang diharapkan harus berupa respons JSON dengan prediksi 5 teratas, mirip dengan ini (label dan probabilitas aktual mungkin sedikit berbeda berdasarkan presisi gambar dan model):

```
{"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}]}
```

Anda dapat secara opsional melanjutkan pengujian gambar lain dalam permintaan POST baru. Contoh:

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

## Kesimpulan
<a name="_conclusion"></a>

Dalam panduan ini, Anda menyiapkan kluster Amazon EKS yang dioptimalkan untuk beban kerja inferensi real-time yang dipercepat GPU. [https://docs.aws.amazon.com/eks/latest/userguide/lbc-helm.html](https://docs.aws.amazon.com/eks/latest/userguide/lbc-helm.html) NodePools Anda menggunakan Plugin Perangkat NVIDIA untuk mengaktifkan penjadwalan GPU dan mengkonfigurasi S3 dengan PersistentVolume dan PersistentVolumeClaim untuk akses model. Anda memvalidasi penyiapan dengan menerapkan contoh pod GPU, menyiapkan akses model untuk model NVIDIA [GPUNet-0](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/dle/models/gpunet_0_pyt_ckpt) di Amazon S3, mengaktifkan inisialisasi pod, dan [mengekspos](https://aws.amazon.com/s3/) layanan inferensi melalui Application Load Balancer. Untuk sepenuhnya memanfaatkan cluster Anda, konfigurasikan [Agen Pemantauan Node EKS dengan perbaikan](https://docs.aws.amazon.com/eks/latest/userguide/node-health.html) otomatis. Pastikan untuk melakukan tes benchmark, termasuk kinerja GPU, latensi, dan penilaian throughput untuk mengoptimalkan waktu respons. Untuk mempelajari lebih lanjut, lihat [Menggunakan Alat Pemantauan dan Pengamatan untuk Beban AI/ML Kerja Anda](https://docs.aws.amazon.com/eks/latest/best-practices/aiml-observability.html#_using_monitoring_and_observability_tools_for_your_aiml_workloads).

## Bersihkan
<a name="_clean_up"></a>

Untuk menghindari biaya future charge, Anda perlu menghapus CloudFormation tumpukan terkait secara manual untuk menghapus semua sumber daya yang dibuat selama panduan ini, termasuk jaringan VPC.

Hapus CloudFormation tumpukan menggunakan `--wait` bendera dengan eksctl:

```
eksctl delete cluster --region ${AWS_REGION} --name ${EKS_CLUSTER_NAME} --wait
```

Setelah selesai, Anda akan melihat output respons berikut:

```
2025-07-29 13:03:55 [✔]  all cluster resources were deleted
```

Hapus bucket Amazon S3 yang dibuat selama panduan ini menggunakan Konsol [Amazon S3](https://console.aws.amazon.com/s3/home).