このドキュメントでは、マルチクラスタ Google Kubernetes Engine(GKE)Inference Gateway を設定して、異なるリージョンにまたがる複数の GKE クラスタ間で AI/ML 推論ワークロードをインテリジェントにロード バランシングする方法について説明します。この設定では、Gateway API、マルチクラスタ Ingress、InferencePool や InferenceObjective などのカスタム リソースを使用して、スケーラビリティを向上させ、高可用性を確保し、モデル提供デプロイのリソース使用率を最適化します。
このドキュメントを理解するには、次のことを把握しておく必要があります。
- GKE での AI/ML オーケストレーション。
- 生成 AI の用語。
- GKE ネットワーキング のコンセプト(次を含む)。
- でのロード バランシング Google Cloud、特に ロードバランサが GKE とやり取りする方法。
このドキュメントは、次のペルソナを対象としています。
- AI / ML ワークロードの提供に GKE のコンテナ オーケストレーション機能を使用する ML エンジニア、プラットフォーム管理者 / オペレーター、データ / AI スペシャリスト。
- GKE ネットワーキングを操作するクラウド アーキテクトまたはネットワーク スペシャリスト。
のコンテンツで使用されている一般的なロールとタスク例の詳細については、GKE Enterprise ユーザーの一般的なロールと タスクをご覧ください。Google Cloud
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API を有効にする
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。gcloud CLI をインストール済みの場合は、
gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
Compute Engine API、Kubernetes Engine API、Model Armor、Network Services API を有効にします。
Autoscaling API を有効にします。
Autoscaling API に移動し、手順に沿って操作します。
Hugging Face の前提条件:
- Hugging Face アカウントをお持ちでない場合は、アカウントを作成します。
- Hugging Face で Llama 3.1 モデルへのアクセスをリクエストして承認を得ます。
- Hugging Face のモデルのページでライセンス同意契約に署名します。
- 少なくとも
Read権限を持つ Hugging Face アクセス トークンを生成します。
要件
- H100 GPU 用にプロジェクトに十分な割り当てがあることを確認します。詳細については、 GPU 割り当てを計画すると数量に基づく割り当てをご覧ください。
- GKE バージョン 1.34.1-gke.1127000 以降を使用します。
- gcloud CLI バージョン 480.0.0 以降を使用します。
- ノード サービス アカウントに、 指標を書き込む権限が Autoscaling API に必要です。
- プロジェクトに
roles/container.adminとroles/iam.serviceAccountAdminの IAM ロールが必要です。
マルチポートと NEG の上限
マルチクラスタ設定でマルチポート InferencePool リソースをデプロイする場合は、 Backend Service NEG Google Cloud の上限を考慮してください。各ゾーンの各ポートに専用の NEG が作成されます。たとえば、3 つのゾーンを持つリージョン クラスタと 8 つのポートで構成された InferencePool では、24 個の NEG が使用されます。Backend Service は 50 個の NEG に制限されているため、上限に達する前に、最大 2 つのクラスタからこの特定の InferencePool を集約できます。
マルチクラスタ Inference Gateway を設定する
マルチクラスタ GKE Inference Gateway を設定する手順は次のとおりです。
クラスタとノードプールを作成する
AI/ML 推論ワークロードをホストし、リージョン間のロード バランシングを有効にするには、異なるリージョンに 2 つの GKE クラスタを作成します。各クラスタには H100 GPU ノードプールがあります。
最初のクラスタを作成します。
gcloud container clusters create CLUSTER_1_NAME \ --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediately次のように置き換えます。
CLUSTER_1_NAME: 最初のクラスタの名前(gke-westなど)。LOCATION: 最初のクラスタのリージョン(europe-west3など)。PROJECT_ID: プロジェクト ID。GKE_VERSION: 使用する GKE バージョン(1.34.1-gke.1127000など)。MACHINE_TYPE: クラスタノードのマシンタイプ(c2-standard-16など)。DISK_TYPE: クラスタノードのディスクタイプ(pd-standardなど)。
最初のクラスタの H100 ノードプールを作成します。
gcloud container node-pools create NODE_POOL_NAME \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_1_ZONE \ --node-locations=CLUSTER_1_ZONE \ --cluster=CLUSTER_1_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediately次のように置き換えます。
NODE_POOL_NAME: ノードプールの名前(h100など)。PROJECT_ID: プロジェクト ID。CLUSTER_1_ZONE: 最初のクラスタのゾーン(europe-west3-cなど)。CLUSTER_1_NAME: 最初のクラスタの名前(gke-westなど)。NODE_POOL_MACHINE_TYPE: ノードプールのマシンタイプ(a3-highgpu-2gなど)。NUM_NODES: ノードプール内のノード数(3など)。
認証情報を取得します。
gcloud container clusters get-credentials CLUSTER_1_NAME \ --location CLUSTER_1_ZONE \ --project=PROJECT_ID次のように置き換えます。
PROJECT_ID: プロジェクト ID。CLUSTER_1_NAME: 最初のクラスタの名前(gke-westなど)。CLUSTER_1_ZONE: 最初のクラスタのゾーン(europe-west3-cなど)。
最初のクラスタで、Hugging Face トークンの Secret を作成します。
kubectl create secret generic hf-token \ --from-literal=token=HF_TOKENHF_TOKENは、Hugging Face アクセス トークンに置き換えます。最初のクラスタとは異なるリージョンに 2 番目のクラスタを作成します。
gcloud container clusters create gke-east --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus \ --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediately while the cluster is created in the background.次のように置き換えます。
LOCATION: 2 番目のクラスタのリージョン。 これは最初のクラスタとは異なるリージョンである必要があります。例:us-east4。PROJECT_ID: プロジェクト ID。GKE_VERSION: 使用する GKE バージョン(1.34.1-gke.1127000など)。MACHINE_TYPE: クラスタノードのマシンタイプ(c2-standard-16など)。DISK_TYPE: クラスタノードのディスクタイプ(pd-standardなど)。
2 番目のクラスタの H100 ノードプールを作成します。
gcloud container node-pools create h100 \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_2_ZONE \ --node-locations=CLUSTER_2_ZONE \ --cluster=CLUSTER_2_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediately次のように置き換えます。
PROJECT_ID: プロジェクト ID。CLUSTER_2_ZONE: 2 番目のクラスタのゾーン(us-east4-aなど)。CLUSTER_2_NAME: 2 番目のクラスタの名前(gke-eastなど)。NODE_POOL_MACHINE_TYPE: ノードプールのマシンタイプ(a3-highgpu-2gなど)。NUM_NODES: ノードプール内のノード数(3など)。
2 番目のクラスタで、認証情報を取得し、Hugging Face トークンの Secret を作成します。
gcloud container clusters get-credentials CLUSTER_2_NAME \ --location CLUSTER_2_ZONE \ --project=PROJECT_ID kubectl create secret generic hf-token --from-literal=token=HF_TOKEN次のように置き換えます。
CLUSTER_2_NAME: 2 番目のクラスタの名前(gke-eastなど)。CLUSTER_2_ZONE: 2 番目のクラスタのゾーン(us-east4-aなど)。PROJECT_ID: プロジェクト ID。HF_TOKEN: Hugging Face アクセス トークン。
クラスタをフリートに登録する
マルチクラスタ GKE Inference Gateway などのマルチクラスタ機能を有効にするには、クラスタをフリートに登録します。
両方のクラスタをプロジェクトのフリートに登録します。
gcloud container fleet memberships register CLUSTER_1_NAME \ --gke-cluster CLUSTER_1_ZONE/CLUSTER_1_NAME \ --location=global \ --project=PROJECT_ID gcloud container fleet memberships register CLUSTER_2_NAME \ --gke-cluster CLUSTER_2_ZONE/CLUSTER_2_NAME \ --location=global \ --project=PROJECT_ID次のように置き換えます。
CLUSTER_1_NAME: 最初のクラスタの名前(gke-westなど)。CLUSTER_1_ZONE: 最初のクラスタのゾーン(europe-west3-cなど)。PROJECT_ID: プロジェクト ID。CLUSTER_2_NAME: 2 番目のクラスタの名前(gke-eastなど)。CLUSTER_2_ZONE: 2 番目のクラスタのゾーン(us-east4-aなど)。
単一の Gateway で複数のクラスタ間のトラフィックを管理できるようにするには、マルチクラスタ Ingress 機能を有効にして、構成クラスタを指定します。
gcloud container fleet ingress enable \ --config-membership=projects/PROJECT_ID/locations/global/memberships/CLUSTER_1_NAME次のように置き換えます。
PROJECT_ID: プロジェクト ID。CLUSTER_1_NAME: 最初のクラスタの名前(gke-westなど)。
プロキシ専用サブネットを作成する
内部 Gateway の場合は、各リージョンにプロキシ専用サブネットを作成します。内部 Gateway の Envoy プロキシは、これらの専用サブネットを使用して VPC ネットワーク内のトラフィックを処理します。
最初のクラスタのリージョンにサブネットを作成します。
gcloud compute networks subnets create CLUSTER_1_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_1_REGION \ --network=default \ --range=10.0.0.0/23 \ --project=PROJECT_ID2 番目のクラスタのリージョンにサブネットを作成します。
gcloud compute networks subnets create CLUSTER_2_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_2_REGION \ --network=default \ --range=10.5.0.0/23 \ --project=PROJECT_ID次のように置き換えます。
PROJECT_ID: プロジェクト ID。CLUSTER_1_REGION: 最初のクラスタのリージョン(europe-west3など)。CLUSTER_2_REGION: 2 番目のクラスタのリージョン(us-east4など)。
必要な CRD をインストールする
マルチクラスタ GKE Inference Gateway は、InferencePool や InferenceObjective などのカスタム リソースを使用します。GKE Gateway API コントローラは、InferencePool カスタム リソース定義(CRD)を管理します。ただし、アルファ版の InferenceObjective CRD はクラスタに手動でインストールする必要があります。
クラスタのコンテキスト変数を定義します。
CLUSTER1_CONTEXT="gke_PROJECT_ID_CLUSTER_1_ZONE_CLUSTER_1_NAME" CLUSTER2_CONTEXT="gke_PROJECT_ID_CLUSTER_2_ZONE_CLUSTER_2_NAME"次のように置き換えます。
PROJECT_ID: プロジェクト ID。CLUSTER_1_ZONE: 最初のクラスタのゾーン(europe-west3-cなど)。CLUSTER_1_NAME: 最初のクラスタの名前(gke-westなど)。CLUSTER_2_ZONE: 2 番目のクラスタのゾーン(us-east4-aなど)。CLUSTER_2_NAME: 2 番目のクラスタの名前(gke-eastなど)。
両方のクラスタに InferenceObjective CRD をインストールします。
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CLUSTER2_CONTEXT
リソースをターゲット クラスタにデプロイする
各クラスタで AI/ML 推論ワークロードを使用できるようにするには、モデルサーバーや InferenceObjective カスタム リソースなどの必要なリソースをデプロイします。
両方のクラスタにモデルサーバーをデプロイします。
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/manifests/vllm/gpu-deployment.yaml --context=CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/manifests/vllm/gpu-deployment.yaml --context=CLUSTER2_CONTEXT次のように置き換えます。
CLUSTER1_CONTEXT: 最初のクラスタのコンテキスト(gke_my-project_europe-west3-c_gke-westなど)。CLUSTER2_CONTEXT: 2 番目のクラスタのコンテキスト(gke_my-project_us-east4-a_gke-eastなど)。
InferenceObjective リソースを両方のクラスタにデプロイします。次のサンプル マニフェストを
inference-objective.yamlという名前のファイルに保存します。apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceObjective metadata: name: food-review spec: priority: 10 poolRef: name: llama3-8b-instruct group: "inference.networking.k8s.io"マニフェストを両方のクラスタに適用します。
kubectl apply -f inference-objective.yaml --context=CLUSTER1_CONTEXT kubectl apply -f inference-objective.yaml --context=CLUSTER2_CONTEXT次のように置き換えます。
CLUSTER1_CONTEXT: 最初のクラスタのコンテキスト(gke_my-project_europe-west3-c_gke-westなど)。CLUSTER2_CONTEXT: 2 番目のクラスタのコンテキスト(gke_my-project_us-east4-a_gke-eastなど)。
Helm を使用して、InferencePool リソースを両方のクラスタにデプロイします。
helm install vllm-llama3-8b-instruct \ --kube-context CLUSTER1_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.1.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepoolhelm install vllm-llama3-8b-instruct \ --kube-context CLUSTER2_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.1.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool次のように置き換えます。
CLUSTER1_CONTEXT: 最初のクラスタのコンテキスト(gke_my-project_europe-west3-c_gke-westなど)。CLUSTER2_CONTEXT: 2 番目のクラスタのコンテキスト(gke_my-project_us-east4-a_gke-eastなど)。
両方のクラスタで InferencePool リソースをエクスポート済みとしてマークします。このアノテーションにより、InferencePool を構成クラスタでインポートできるようになります。これは、マルチクラスタ ルーティングに必要なステップです。
kubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \ --context=CLUSTER1_CONTEXTkubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \ --context=CLUSTER2_CONTEXT次のように置き換えます。
CLUSTER1_CONTEXT: 最初のクラスタのコンテキスト(gke_my-project_europe-west3-c_gke-westなど)。CLUSTER2_CONTEXT: 2 番目のクラスタのコンテキスト(gke_my-project_us-east4-a_gke-eastなど)。
リソースを構成クラスタにデプロイする
登録されているすべてのクラスタの InferencePool リソース間でトラフィックをルーティングしてロード バランシングする方法を定義するには、Gateway、HTTPRoute、HealthCheckPolicy
リソースをデプロイします。これらのリソースは、指定された構成クラスタ(このドキュメントでは gke-west)にのみデプロイします。
次の内容で
mcig.yamlという名前のファイルを作成します。--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: cross-region-gateway namespace: default spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: - type: networking.gke.io/ephemeral-ipv4-address/europe-west3 value: "europe-west3" - type: networking.gke.io/ephemeral-ipv4-address/us-east4 value: "us-east4" listeners: - name: http protocol: HTTP port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: vllm-llama3-8b-instruct-default spec: parentRefs: - name: cross-region-gateway kind: Gateway rules: - backendRefs: - group: networking.gke.io kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct --- apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: health-check-policy namespace: default spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: config: type: HTTP httpHealthCheck: requestPath: /health port: 8000次のようにマニフェストを適用します。
kubectl apply -f mcig.yaml --context=CLUSTER1_CONTEXTCLUSTER1_CONTEXTは、最初のクラスタ(構成クラスタ)のコンテキスト(gke_my-project_europe-west3-c_gke-westなど)に置き換えます。
カスタム指標のレポート送信を有効にする
カスタム指標のレポート送信を有効にして、リージョン間のロード バランシングを改善するには、すべてのクラスタから KV キャッシュ使用率指標をエクスポートします。ロードバランサは、このエクスポートされた KV キャッシュ使用率データをカスタム ロードシグナルとして使用します。このカスタム ロードシグナルを使用すると、各クラスタの実際のワークロードに基づいて、よりインテリジェントなロード バランシングの決定が可能になります。
次の内容で
metrics.yamlという名前のファイルを作成します。apiVersion: autoscaling.gke.io/v1beta1 kind: AutoscalingMetric metadata: name: gpu-cache namespace: default spec: selector: matchLabels: app: vllm-llama3-8b-instruct endpoints: - port: 8000 path: /metrics metrics: - name: vllm:kv_cache_usage_perc # For vLLM versions v0.10.2 and newer exportName: kv-cache - name: vllm:gpu_cache_usage_perc # For vLLM versions v0.6.2 and newer exportName: kv-cache-old両方のクラスタに指標構成を適用します。
kubectl apply -f metrics.yaml --context=CLUSTER1_CONTEXT kubectl apply -f metrics.yaml --context=CLUSTER2_CONTEXT次のように置き換えます。
CLUSTER1_CONTEXT: 最初のクラスタのコンテキスト(gke_my-project_europe-west3-c_gke-westなど)。CLUSTER2_CONTEXT: 2 番目のクラスタのコンテキスト(gke_my-project_us-east4-a_gke-eastなど)。
ロード バランシング ポリシーを構成する
AI/ML 推論リクエストが GKE クラスタに分散される方法を最適化するには、ロード バランシング ポリシーを構成します。適切なバランシング モードを選択すると、リソース使用率を効率化し、個々のクラスタの過負荷を防ぎ、推論サービスの全体的なパフォーマンスと応答性を向上させることができます。
タイムアウトを構成する
リクエストの所要時間が長くなることが予想される場合は、ロードバランサのタイムアウトを長く構成します。GCPBackendPolicy で、timeoutSec フィールドを推定 P99 リクエスト レイテンシの 2 倍以上に設定します。
たとえば、次のマニフェストでは、ロードバランサのタイムアウトが 100 秒に設定されています。
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
name: my-backend-policy
spec:
targetRef:
group: "networking.gke.io"
kind: GCPInferencePoolImport
name: vllm-llama3-8b-instruct
default:
timeoutSec: 100
balancingMode: CUSTOM_METRICS
trafficDuration: LONG
customMetrics:
- name: gke.named_metrics.kv-cache
dryRun: false
maxUtilizationPercent: 60
詳細については、 マルチクラスタ Gateway の制限事項をご覧ください。
[カスタム指標] ロード バランシング モードと [処理中のリクエスト] ロード バランシング モードは相互に排他的であるため、GCPBackendPolicy で構成できるのはどちらか 1 つのみです。
デプロイのロード バランシング モードを選択します。
カスタム指標
ロード バランシングを最適化するには、目標使用率を 60% に設定します。この目標を達成するには、GCPBackendPolicy の customMetrics 構成で maxUtilizationPercent: 60 を設定します。
kv-cacheカスタム指標に基づいてロード バランシングを有効にするには、次の内容でbackend-policy.yamlという名前のファイルを作成します。apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: balancingMode: CUSTOM_METRICS trafficDuration: LONG customMetrics: - name: gke.named_metrics.kv-cache dryRun: false maxUtilizationPercent: 60新しいポリシーを適用します。
kubectl apply -f backend-policy.yaml --context=CLUSTER1_CONTEXTCLUSTER1_CONTEXTは、最初のクラスタのコンテキスト(gke_my-project-europe-west3-c-gke-westなど)に置き換えます。
処理中のリクエスト
処理中のバランシング モードを使用するには、各バックエンドが処理できる処理中のリクエスト数を推定し、容量値を明示的に構成します。
処理中のリクエスト数に基づいてロード バランシングを有効にするには、次の内容で
backend-policy.yamlという名前のファイルを作成します。kind: GCPBackendPolicy apiVersion: networking.gke.io/v1 metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: balancingMode: IN_FLIGHT trafficDuration: LONG maxInFlightRequestsPerEndpoint: 1000 dryRun: false新しいポリシーを適用します。
kubectl apply -f backend-policy.yaml --context=CLUSTER1_CONTEXTCLUSTER1_CONTEXTは、最初のクラスタのコンテキスト(gke_my-project_europe-west3-c_gke-westなど)に置き換えます。
デプロイを確認する
内部ロードバランサを確認するには、VPC ネットワーク内からリクエストを送信する必要があります。これは、内部ロードバランサがプライベート IP アドレスを使用するためです。クラスタの 1 つに一時的な Pod を実行して VPC ネットワークからリクエストを送信し、内部ロードバランサを確認します。
新しいシェルから、Gateway の IP アドレスを取得します。
GW_IP=$(kubectl get gateway/cross-region-gateway -n default --context=$CLUSTER1_CONTEXT -o jsonpath='{.status.addresses[0].value}')クラスタ内の一時的な Pod からテスト リクエストを送信します。
kubectl run -it --rm --image=curlimages/curl curly --context=$CLUSTER1_CONTEXT -- \ curl -i -X POST ${GW_IP}:80/v1/completions -H 'Content-Type: application/json' -d '{ "model": "food-review-1", "prompt": "What is the best pizza in the world?", "max_tokens": 100, "temperature": 0 }'
次のステップ
- GKE Gateway API の詳細を確認する。
- マルチクラスタ GKE Inference Gateway の詳細を確認する。
- マルチクラスタ Ingress の詳細を確認する。