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.
Siapkan klaster Amazon EKS untuk AI/ML beban kerja menggunakan CLI
Tip
Daftar
Bagian ini memandu Anda melalui langkah-langkah untuk membuat infrastruktur yang diperlukan untuk menjalankan beban kerja pelatihan atau inferensi di Amazon EKS melalui perintah CLI. Langkah-langkahnya termasuk membuat cluster EKS, GPU-enabled node dengan Mode Otomatis EKS atau Karpenter, tumpukan pemantauan dengan Prometheus dan Grafana, dan penyimpanan Amazon S3 untuk bobot model.
Lihat dokumentasi untuk Mode Otomatis EKS dan Karpenter
High-level arsitektur dan alur kerja
Diagram menunjukkan arsitektur AWS tingkat tinggi untuk pengaturan bagian ini. Langkah-langkah bernomor di sebelah kanan menunjukkan urutan di mana Anda menyelesaikan konfigurasi pada langkah-langkah di bawah ini.
Prasyarat
-
kubectl>= 1,35. Untuk petunjuk penyiapan, lihatSiapkan kubectl dan eksctl. -
AWS CLI >= 2.27. Untuk petunjuk penyiapan, lihat Menginstal.
-
Helm >= 3.14. Untuk petunjuk penyiapan, lihat Setup Helm.
-
jq. Untuk petunjuk penyiapan, lihat Unduh jq. -
eksctl>= 0.227.0. Untuk petunjuk penyiapan, lihat Instalasidalam eksctldokumentasi.
Verifikasi eksctl versi Anda:
eksctl version
Jika Anda menggunakan versi yang lebih lama dari 0.227.0, ikuti panduan instalasi eksctl
Tetapkan variabel lingkungan
Jaga agar nama klaster dan AWS Wilayah berikut tetap konsisten di seluruh langkah ini. Mengubahnya dapat menyebabkan perintah berikutnya menargetkan cluster EKS yang salah.
export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2
Menggunakan semua AZ yang tersedia meningkatkan toleransi kesalahan dan meningkatkan peluang mendapatkan kapasitas GPU:
export AZS=$(aws ec2 describe-availability-zones \ --region ${AWS_REGION} \ --query "AvailabilityZones[?ZoneId!='use1-az3' && ZoneId!='usw1-az2' && ZoneId!='cac1-az3'].ZoneName" \ --output text | tr '\t' ',') echo $AZS
penting
Availability Zones use1-az3usw1-az2,, dan cac1-az3 dikecualikan karena Amazon EKS tidak mendukung penempatan pesawat kontrol di zona tersebutUnsupportedAvailabilityZoneException.
Keluaran yang diharapkan
us-east-2a,us-east-2b,us-east-2c
AZ dalam output akan bervariasi per wilayah. Contoh ini menunjukkan AZ yang tersedia untuk us-east-2 wilayah.
Buat cluster dan GPU NodePool
Bagian ini menyediakan dua jalur untuk membuat kluster dan GPU-enabled node EKS Anda, yang ditunjukkan pada diagram berikut. Pilih hanya satu opsi di seluruh panduan.
-
Mode Otomatis EKS — Selain add-on jaringan inti, penyimpanan, dan penyeimbangan beban, Mode Otomatis EKS menyertakan dan mengelola kemampuan berikut untuk beban kerja pelatihan dan inferensi: agen pemantauan simpul EKS, perbaikan node otomatis, snapshotter SOCI
untuk penarikan kontainer cepat, dan kesiapan GPU untuk default. NodeClass Plugin perangkat NVIDIA termasuk dalam AMI yang dipercepat Bottlerocket yang digunakan Mode Otomatis EKS untuk node. GPU-enabled -
Self-managed Karpenter — Pada cluster EKS tanpa Mode Otomatis EKS, Anda bertanggung jawab untuk menginstal dan mengonfigurasi komponen yang diperlukan untuk beban kerja pelatihan dan inferensi. Ini termasuk add-on jaringan (VPC CNI, CoreDNS, kube-proxy), Karpenter, agen pemantauan node EKS, plugin perangkat NVIDIA, dan snapshotter SOCI untuk penarikan kontainer cepat.
Opsi kluster EKS: Mode Otomatis EKS dan Karpenter yang dikelola sendiri
Di setiap langkah berikut, pilih jalur (Mode Otomatis EKS, Karpenter) dan ikuti seluruhnya. Setelah menyelesaikan langkah-langkah untuk jalur yang Anda pilih, Anda akan memiliki cluster EKS dengan GPU yang NodePool siap menjadwalkan beban kerja GPU.
Langkah 1: Buat klaster
Mulailah dengan membuat kluster EKS Anda dan menginstal komponen cluster yang diperlukan untuk beban kerja GPU.
Dengan Mode Otomatis EKS, satu eksctl create cluster --enable-auto-mode perintah menyediakan kluster EKS yang siap untuk beban kerja GPU.
Dengan Karpenter yang dikelola sendiri, eksctl create cluster perintah tersebut menyediakan add-on jaringan inti, kemudian langkah-langkah tambahan diperlukan untuk mengaktifkan perbaikan node otomatis melalui gerbang fitur Karpenter, menginstal agen pemantauan node EKS, dan menginstal plugin perangkat NVIDIA.
Awas
Untuk Mode Otomatis EKS dan jalur Karpenter yang dikelola sendiri, perbaikan node otomatis berperilaku dengan cara yang sama untuk node yang disediakan oleh. NodePools Perbaikan node otomatis di EKS Auto Mode dan Karpenter adalah metode gangguan kuat yang memintas PodDisruptionBudgets, anotasi, dan. karpenter.sh/do-not-disrupt terminationGracePeriod Perbaikan node otomatis menunggu 10 menit sebelum mengganti node dengan AcceleratedHardwareReady kondisi yang disetel ke False dan 30 menit untuk kondisi perbaikan lainnya.
Langkah 2: Buat GPU dinamis NodePool
Tentukan instans GPU NodePool yang secara dinamis G-family menyediakan instans GPU dengan generasi lebih besar dari 4, menggunakan kapasitas Spot On-Demand sebagai fallback. Jalur Mode Otomatis EKS dan Karpenter keduanya menggunakan NodePool API yang sama dengan satu-satunya perbedaan adalah yang NodeClass ditunjuknya. Dalam Mode Otomatis EKS, bundel default NodeClass sudah memilih AMI yang tepat dan mengonfigurasi tarikan paralel SOCI, jadi satu-satunya objek NodePool yang Anda buat. Di Karpenter yang dikelola sendiri, Anda juga memerlukan kustom EC2NodeClass yang menyematkan AMI dan menyetel SOCI.
Validasi yang NodePool telah dibuat:
kubectl get nodepool gpu-inf
Keluaran yang diharapkan
NAME NODECLASS NODES READY AGE gpu-inf default 0 True 8s
Di jalur Karpenter yang dikelola sendiri, kolom NODECLASS menunjukkan alih-alih. gpu-inf default
Langkah 3: Uji dengan sampel Pod
Uji NodePool pengaturan GPU Anda dengan nvidia-smi Pod.
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: nvidia-smi labels: guide: ai-eks-docs spec: tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" containers: - name: nvidia-smi image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal command: ["nvidia-smi"] resources: limits: nvidia.com/gpu: 1 restartPolicy: OnFailure EOF
Verifikasi bahwa Pod sudah dijadwalkan dan diselesaikan dengan sukses.
kubectl get pods
Keluaran yang diharapkan
NAME READY STATUS RESTARTS AGE nvidia-smi 0/1 Completed 0 67s
STATUS: Selesai berarti perintah nvidia-smi berjalan dan keluar. Periksa log Pod untuk melihat GPU terdeteksi oleh node.
kubectl logs nvidia-smi
Keluaran yang diharapkan
+-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 580.126.09 Driver Version: 580.126.09 CUDA Version: 13.0 | +-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA RTX PRO 6000 Blac... On | 00000000:2B:00.0 Off | 0 | | N/A 30C P0 81W / 600W | 0MiB / 97887MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+
Output menunjukkan model GPU, versi driver, versi CUDA, dan memori yang tersedia. Dalam contoh ini, Karpenter menyediakan instance G7e yang memiliki GPU NVIDIA RTX PRO 6000 Blackwell dengan memori 96 GB. 30C adalah suhu GPU saat ini dan P0 berarti GPU berada dalam kondisi kinerja tertinggi (idle tapi siap). 81W/600W menunjukkan penarikan daya saat ini vs kapasitas daya maks, dan 0MiB/97887MiB menunjukkan memori GPU saat ini yang digunakan vs total yang tersedia. Karena Pod baru saja menjalankan nvidia-smi dan keluar, tidak ada beban kerja yang menggunakan GPU sehingga memori berada pada 0 dan daya saat idle. Versi driver GPU NVIDIA (580.126.09) berasal dari Bottlerocket AMI, sedangkan versi CUDA (13.0) berasal dari gambar kontainer. Model dan memori GPU akan bervariasi tergantung pada jenis instance yang dipilih Karpenter. Instans G5 memiliki GPU NVIDIA A10G (24 GB), instans G6e memiliki GPU NVIDIA L40S (48 GB), dan instance G7e memiliki GPU NVIDIA RTX PRO 6000 (96 GB).
Untuk memahami bagaimana Karpenter dan penjadwal Kubernetes berkoordinasi untuk menyediakan sebuah node dan menempatkan Pod, periksa peristiwa siklus hidup Pod:
kubectl describe po nvidia-smi
Keluaran yang diharapkan
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 60s default-scheduler 0/2 nodes are available: 2 node(s) had untolerated taint(s). no new claims to deallocate, preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. Normal Nominated 59s eks-auto-mode/compute Pod should schedule on: nodeclaim/gpu-inf-vxcnj Normal Scheduled 24s default-scheduler Successfully assigned default/nvidia-smi to i-0fb17a09bc4203164 Warning FailedCreatePodSandBox 21s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "7f85e25b220c8fb245187758dbbbc8efb3d40f3e49e13054404880daf4c3b2f0": plugin type="aws-cni" name="aws-cni" failed (add): add cmd: failed to setup network policy Normal Pulling 7s kubelet spec.containers{nvidia-smi}: Pulling image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal" Normal Pulled 5s kubelet spec.containers{nvidia-smi}: Successfully pulled image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal" in 1.237s (1.237s including waiting). Image size: 37442701 bytes. Normal Created 5s kubelet spec.containers{nvidia-smi}: Container created Normal Started 5s kubelet spec.containers{nvidia-smi}: Container started
Peristiwa ini menunjukkan urutan penjadwalan Pod: Pod awalnya gagal menjadwalkan karena tidak ada node GPU yang ada (FailedScheduling), Karpenter menominasikan new NodeClaim (Nominated), scheduler menetapkan Pod setelah node siap (Terjadwal), dan kemudian gambar kontainer ditarik dan dimulai. EKS Auto Mode dilengkapi dengan parallel pull SOCI (Seekable OCI) yang dipasang dan dikonfigurasi di luar kotak pada instance G, P, dan Trn. Perhatikan karena tarikan paralel SOCI, gambar kontainer ditarik dari ECR dalam waktu kurang dari 2 detik (1,237 detik).
A NodeClaim adalah permintaan Karpenter menciptakan untuk menyediakan node tertentu. Ini menunjukkan jenis instance, tipe kapasitas, AZ, dan apakah node siap.
kubectl get nodeclaims
NodeClaim Output yang diharapkan:
NAME TYPE CAPACITY ZONE NODE READY AGE gpu-inf-xxxxx g7e.2xlarge spot us-east-2a i-0xxxxxxxxxxxx True 2m
Jenis instans dan AZ akan bervariasi. Setiap G-family instance dengan generasi> 4 memenuhi syarat.
FailedCreatePodSandBoxPeringatan di kubectl describe pod nvidia-smi bersifat sementara dan diharapkan. VPC CNI menginisialisasi secara asinkron setelah node bergabung, dan kubelet mencoba ulang secara otomatis. Jika Pod tetap berada di dalamContainerCreating, periksa peristiwa node dengankubectl describe node <node-name>.
Tip
Jika tidak ada node yang muncul, periksa Kesalahan Kapasitas Tidak Cukup:
kubectl get events | grep InsufficientCapacityError
Karpenter menyimpan penawaran yang tidak tersedia selama 3 menit. Memperluas jenis instans dan AZ yang diizinkan di Anda NodePool meningkatkan kemungkinan kapasitas pendaratan.
catatan
Instans spot yang diluncurkan oleh Karpenter tidak akan muncul di konsol Permintaan Spot EC2. Karpenter menggunakan API EC2 CreateFleetdengan. type: instant Instans muncul di konsol Instans EC2 dengan siklus hidup. spot
Langkah 4: Tambahkan kapasitas cadangan ke NodePool (opsional)
Untuk menggunakan kapasitas cadangan terlebih dahulu dengan Spot/On-Demand fallback, buat ODCR dan pasang ke Anda NodeClass, lalu perbarui dinamika NodePool dari Langkah 2 untuk juga memungkinkan kapasitas. reserved Panggilan API reservasi sama untuk kedua jalur; NodeClass lampiran berbeda karena Mode Otomatis EKS dan Karpenter yang dikelola sendiri menggunakan jenis yang berbeda. NodeClass
Awas
Perintah berikut menghasilkan biaya untuk jenis instans yang dicadangkan hingga Anda membatalkannyaaws ec2 cancel-capacity-reservation --capacity-reservation-id <id>.
Buat reservasi kapasitas:
CR_AZ="us-east-2a" INSTANCE_TYPE="g6e.4xlarge" aws ec2 create-capacity-reservation \ --instance-type $INSTANCE_TYPE \ --instance-platform Linux/UNIX \ --availability-zone "$CR_AZ" \ --instance-count 1 \ --instance-match-criteria open \ --end-date-type unlimited
Jika Anda mendapatkan InsufficientInstanceCapacity kesalahan, ubah CR_AZ ke AZ yang berbeda dan coba lagi.
Cari ID reservasi kapasitas dan simpan dalam variabel shell untuk langkah-langkah berikut:
CAPACITY_RESERVATION_ID=$(aws ec2 describe-capacity-reservations \ --filters "Name=state,Values=active" "Name=instance-type,Values=${INSTANCE_TYPE}" \ --query 'CapacityReservations[0].CapacityReservationId' \ --output text \ --region ${AWS_REGION}) echo "Capacity reservation ID: ${CAPACITY_RESERVATION_ID}"
Kemudian terapkan NodeClass dan NodePool perubahan untuk jalur Anda:
Karpenter memperlakukan reserved sebagai opsi yang paling hemat biaya dan meluncurkannya terlebih dahulu. Setelah reservasi penuh, itu jatuh kembali ke Spot atau On-Demand.
Setelah menerapkan perubahan, validasi bahwa Karpenter memprioritaskan kapasitas cadangan dan kembali ke Spot atau. On-Demand Menerapkan Deployment 2-replika yang meminta 1 GPU per Pod. ODCR adalah untuk 1 instance, jadi Pod pertama memicu Karpenter untuk meluncurkan node reserved. Pod kedua tidak bisa muat pada node reserved dan memicu Karpenter untuk meluncurkan node lain dari Spot atau kapasitas. On-Demand
cat << 'EOF' | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: gpu-overflow-test labels: guide: ai-eks-docs spec: replicas: 2 selector: matchLabels: app: gpu-overflow-test template: metadata: labels: app: gpu-overflow-test guide: ai-eks-docs spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: nvidia-smi image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal command: ["sh", "-c", "nvidia-smi && sleep infinity"] resources: limits: nvidia.com/gpu: 1 EOF
Berbeda dengan Pod nvidia-smi uji dari Langkah 3 yang berjalan dan keluar, Deployment ini membuat Pod tetap berjalan (sleep infinity) sehingga mereka menahan GPU dan tidak melepaskan node.
Verifikasi Pod yang dijadwalkan pada node yang berbeda:
kubectl get pods -l app=gpu-overflow-test -o wide
Keluaran yang diharapkan
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES gpu-overflow-test-59b97944fb-lq56c 1/1 Running 0 2m42s 192.168.186.240 i-057692590480155da <none> <none> gpu-overflow-test-59b97944fb-z4zcx 1/1 Running 0 2m42s 192.168.130.64 i-0521ecd1849fa0578 <none> <none>
Kedua pod berjalan, masing-masing pada node yang berbeda.
Periksa NodeClaims untuk melihat jenis kapasitas:
kubectl get nodeclaims
Keluaran yang diharapkan
NAME TYPE CAPACITY ZONE NODE READY AGE gpu-inf-shg5w g6e.xlarge reserved us-east-2a i-0ea91fdeef65b8cb6 True 2m2s gpu-inf-ssnqf g7e.2xlarge spot us-east-2b i-00ccf7ce65cf3f6ca True 112s
Node cadangan diluncurkan terlebih dahulu, diikuti oleh Spot atau On-Demand node setelah reservasi penuh.
Bersihkan penerapan pengujian:
kubectl delete deployment gpu-overflow-test
Memantau
Instal tumpukan pemantauan yang mengumpulkan metrik cluster, node, dan GPU ke Amazon Managed Service for Prometheus (AMP), dan visualisasikan dengan Grafana. Bagan Helm kube-prometheus-stack menerapkan Prometheus untuk mengikis dan menulis metrik jarak jauh ke AMP, ditambah Grafana yang dikelola sendiri untuk dasbor. Eksportir NVIDIA DCGM menambahkan GPU-specific metrik (pemanfaatan, memori, suhu, daya, NVLink, aktivitas tensor).
Prometheus, Grafana, dan operator mendarat di node non-GPU secara default karena node GPU membawa noda. nvidia.com/gpu:NoSchedule Node-exporter dan Eksportir DCGM keduanya berjalan pada node GPU sehingga kami dapat mengikis metrik host dan GPU di seluruh armada.
Jika Anda membuka terminal baru, atur nama cluster dan wilayah:
export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2
Membuat ruang kerja AMP
Membuat ruang kerja AMP untuk menyimpan metrik:
aws amp create-workspace \ --alias "amp-ws-${CLUSTER_NAME}" \ --region ${AWS_REGION}
Dapatkan ID ruang kerja:
AMP_WORKSPACE_ID=$(aws amp list-workspaces \ --alias "amp-ws-${CLUSTER_NAME}" \ --query 'workspaces[0].workspaceId' \ --output text \ --region ${AWS_REGION}) echo "AMP Workspace ID: ${AMP_WORKSPACE_ID}"
Dapatkan titik akhir penulisan jarak jauh:
AMP_ENDPOINT=$(aws amp describe-workspace \ --workspace-id ${AMP_WORKSPACE_ID} \ --query 'workspace.prometheusEndpoint' \ --output text \ --region ${AWS_REGION}) echo "AMP Endpoint: ${AMP_ENDPOINT}"
Membuat kebijakan IAM dan asosiasi Identitas Pod EKS
Buat kebijakan IAM yang memungkinkan Prometheus menulis metrik dari jarak jauh dan Grafana untuk menanyainya:
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) AMP_POLICY_ARN=$(aws iam create-policy \ --policy-name "${CLUSTER_NAME}-amp-grafana-policy" \ --policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Sid\": \"AllowAMPReadWrite\", \"Effect\": \"Allow\", \"Action\": [\"aps:ListWorkspaces\", \"aps:DescribeWorkspace\", \"aps:GetMetricMetadata\", \"aps:GetSeries\", \"aps:QueryMetrics\", \"aps:RemoteWrite\", \"aps:GetLabels\"], \"Resource\": \"arn:aws:aps:${AWS_REGION}:${ACCOUNT_ID}:workspace/*\"}, {\"Sid\": \"AllowCloudWatchMetrics\", \"Effect\": \"Allow\", \"Action\": [\"cloudwatch:DescribeAlarmsForMetric\", \"cloudwatch:ListMetrics\", \"cloudwatch:GetMetricData\", \"cloudwatch:GetMetricStatistics\"], \"Resource\": \"*\"}]}" \ --query 'Policy.Arn' \ --output text) echo "AMP Policy ARN: ${AMP_POLICY_ARN}"
Buat namespace pemantauan dan akun layanan untuk Prometheus dan Grafana:
kubectl create namespace monitoring kubectl create serviceaccount amp-iamproxy-ingest-service-account -n monitoring kubectl create serviceaccount grafana-sa -n monitoring
Buat Asosiasi Identitas Pod EKS untuk menautkan akun layanan ke kebijakan IAM:
eksctl create podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name amp-iamproxy-ingest-service-account \ --role-name "${CLUSTER_NAME}-amp-ingest-role" \ --permission-policy-arns ${AMP_POLICY_ARN} \ --region ${AWS_REGION} eksctl create podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name grafana-sa \ --role-name "${CLUSTER_NAME}-grafana-role" \ --permission-policy-arns ${AMP_POLICY_ARN} \ --region ${AWS_REGION}
Verifikasi kedua asosiasi Identitas Pod EKS telah dibuat:
eksctl get podidentityassociation --cluster ${CLUSTER_NAME} --region ${AWS_REGION}
Output yang diharapkan harus mencakup keduanya amp-iamproxy-ingest-service-account dan grafana-sa di monitoring namespace.
Instal kube-prometheus-stack
Tambahkan repo Helm:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update
File nilai ini menghilangkan NodeSelector untuk Prometheus, Grafana, dan operator: noda node GPU menjauhkan mereka dari node nvidia.com/gpu:NoSchedule GPU, sehingga mereka mendarat di sistem atau kumpulan tujuan umum secara default. Node-exporter menggunakan toleransi wildcard sehingga berjalan di setiap node — termasuk node GPU — untuk mengumpulkan metrik di seluruh armada.
Buat file nilai:
cat << EOF > /tmp/kube-prometheus-values.yaml prometheus: serviceAccount: create: false name: amp-iamproxy-ingest-service-account prometheusSpec: serviceAccountName: amp-iamproxy-ingest-service-account remoteWrite: - url: "${AMP_ENDPOINT}api/v1/remote_write" sigv4: region: "${AWS_REGION}" queueConfig: maxSamplesPerSend: 1000 maxShards: 200 capacity: 2500 retention: 5h scrapeInterval: 30s evaluationInterval: 30s podMonitorSelectorNilUsesHelmValues: false serviceMonitorSelectorNilUsesHelmValues: false alertmanager: enabled: false grafana: enabled: true serviceAccount: create: false name: grafana-sa grafana.ini: auth.sigv4: enabled: true sidecar: datasources: defaultDatasourceEnabled: false plugins: - grafana-amazonprometheus-datasource additionalDataSources: - name: Amazon-Managed-Prometheus type: grafana-amazonprometheus-datasource access: proxy url: "${AMP_ENDPOINT}" isDefault: true jsonData: sigV4Auth: true defaultRegion: "${AWS_REGION}" sigV4Region: "${AWS_REGION}" editable: true dashboardProviders: dashboardproviders.yaml: apiVersion: 1 providers: - name: default orgId: 1 folder: 'GPU Monitoring' type: file disableDeletion: false editable: true options: path: /var/lib/grafana/dashboards/default dashboards: default: nvidia-dcgm: gnetId: 25261 revision: 1 datasource: - name: DS_PROMETHEUS value: Amazon-Managed-Prometheus vllm: gnetId: 25263 revision: 1 datasource: - name: DS_PROMETHEUS value: Amazon-Managed-Prometheus prometheus-node-exporter: tolerations: - operator: Exists EOF
Validasi variabel diisi dengan benar:
grep -E "url:|region:|tolerations:" /tmp/kube-prometheus-values.yaml
Anda akan melihat URL titik akhir AMP lengkap (dimulai denganhttps://aps-workspaces…), wilayah Anda, dan baris pengekspor simpultolerations:. Jika ada yang kosong, ekspor ulang variabel dan buat ulang file.
Instal bagan:
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \ --namespace monitoring \ -f /tmp/kube-prometheus-values.yaml
Verifikasi pod sedang berjalan:
kubectl get pods -n monitoring
Keluaran yang diharapkan
NAME READY STATUS RESTARTS AGE kube-prometheus-stack-grafana-7c58f54f77-rftrj 3/3 Running 0 4m kube-prometheus-stack-kube-state-metrics-d68dcbc84-5smxq 1/1 Running 0 4m kube-prometheus-stack-operator-5895df479f-ttm47 1/1 Running 0 4m kube-prometheus-stack-prometheus-node-exporter-t9q7s 1/1 Running 0 4m kube-prometheus-stack-prometheus-node-exporter-x6vfb 1/1 Running 0 4m prometheus-kube-prometheus-stack-prometheus-0 2/2 Running 0 4m
Tumpukan menyebarkan komponen-komponen berikut:
-
Prometheus StatefulSet (): menggores metrik dan menulisnya dari jarak jauh ke AMP
-
Grafana: dasbor dan visualisasi, dikonfigurasi sebelumnya dengan sumber data AMP
-
kube-state-metrics: menghasilkan metrik tentang status objek Kubernetes (status Pod, sumber daya, status) requests/limits NodeClaim
-
node-eksportir (DaemonSet, satu per node): mengumpulkan metrik tingkat host (CPU, memori, disk, jaringan)
-
operator: mengelola sumber daya kustom Prometheus dan Alertmanager
Alertmanager dinonaktifkan dalam pengaturan ini.
Akses Grafana
Buka terminal terpisah dan port-forward untuk mengakses Grafana:
kubectl port-forward svc/kube-prometheus-stack-grafana 3000:80 -n monitoring
Buka http://localhost:3000admin dan kata sandi dari perintah berikut:
kubectl --namespace monitoring get secrets kube-prometheus-stack-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo
Untuk memverifikasi, pipa metrik berfungsi dari ujung ke ujung:
-
Arahkan ke Koneksi > Sumber data dan konfirmasi
Amazon-Managed-Prometheusterdaftar sebagai sumber data default.Validasi sumber data AMP di Grafana
-
Arahkan ke Drilldown > Metrics dan cari metrik.
upAnda akan melihat hasil dari target scrape cluster Anda.Validasi
upmetrik di Grafana
Jika up menunjukkan hasil, pipeline (cluster → Prometheus → AMP → Grafana) berfungsi.
Terapkan Eksportir DCGM untuk metrik GPU
Kube-prometheus-stack mengumpulkan metrik CPU dan memori tingkat node tetapi bukan metrik GPU. Eksportir NVIDIA DCGM menambahkan pemanfaatan GPU, penggunaan memori, suhu, penarikan daya, bandwidth NVLink, dan aktivitas tensor.
helm repo add gpu-helm-charts https://nvidia.github.io/dcgm-exporter/helm-charts helm repo update
Tetapkan kunci pemilih node GPU untuk jalur Anda. Mode Otomatis EKS dan Karpenter yang dikelola sendiri menggunakan kunci label yang berbeda untuk produsen GPU.
Buat file nilai eksportir DCGM:
cat << EOF > /tmp/dcgm-exporter-values.yaml resources: requests: memory: "512Mi" cpu: "100m" limits: memory: "1Gi" cpu: "500m" serviceMonitor: enabled: true additionalLabels: release: kube-prometheus-stack nodeSelector: ${GPU_NODE_SELECTOR_KEY}: nvidia tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" customMetrics: | # Clocks DCGM_FI_DEV_SM_CLOCK, gauge, SM clock frequency (in MHz). DCGM_FI_DEV_MEM_CLOCK, gauge, Memory clock frequency (in MHz). # Temperature DCGM_FI_DEV_MEMORY_TEMP, gauge, Memory temperature (in C). DCGM_FI_DEV_GPU_TEMP, gauge, GPU temperature (in C). # Power DCGM_FI_DEV_POWER_USAGE, gauge, Power draw (in W). DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION, counter, Total energy consumption since boot (in mJ). # PCIe DCGM_FI_PROF_PCIE_TX_BYTES, counter, Number of bytes transmitted through PCIe TX (in KB) via NVML. DCGM_FI_PROF_PCIE_RX_BYTES, counter, Number of bytes received through PCIe RX (in KB) via NVML. DCGM_FI_DEV_PCIE_REPLAY_COUNTER, counter, Total number of PCIe retries. # Utilization (the sample period varies depending on the product) DCGM_FI_DEV_GPU_UTIL, gauge, GPU utilization (in %). DCGM_FI_DEV_MEM_COPY_UTIL, gauge, Memory utilization (in %). DCGM_FI_DEV_ENC_UTIL, gauge, Encoder utilization (in %). DCGM_FI_DEV_DEC_UTIL, gauge, Decoder utilization (in %). # Errors and violations DCGM_FI_DEV_XID_ERRORS, gauge, Value of the last XID error encountered. DCGM_EXP_XID_ERRORS_COUNT, gauge, Value of count of XID errors encountered. DCGM_FI_DEV_POWER_VIOLATION, counter, Throttling duration due to power constraints (in us). DCGM_FI_DEV_THERMAL_VIOLATION, counter, Throttling duration due to thermal constraints (in us). DCGM_FI_DEV_SYNC_BOOST_VIOLATION, counter, Throttling duration due to sync-boost constraints (in us). DCGM_FI_DEV_BOARD_LIMIT_VIOLATION, counter, Throttling duration due to board limit constraints (in us). DCGM_FI_DEV_LOW_UTIL_VIOLATION, counter, Throttling duration due to low utilization (in us). DCGM_FI_DEV_RELIABILITY_VIOLATION, counter, Throttling duration due to reliability constraints (in us). # Memory usage DCGM_FI_DEV_FB_FREE, gauge, Framebuffer memory free (in MiB). DCGM_FI_DEV_FB_USED, gauge, Framebuffer memory used (in MiB). # Retired pages DCGM_FI_DEV_RETIRED_SBE, counter, Total number of retired pages due to single-bit errors. DCGM_FI_DEV_RETIRED_DBE, counter, Total number of retired pages due to double-bit errors. DCGM_FI_DEV_RETIRED_PENDING, counter, Total number of pages pending retirement. # NVLink DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL, counter, Total number of NVLink bandwidth counters for all lanes. DCGM_FI_PROF_NVLINK_TX_BYTES, counter, The rate of data transmitted over NVLink not including protocol headers in bytes per second. DCGM_FI_PROF_NVLINK_RX_BYTES, counter, The rate of data received over NVLink not including protocol headers in bytes per second. # DCP metrics DCGM_FI_PROF_GR_ENGINE_ACTIVE, gauge, Ratio of time the graphics engine is active (in %). DCGM_FI_PROF_SM_ACTIVE, gauge, The ratio of cycles an SM has at least 1 warp assigned (in %). DCGM_FI_PROF_SM_OCCUPANCY, gauge, The ratio of number of warps resident on an SM (in %). DCGM_FI_PROF_PIPE_TENSOR_ACTIVE, gauge, Ratio of cycles the tensor (HMMA) pipe is active (in %). DCGM_FI_PROF_DRAM_ACTIVE, gauge, Ratio of cycles the device memory interface is active sending or receiving data (in %). DCGM_FI_DEV_CLOCK_THROTTLE_REASONS, gauge, Current clock throttle reasons (bitmask of DCGM_CLOCKS_THROTTLE_REASON_*). DCGM_FI_DEV_GPU_NVLINK_ERRORS, gauge, Identifies a GPU NVLink error type returned by DCGM_FI_DEV_GPU_NVLINK_ERRORS. ## NVLink DCGM_FI_DEV_NVLINK_BANDWIDTH_L0, counter, The number of bytes of active NVLink rx or tx data including both header and payload. ## Remapped rows DCGM_FI_DEV_UNCORRECTABLE_REMAPPED_ROWS, counter, Number of remapped rows for uncorrectable errors. DCGM_FI_DEV_CORRECTABLE_REMAPPED_ROWS, counter, Number of remapped rows for correctable errors. DCGM_FI_DEV_ROW_REMAP_FAILURE, gauge, whether remapping of rows has failed. ## Profiling metrics DCGM_FI_PROF_PIPE_FP64_ACTIVE, gauge, Ratio of cycles the fp64 pipes are active (in %). DCGM_FI_PROF_PIPE_FP32_ACTIVE, gauge, Ratio of cycles the fp32 pipes are active (in %). DCGM_FI_PROF_PIPE_FP16_ACTIVE, gauge, Ratio of cycles the fp16 pipes are active (in %). # ECC DCGM_FI_DEV_ECC_SBE_VOL_TOTAL, counter, Total number of single-bit volatile ECC errors. DCGM_FI_DEV_ECC_DBE_VOL_TOTAL, counter, Total number of double-bit volatile ECC errors. EOF
customMetricsBidang ini mengesampingkan set metrik default eksportir DCGM dengan yang diperluas yang mencakup bandwidth NVLink, aktivitas tensor, throughput PCIe, kesalahan ECC, dan pelambatan termal. Untuk beban kerja inferensi, ini membantu Anda memahami apakah unit komputasi GPU sepenuhnya digunakan, apakah GPU menganggur di antara permintaan karena ukuran batch yang rendah, apakah transfer data antara CPU dan GPU merupakan hambatan, apakah pelambatan termal menyebabkan lonjakan latensi, dan berapa banyak ruang kepala memori GPU yang tersisa untuk batch yang lebih besar.
Instal eksportir DCGM:
helm install dcgm-exporter gpu-helm-charts/dcgm-exporter \ --namespace monitoring \ -f /tmp/dcgm-exporter-values.yaml
tolerationsIzinkan eksportir untuk berjalan pada GPU-tainted node yang Anda sediakan di Langkah 2. serviceMonitorDengan release: kube-prometheus-stack label memastikan Prometheus menemukan dan menggoresnya secara otomatis.
Verifikasi eksportir DCGM: DaemonSet
kubectl get daemonset dcgm-exporter -n monitoring
Setelah node GPU berjalan, Anda akan melihat satu Pod siap. Untuk memvalidasi metrik DCGM, navigasikan ke Drilldown > Metrics di Grafana dan cari. DCGM_
Validasi metrik DCGM di Grafana
Untuk melihat dasbor, navigasikan ke Dasbor> Pemantauan GPU > Dasbor Eksportir NVIDIA DCGM.
Dasbor Eksportir NVIDIA DCGM di Grafana
Model bobot ember S3
Buat bucket Amazon S3 untuk menyimpan bobot model dan konfigurasikan Asosiasi Identitas Pod EKS sehingga pod beban kerja dapat membaca dan menulis padanya.
Jika Anda membuka terminal baru, atur nama cluster dan wilayah:
export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2
Buat ember S3
Buat bucket dengan akhiran acak untuk menghindari tabrakan nama:
BUCKET_SUFFIX=$(head -c 4 /dev/urandom | od -An -tx1 | tr -d ' \n') MODEL_BUCKET="${CLUSTER_NAME}-models-${BUCKET_SUFFIX}" aws s3 mb s3://${MODEL_BUCKET} --region ${AWS_REGION}
Bucket S3 yang dibuat setelah Januari 2023 memiliki enkripsi sisi server (AES256) dan pemblokiran akses publik diaktifkan secara default.
Konfigurasikan EKS Pod Identity untuk akses S3
Buat model-storage-sa ServiceAccount di default namespace, kebijakan IAM yang dicakup ke bucket model, dan Asosiasi Identitas Pod EKS yang menautkannya. Pod beban kerja yang disetel serviceAccountName: model-storage-sa akan dapat membaca dan menulis ke bucket.
kubectl create serviceaccount model-storage-sa
Buat kebijakan IAM:
POLICY_ARN=$(aws iam create-policy \ --policy-name "${CLUSTER_NAME}-model-storage-policy" \ --policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:GetObject\", \"s3:PutObject\", \"s3:ListBucket\", \"s3:DeleteObject\"], \"Resource\": [\"arn:aws:s3:::${MODEL_BUCKET}\", \"arn:aws:s3:::${MODEL_BUCKET}/*\"]}]}" \ --query 'Policy.Arn' \ --output text) echo "Policy ARN: ${POLICY_ARN}"
catatan
Kebijakan ini memberikan s3:DeleteObject dan s3:PutObject untuk langkah validasi. Untuk pod inferensi produksi yang hanya membaca bobot model, hapus s3:PutObject dan ikuti s3:DeleteObject least-privilege.
Buat Asosiasi Identitas Pod EKS. eksctlmembuat peran IAM dengan kebijakan kepercayaan yang benar dan menautkannya ke ServiceAccount:
eksctl create podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace default \ --service-account-name model-storage-sa \ --role-name "${CLUSTER_NAME}-model-storage-role" \ --permission-policy-arns ${POLICY_ARN} \ --region ${AWS_REGION}
Verifikasi asosiasi:
eksctl get podidentityassociation --cluster ${CLUSTER_NAME} --region ${AWS_REGION}
Output harus menyertakan model-storage-sa asosiasi di default namespace.
Jalankan Pod satu kali dengan image AWS CLI, menggunakan model-storage-sa ServiceAccount, untuk mengonfirmasi EKS Pod Identity tersambung dan akses S3 berfungsi:
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: s3-test labels: guide: ai-eks-docs spec: serviceAccountName: model-storage-sa containers: - name: aws-cli image: public.ecr.aws/aws-cli/aws-cli:2.27.0 command: - sh - -c - | echo "=== Caller Identity ===" aws sts get-caller-identity echo "" echo "=== S3 Write Test ===" echo "pod identity works" | aws s3 cp - s3://${MODEL_BUCKET}/test.txt echo "" echo "=== S3 List Test ===" aws s3 ls s3://${MODEL_BUCKET}/ echo "" echo "=== S3 Delete Test ===" aws s3 rm s3://${MODEL_BUCKET}/test.txt restartPolicy: Never EOF
Tunggu sampai Pod selesai dan periksa log:
kubectl wait --for=jsonpath='{.status.phase}'=Succeeded pod/s3-test --timeout=300s kubectl logs s3-test
Keluaran yang diharapkan
=== Caller Identity ===
{
"UserId": "AROA...:eks-ai-eks-docs-model-s-...",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/ai-eks-docs-model-storage-role/eks-ai-eks-docs-model-s-..."
}
=== S3 Write Test ===
upload: - to s3://ai-eks-docs-models-01234567/test.txt
=== S3 List Test ===
2026-05-04 12:00:00 19 test.txt
=== S3 Delete Test ===
delete: s3://ai-eks-docs-models-01234567/test.txtIdentitas penelepon mengonfirmasi bahwa Pod mengambil ${CLUSTER_NAME}-model-storage-role peran melalui EKS Pod Identity. Perintah S3 mengkonfirmasi akses baca dan tulis.
Bersihkan Pod uji:
kubectl delete pod s3-test
Langkah selanjutnya
Dengan klaster Anda siap, Anda dapat melanjutkan ke Load & Serve Model untuk menerapkan model bahasa besar dan berinteraksi dengan titik akhir inferensi.
Pembersihan
Tip
Jika Anda berencana untuk melanjutkan dengan bagian selanjutnya dari panduan ini, lewati pembersihan penuh. Jalankan hanya ketika Anda selesai.
export CLUSTER_NAME=ai-eks-docs export AWS_REGION=us-east-2
kubectl delete pod nvidia-smi --ignore-not-found kubectl delete deployment gpu-overflow-test --ignore-not-found
Jika Anda membuat ODCR, batalkan terlebih dahulu:
INSTANCE_TYPE="g6e.4xlarge" CAPACITY_RESERVATION_ID=$(aws ec2 describe-capacity-reservations \ --filters "Name=state,Values=active" "Name=instance-type,Values=${INSTANCE_TYPE}" \ --query 'CapacityReservations[0].CapacityReservationId' \ --output text \ --region ${AWS_REGION}) aws ec2 cancel-capacity-reservation --capacity-reservation-id ${CAPACITY_RESERVATION_ID}
penting
Membatalkan reservasi tidak menghentikan instans yang sedang berjalan. Mereka melanjutkan dengan On-Demand tarif standar sampai dihentikan. Hapus penerapan terlebih dahulu untuk menguras node yang dicadangkan sebelum membatalkan.
Cari kebijakan IAM ARN:
AMP_POLICY_ARN=$(aws iam list-policies \ --scope Local \ --query "Policies[?PolicyName=='${CLUSTER_NAME}-amp-grafana-policy'].Arn" \ --output text) echo "AMP Policy ARN: ${AMP_POLICY_ARN}"
Cari ID ruang kerja AMP:
AMP_WORKSPACE_ID=$(aws amp list-workspaces \ --alias "amp-ws-${CLUSTER_NAME}" \ --query 'workspaces[0].workspaceId' \ --output text \ --region ${AWS_REGION}) echo "AMP Workspace ID: ${AMP_WORKSPACE_ID}"
Copot pemasangan rilis Helm eksportir DCGM:
helm uninstall dcgm-exporter -n monitoring
Copot pemasangan rilis Helm kube-prometheus-stack:
helm uninstall kube-prometheus-stack -n monitoring
Hapus asosiasi Identitas Pod EKS untuk akun layanan konsumsi Prometheus:
eksctl delete podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name amp-iamproxy-ingest-service-account \ --region ${AWS_REGION}
Hapus asosiasi Identitas Pod EKS untuk akun layanan Grafana:
eksctl delete podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace monitoring \ --service-account-name grafana-sa \ --region ${AWS_REGION}
Hapus kebijakan IAM yang digunakan oleh Prometheus dan Grafana:
aws iam delete-policy --policy-arn ${AMP_POLICY_ARN}
Menghapus ruang kerja AMP:
aws amp delete-workspace --workspace-id ${AMP_WORKSPACE_ID} --region ${AWS_REGION}
Hapus namespace pemantauan:
kubectl delete namespace monitoring
Cari nama bucket model:
MODEL_BUCKET=$(aws s3api list-buckets \ --query "Buckets[?starts_with(Name, '${CLUSTER_NAME}-models-')].Name | [0]" \ --output text) echo "Model bucket: ${MODEL_BUCKET}"
Cari kebijakan IAM ARN:
POLICY_ARN=$(aws iam list-policies \ --scope Local \ --query "Policies[?PolicyName=='${CLUSTER_NAME}-model-storage-policy'].Arn" \ --output text) echo "Policy ARN: ${POLICY_ARN}"
Hapus bucket model S3 dan semua objeknya:
aws s3 rb s3://${MODEL_BUCKET} --force
Hapus asosiasi Identitas Pod EKS:
eksctl delete podidentityassociation \ --cluster ${CLUSTER_NAME} \ --namespace default \ --service-account-name model-storage-sa \ --region ${AWS_REGION}
Hapus kebijakan IAM:
aws iam delete-policy --policy-arn ${POLICY_ARN}
Hapus Kubernetes ServiceAccount:
kubectl delete serviceaccount model-storage-sa
kubectl delete nodepool gpu-inf --ignore-not-found kubectl delete nodeclass gpu-inf --ignore-not-found kubectl delete ec2nodeclass gpu-inf --ignore-not-found eksctl delete cluster --name=$CLUSTER_NAME --region=$AWS_REGION