このページの改善にご協力ください
このユーザーガイドに貢献するには、すべてのページの右側のペインにある「GitHub でこのページを編集する」リンクを選択してください。
Terraform を使用して AI/ML ワークロード用の Amazon EKS クラスターを設定する
ヒント
今後開催予定の Amazon EKS AI/ML ワークショップに登録
このセクションでは、Terraform を使用して Amazon EKS でトレーニングまたは推論ワークロードを実行するために必要なインフラストラクチャを作成する手順について説明します。ステップには、EKS クラスターの作成、EKS Auto Mode または Karpenter を使用した GPU 対応ノードの作成、Prometheus と Grafana を使用したモニタリングスタック、モデルの重み付け用の Amazon S3 ストレージが含まれます。
これらの機能が EKS クラスターで EC2 インスタンスをプロビジョニングおよび自動スケールする方法の詳細については、EKS Auto Mode と Karpenter
高レベルアーキテクチャとワークフロー
この図は、このセクションのセットアップの AWS 高レベルアーキテクチャを示しています。
前提条件
重要
EKS クラスター、GPU インスタンス、Application Load Balancer、Amazon Managed Service for Prometheus など、このチュートリアルで作成するリソースには料金が発生します。終了したリソースは、継続的な料金の発生を回避するために削除してください。
-
Terraform >= 1.15.0。セットアップ手順については、「Terraform のインストール
」を参照してください。 -
kubectl>= 1.36。セットアップ手順については、「kubectl および eksctl のセットアップ」を参照してください。 -
AWS CLI >= 2.27。セットアップ手順については、「AWS CLI の最新バージョンのインストールまたは更新」を参照してください。
-
jq。セットアップ手順については、「Download jq」を参照してください。
ツールのバージョンを確認します。
terraform --version aws --version kubectl version --client jq --version
ステップ 1: Terraform コードをダウンロードしてデプロイする
このチュートリアルでは、sample-eks-docs
git clone git@github.com:aws-samples/sample-eks-docs.git cd sample-eks-docs/ai-ml/set-up-cluster
リポジトリには、先ほど変更した ai-ml/set-up-cluster/ ディレクトリの下に次の構造があります。
set-up-cluster/
├── scripts/
│ └── cleanup.sh
└── terraform/
├── auto-mode/
└── karpenter/
リポジトリには 2 つのデプロイパスがあります。ガイド全体で 1 つのオプションのみを選択し、それを使用します。
-
EKS Auto Mode (
terraform/auto-mode/) – コアネットワーク、ストレージ、ロードバランシングアドオンに加えて、EKS Auto Mode には、EKS ノードモニタリングエージェント、自動ノード修復、高速コンテナプル用の SOCIスナップショッター、デフォルトの NodeClass の GPU 準備など、トレーニングおよび推論ワークロード向けの以下の機能が含まれており、管理されています。NVIDIA デバイスプラグインは、EKS Auto Mode が GPU 対応ノードに使用する Bottlerocket 高速 AMI に含まれています。 -
セルフマネージド Karpenter (
terraform/karpenter/) – EKS Auto Mode のない EKS クラスターでは、Terraform コードがトレーニングおよび推論ワークロードに必要なコンポーネントをインストールおよび設定します。これには、ネットワーキングアドオン (VPC CNI、CoreDNS、kube-proxy)、Karpenter、EKS ノードモニタリングエージェント、NVIDIA デバイスプラグイン、高速コンテナプル用の SOCI スナップショットターが含まれます。
重要
EKS Auto Mode またはセルフマネージド Karpenter を選択し、ガイド全体で使用します。ストリームの途中で切り替えるには、クラスターを破棄して最初からやり直す必要があります。
EKS クラスターオプション: EKS Auto Mode とセルフマネージド Karpenter
Grafana は、デフォルトの認証情報を使用して HTTP 経由でパブリックにアクセス可能です
Grafana ALB Ingress ではデフォルトで var.my_cidr が 0.0.0.0/0 になります。これにより、Grafana はデフォルトの管理者認証情報を使用してプレーン HTTP 経由でパブリックインターネットに公開されます。自動スキャナーは、数分以内にパブリックロードバランサーを検出します。独自の IP アドレスで var.my_cidr を上書きしてアクセスを制限する必要があります。
export MY_CIDR="$(curl -s https://checkip.amazonaws.com)/32" terraform apply -var "my_cidr=${MY_CIDR}"
送信元 IP 許可リストは、完全な保護ではなく、最小限の保護手段として扱います。また、最初のログイン後にデフォルトの Grafana 管理者パスワードを変更します。体制を強化するには、alb.ingress.kubernetes.io/scheme を internal (VPC または接続された VPN 内からのみ到達可能) に変更し、TLS 証明書を追加します。
クラスターをデプロイする
選択したパスのディレクトリに移動し、Terraform を初期化して適用します。
どちらのバリアントもデフォルトで us-east-2 リージョンになります。別のリージョンにデプロイするには、次のステップで terraform apply コマンドに -var "region= を追加します。ここで、region-code"region-code はデプロイする AWS リージョンです。
Terraform コードは、ターゲットリージョン内の利用可能なすべてのアベイラビリティーゾーンを使用しますが、Amazon EKS はこれらのゾーンでのコントロールプレーン配置をサポートしていないuse1-az3、usw1-az2、および cac1-az3 は除外されます。
Terraform 出力を確認する
適用が完了すると、Terraform は次の出力を表示します (値は設定によって異なります)。
Apply complete! Resources: 74 added, 0 changed, 0 destroyed. Outputs: cluster_name = "ai-eks-docs" configure_kubectl = "aws eks update-kubeconfig --region us-east-2 --name ai-eks-docs --alias ai-eks-docs" configure_model_bucket = "export MODEL_BUCKET=ai-eks-docs-models-20250612abc1" model_bucket = "ai-eks-docs-models-20250612abc1" node_iam_role_name = "ai-eks-docs-eks-auto-20250612..." region = "us-east-2"
configure_kubectl 出力は、クラスターに kubectl を向けるすぐに実行できるコマンドです。model_bucket 出力には、モデルの重みの S3 バケット名が含まれます。node_iam_role_name 出力には、ノードが使用する IAM ロールが表示されます。
kubectl を設定する
新しいクラスターに kubectl を向けます。configure_kubectl 出力はすぐに実行できるコマンドです。
eval "$(terraform output -raw configure_kubectl)"
クラスターを確認する
ステップ 2: 動的 GPU NodePool を作成する
GPU NodePools はオプトインです。デフォルトでは、terraform apply は GPU キャパシティや GPU 請求なしでクラスターとモニタリングスタックを作成します。GPU ノードをプロビジョニングするには、戦略名を付けて nodepools 変数を渡します。
On-Demand をフォールバックとした Spot キャパシティを使用して、世代が 4 より大きい G ファミリー GPU インスタンスをプロビジョニングする spot-ondemand 戦略を有効にします:
terraform apply -var 'nodepools={"spot-ondemand"={}}'
このコマンドは、nodepools/spot-ondemand/ ディレクトリから NodePool テンプレートと NodeClass テンプレートを適用します。どちらのパスも同じ NodePool API を使用しますが、NodePool が参照する NodeClass が異なります。
GPU ワークロードがスケジュールされるまで、両方のパスに gpu-inf の 0 ノードが表示されます。EKS Auto Mode と Karpenter は、保留中の Pod がノードを必要とする場合にのみノードを起動します。
ステップ 3: サンプル Pod でテストする
nvidia-smi Pod を使用して GPU NodePool のセットアップをテストします:
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: nvidia-smi labels: guide: ai-eks-docs spec: restartPolicy: OnFailure tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" containers: - name: nvidia-smi image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal command: ["nvidia-smi"] resources: limits: nvidia.com/gpu: 1 EOF
Pod がスケジュールされ、正常に完了していることを確認します:
kubectl get pods nvidia-smi
正常な出力:
NAME READY STATUS RESTARTS AGE nvidia-smi 0/1 Completed 0 67s
STATUS: Completed は、nvidia-smi コマンドが実行され、終了したことを意味します。Pod ログをチェックして、ノードによって検出された GPU を確認します:
kubectl logs nvidia-smi
正常な出力:
+-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 580.159.03 Driver Version: 580.159.03 CUDA Version: 13.0 | +-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA L4 On | 00000000:31:00.0 Off | 0 | | N/A 41C P8 13W / 72W | 0MiB / 23034MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+
出力には、GPU モデル、ドライバーバージョン、CUDA バージョン、利用可能なメモリが表示されます。この例では、Karpenter は 24 GB のメモリを持つ NVIDIA L4 GPU を持つ G6 インスタンスをプロビジョニングしました。GPU モデルとメモリは、Karpenter が選択するインスタンスタイプによって異なります。G5 インスタンスには NVIDIA A10G GPU (24 GB)、G6 インスタンスには NVIDIA L4 GPU (24 GB)、G6e インスタンスには NVIDIA L40S GPU (48 GB) があります。
Karpenter と Kubernetes スケジューラがどのように連携してノードをプロビジョニングし、ポッドを配置したかを理解するには、ポッドのライフサイクルイベントを確認します。
kubectl describe pod nvidia-smi
正常な出力:
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 75s default-scheduler 0/2 nodes are available: 2 node(s) had untolerated taint(s). Normal Nominated 74s eks-auto-mode/compute Pod should schedule on: nodeclaim/gpu-inf-z6q75 Normal Scheduled 35s default-scheduler Successfully assigned default/nvidia-smi to i-0eb897a8302551589 Normal Pulling 27s kubelet spec.containers{nvidia-smi}: Pulling image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal" Normal Pulled 22s kubelet spec.containers{nvidia-smi}: Successfully pulled image "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal" in 5.625s (5.626s including waiting). Image size: 37440620 bytes. Normal Created 22s kubelet spec.containers{nvidia-smi}: Container created Normal Started 21s kubelet spec.containers{nvidia-smi}: Container started
これらのイベントは、Pod スケジューリングシーケンスを示しています。まず、GPU ノードが存在しないため、Pod はスケジュールに失敗します (FailedScheduling)。Karpenter が新しい NodeClaim をノミネートします (Nominated)。ノードが準備完了になるとスケジューラが Pod を割り当てます (Scheduled)。その後、コンテナイメージがプルされて起動します。EKS Auto Mode には、G、P、Trn インスタンスに SOCI (Seekable OCI) 並列プルがデフォルトでインストールおよび設定されており、セルフマネージド Karpenter パスは FastImagePull 機能ゲートを介してそれを明示的に設定します。
注記
セルフマネージド Karpenter クラスターでは、Nominated イベントは eks-auto-mode/compute の代わりに karpenter/compute を表示します。
NodeClaim は、Karpenter が特定のノードをプロビジョニングするために作成するリクエストです。インスタンスタイプ、キャパシティタイプ、AZ、ノードの準備が整っているかどうかが表示されます:
kubectl get nodeclaims
正常な出力:
NAME TYPE CAPACITY ZONE NODE READY AGE gpu-inf-z6q75 g6.xlarge spot us-east-2a i-0eb897a8302551589 True 5m
インスタンスタイプと AZ は異なります。世代が 4 より大きい G ファミリーインスタンスが対象です。
ヒント
ノードが表示されない場合は、容量不足エラーを確認します。
kubectl get events | grep InsufficientCapacityError
Karpenter は、使用できないサービスを 3 分間キャッシュします。NodePool で許可されたインスタンスタイプと AZ を拡張すると、ランディングキャパシティの可能性が高まります。
注記
Karpenter によって起動された Spot インスタンスは EC2 Spot Requests コンソールに表示されません。Karpenter は type: instant で EC2 CreateFleet API を使用します。インスタンスは、spot ライフサイクルとともに EC2 インスタンスコンソールに表示されます。
ステップ 4: NodePool にリザーブドキャパシティを追加する (オプション)
ステップ 2 の GPU NodePool は Spot インスタンスまたは On-Demand インスタンスを動的にプロビジョニングしますが、一部のユースケースでは保証されたキャパシティが必要です。オンデマンドキャパシティ予約 (ODCR) を作成して、GPU キャパシティが必要なときに使用可能になるようにできます。
Terraform では、1 つのコマンドで ODCR が作成され、予約をタグで参照するカスタム NodeClass が作成され、NodePool が更新されてキャパシティタイプ reserved として含まれます。Terraform は nodepool=reserved-spot-ondemand で ODCR にタグ付けし、NodeClass はそのタグでそれを選択します。
警告
次のコマンドは、ノードが実行されているかどうかにかかわらず、terraform destroy またはクリーンアップスクリプトを使用して破棄するまで、すぐに請求が開始され、請求が継続される ODCR を作成します。
デフォルト (g6e.4xlarge、1 個のインスタンス、最初のクラスター AZ) を使用します。
terraform apply -var 'nodepools={"reserved-spot-ondemand"={reservation={}}}'
インスタンスタイプ、カウント、AZ を選択します。
terraform apply -var 'nodepools={"reserved-spot-ondemand"={reservation={instance_type="g6e.2xlarge",instance_count=1,az="us-east-2a"}}}'
reservation オブジェクトは以下のフィールドをサポートします:
-
instance_type– 予約する GPU インスタンスタイプ。デフォルト:g6e.4xlarge。 -
instance_count– 予約するインスタンスの数。デフォルト:1。 -
az– 予約のアベイラビリティーゾーン。デフォルト:""(最初のクラスター AZ を使用します)。
重要
spot-ondemand および reserved-spot-ondemand 戦略は相互に排他的です。nodepools 変数では、最大 1 個を有効にできます。以前にステップ 2 で spot-ondemand を使用した場合は、どちらも同じ gpu-inf NodePool を管理するため、reserved-spot-ondemand コマンドによって置き換えられます。
InsufficientInstanceCapacity エラーが発生した場合、指定された AZ で予約を満たすことはできません。Terraform オペレーション (Ctrl+C) をキャンセルしてから、別の az 値で再実行します:
terraform apply -var 'nodepools={"reserved-spot-ondemand"={reservation={instance_type="g6e.4xlarge",az="us-east-2b"}}}'
適用後、Terraform は NodePool を更新して、キャパシティタイプの要件に reserved、spot、on-demand を含めます。Karpenter は、reserved を最もコスト効率の高いオプションとして扱い、最初に起動します。予約がいっぱいになると、スポットまたはオンデマンドにフォールバックします。
EKS Auto Mode パスで、Terraform は capacityReservationSelectorTerms を介してタグで ODCR を参照するカスタム gpu-inf NodeClass (バンドルされた default NodeClass が読み取り専用であるため) を作成します。セルフマネージド Karpenter パスで、Terraform は gpu-inf EC2NodeClass を capacityReservationSelectorTerms で再適用し、reserved を含めるように NodePool を更新します。
ODCR が作成されたことを確認します:
aws ec2 describe-capacity-reservations \ --filters "Name=state,Values=active" "Name=tag:nodepool,Values=reserved-spot-ondemand" \ --query 'CapacityReservations[0].{Id:CapacityReservationId,State:State,InstanceType:InstanceType,AvailableCount:AvailableInstanceCount}' \ --output table \ --region $(terraform output -raw region)
NodeClass が ODCR を参照していることを確認します:
NodePool の準備が整っていることを確認します:
kubectl get nodepools gpu-inf
正常な出力:
NAME NODECLASS NODES READY AGE gpu-inf gpu-inf 0 True 30s
変更を適用したら、Karpenter がリザーブドキャパシティを優先し、スポットまたはオンデマンドにフォールバックすることを確認します。ポッドごとに 1 GPU をリクエストする 2 レプリカデプロイをデプロイします。ODCR は 1 個のインスタンス (1 GPU) 用であるため、最初のポッドは Karpenter をトリガーしてリザーブドノードを起動します。2 番目のポッドはリザーブドノードに収まらず、Karpenter がスポットキャパシティまたはオンデマンドキャパシティから別のノードを起動するようにトリガーします。
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
実行して終了したステップ 3 の nvidia-smi テスト Pod とは異なり、このデプロイでは Pod の実行 (sleep infinity) が維持されるため、Pod は GPU を保持し、ノードが統合されるのを防ぎます。
異なるノードでスケジュールされたポッドを確認します。
kubectl get pods -l app=gpu-overflow-test -o wide
正常な出力:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES gpu-overflow-test-55d55ff5b9-dvg52 1/1 Running 0 4m42s 10.0.75.210 i-08741a36089ff2088 <none> <none> gpu-overflow-test-55d55ff5b9-hw4m9 1/1 Running 0 4m43s 10.0.82.49 i-0f50cdbacb2017202 <none> <none>
NodeClaims でキャパシティタイプを確認します。
kubectl get nodeclaims
正常な出力:
NAME TYPE CAPACITY ZONE NODE READY AGE gpu-inf-vw99m g6e.4xlarge reserved us-east-2c i-0f50cdbacb2017202 True 6m gpu-inf-s65s6 g6.xlarge spot us-east-2b i-08741a36089ff2088 True 5m59s
予約ノードが最初に起動され、その後に予約がいっぱいになるとスポットノードまたはオンデマンドノードが起動されます。
テストデプロイをクリーンアップする:
kubectl delete deployment gpu-overflow-test
モニタリング
Terraform は、ステップ 1 の terraform apply 中に完全なモニタリングスタックをプロビジョニング済みです。スタックには、Amazon Managed Service for Prometheus (AMP) ワークスペース、IAM ポリシー、EKS Pod Identity Associations for Prometheus リモート書き込みおよび Grafana クエリアクセス、kube-prometheus-stack Helm チャート (Prometheus、Grafana、kube-state-metrics、node-exporter)、GPU メトリクス用の NVIDIA DCGM Exporter が含まれます。
このセクションでは、デプロイされたモニタリングコンポーネントの検証について説明します。
モニタリングポッドの検証
すべてのモニタリングポッドの準備が整うまで待ちます。
kubectl wait --for=condition=Ready pod --all -n monitoring --timeout=300s kubectl get pods -n monitoring
正常な出力:
NAME READY STATUS RESTARTS AGE kube-prometheus-stack-grafana-7c58f54f77-rftrj 3/3 Running 0 5m kube-prometheus-stack-kube-state-metrics-d68dcbc84-5smxq 1/1 Running 0 5m kube-prometheus-stack-operator-5895df479f-ttm47 1/1 Running 0 5m kube-prometheus-stack-prometheus-node-exporter-t9q7s 1/1 Running 0 5m kube-prometheus-stack-prometheus-node-exporter-x6vfb 1/1 Running 0 5m prometheus-kube-prometheus-stack-prometheus-0 2/2 Running 0 5m
Grafana にアクセスする
Grafana は、var.my_cidr で設定した CIDR に制限された、インターネット向け AWS Application Load Balancer (ALB) を介して公開されます。ロードバランサー URL を出力します (ALB がプロビジョニングするには 1〜2 分かかります):
echo "http://$(kubectl get ingress kube-prometheus-stack-grafana -n monitoring -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
ブラウザで URL を開きます。以下のコマンドからユーザー名 admin とパスワードを使用してログインします。
kubectl --namespace monitoring get secrets kube-prometheus-stack-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo
メトリクスパイプラインを検証する
メトリクスパイプラインがエンドツーエンドで機能していることを確認するには:
-
[接続] > [データソース] に移動し、Amazon-Managed-Prometheus がデフォルトのデータソースとしてリストされていることを確認します。
Grafana で AMP データソースを検証する
-
[ドリルダウン] > [メトリクス] に移動し、
upメトリクスを検索します。クラスターのスクレイプターゲットの結果が表示されます。Grafana で
upメトリクスを検証する
up が結果を表示する場合、パイプライン (クラスター → Prometheus → AMP → Grafana) は機能しています。
DCGM GPU メトリクスを検証する
DCGM Exporter DaemonSet は GPU ノードで実行され、GPU 使用率、メモリ、温度、消費電力、NVLink 帯域幅、テンソルアクティビティメトリクスをレポートします。
DCGM Exporter DaemonSet を確認します。
kubectl get daemonset dcgm-exporter -n monitoring
GPU ノードが実行されると (ステップ 2 またはステップ 4 から)、1 つ以上の準備完了の Pod が表示されます。DCGM メトリクスを検証するには、Grafana で [ドリルダウン] > [メトリクス] に移動し、DCGM_ を検索します。
Grafana で DCGM メトリクスを検証する
ダッシュボードを表示するには、[ダッシュボード] > [GPU モニタリング] > [NVIDIA DCGM Exporter ダッシュボード] に移動します。
Grafana の NVIDIA DCGM Exporter ダッシュボード
モデルの重み S3 バケット
Terraform は、モデルの重みを保存するための Amazon S3 バケット、default 名前空間の model-storage-sa ServiceAccount、バケットを対象とする IAM ポリシー、およびそれらをリンクする EKS Pod Identity の関連付けを既に作成しています。serviceAccountName: model-storage-sa を設定したワークロード Pod は、バケットを読み書きできます。
バケットを検証する
Terraform 出力からバケット名を取得します:
MODEL_BUCKET=$(terraform output -raw model_bucket) echo ${MODEL_BUCKET}
バケットが存在することを確認します:
aws s3api head-bucket --bucket ${MODEL_BUCKET}
正常な出力:
{
"BucketArn": "arn:aws:s3:::ai-eks-docs-models-20250612abc1",
"BucketRegion": "us-east-2",
"AccessPointAlias": false
}
model-storage-sa ServiceAccount を使用して AWS CLI イメージで 1 回限りのポッドを実行し、EKS Pod Identity が正しく設定され、S3 アクセスが機能することを確認します。
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
ポッドが完了するのを待ち、ログを確認します。
kubectl wait --for=jsonpath='{.status.phase}'=Succeeded pod/s3-test --timeout=300s kubectl logs s3-test
正常な出力:
=== Caller Identity ===
{
"UserId": "AROA...:eks-ai-eks-docs-model-s-...",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/ai-eks-docs-models-.../eks-ai-eks-docs-..."
}
=== S3 Write Test ===
upload: - to s3://ai-eks-docs-models-20250612abc1/test.txt
=== S3 List Test ===
2026-07-15 12:00:00 19 test.txt
=== S3 Delete Test ===
delete: s3://ai-eks-docs-models-20250612abc1/test.txt発信者 ID は、EKS Pod Identity を介してポッドがモデルストレージロールを引き受けたことを確認します。S3 コマンドは読み取りおよび書き込みアクセスを確認します。
テストポッドをクリーンアップします。
kubectl delete pod s3-test
次のステップ
クラスターの準備ができたら、「モデルのロードと提供」に進み、大規模な言語モデルをデプロイし、推論エンドポイントとやり取りできます。
クリーンアップ
ヒント
このガイドの次のセクションに進む場合は、完全なクリーンアップをスキップします。完了時にのみ実行します。
テストワークロードを削除して、Pod が GPU ノードを保持しないようにします:
kubectl delete pod nvidia-smi --ignore-not-found kubectl delete deployment gpu-overflow-test --ignore-not-found
ODCR をリリースして Spot キャパシティと On-Demand キャパシティにフォールバックするだけの場合は、nodepools 変数を spot-ondemand 戦略に切り替えます:
terraform apply -var 'nodepools={"spot-ondemand"={}}'
これにより、NodePool のキャパシティタイプの要件から reserved がドロップされ、ODCR が破棄され、クラスター、モニタリングスタック、S3 バケットがそのまま残ります。
重要
予約をキャンセルしても、既に実行中のインスタンスは終了しません。これらのインスタンスは、終了するまで標準の On-Demand レートで実行され続けます。上記のように、GPU ワークロードを最初に削除して、予約がリリースされる前に予約済みノードがドレインされるようにします。
破棄する前に Karpenter マネージドノードをドレインして、処理中のノードのライフサイクルによって破棄がブロックされないようにします。ドレインを妨げる PodDisruptionBudgets を削除してから、NodeClaims を削除します。
kubectl delete pdb -A --all --ignore-not-found kubectl delete nodeclaim --all --wait=true --timeout=900s
次に、EKS クラスター、VPC、モニタリングスタック、NodePools と NodeClasses、S3 モデルバケット、ODCR など、Terraform が作成したすべてのリソースを破棄します。
terraform destroy
警告
モデルの重み S3 バケットは force_destroy = true で作成されるため、terraform destroy はアップロードしたモデルの重みとともにバケットを削除します。保持したいものは、最初に別の場所にコピーしてください。
注記
リポジトリには、上記のドレインおよび破棄ステップを実行してから、クラスター名でタグ付けされた孤立した EBS ボリュームをスイープする scripts/cleanup.sh ヘルパーも提供されています。適用元の terraform/<mode>/ ディレクトリ内から実行し、--auto-approve を渡して Terraform の確認プロンプトをスキップします。
クラスターにアクティブなキャパシティ予約が残っていないことを確認します。
aws ec2 describe-capacity-reservations \ --filters "Name=state,Values=active" "Name=tag:nodepool,Values=reserved-spot-ondemand" \ --query 'CapacityReservations[].CapacityReservationId' \ --output text
結果が空の場合、予約はアクティブではなく、それ以上の料金はかかりません。