このチュートリアルでは、KEDA を使用して GKE ワークロードを Pod 0 にスケールダウンする方法について説明します。Deployment を 0 Pod にスケーリングすると、非アクティブな期間(週末やオフィス以外の時間など)や、定期的なジョブなどの断続的なワークロードでリソースを節約できます。
目標
このチュートリアルでは、次のユースケースについて説明します。
- Pub/Sub ワークロードをゼロにスケーリングする: Pub/Sub トピックでキューに登録されているメッセージ数に比例して Pod の数をスケーリングします。キューが空になると、ワークロードは自動的にゼロ Pod にスケールダウンします。
- LLM ワークロードをゼロにスケールする。GPU を使用するノードに LLM モデルサーバーをデプロイします。サービスがアイドル状態になると、ワークロードは自動的にゼロ Pod にスケールダウンします。
費用
このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。
- GKE
- GPU resources used by GKE
- Pub/Sub
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
このチュートリアルでは、Cloud Shell を使用してコマンドを実行します。Cloud Shell は、 Google Cloudでホストされているリソースを管理するためのシェル環境です。これには、Google Cloud CLI、kubectl、Helm、Terraform コマンドライン ツールがプリインストールされています。Cloud Shell を使用しない場合は、Google Cloud CLI と Helm をインストールする必要があります。
-
このページにあるコマンドを実行するには、次のいずれかの開発環境で gcloud CLI を設定します。
Cloud Shell
gcloud CLI がすでに設定されているオンライン ターミナルを使用するには、Cloud Shell をアクティブにします。
このページの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。セッションが初期化されるまで数秒かかることがあります。
ローカルシェル
ローカル開発環境を使用する手順は次のとおりです。
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. 環境変数を設定します。
export PROJECT_ID=PROJECT_ID export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)') export LOCATION=LOCATIONPROJECT_IDは、 Google Cloudプロジェクト ID に置き換え、LOCATIONは、GKE クラスタを作成するリージョンまたはゾーンに置き換えます。チュートリアル全体を 1 つのセッションで完了しない場合や、なんらかの理由で環境変数が設定されていない場合は、このコマンドを再度実行して、変数を再度設定してください。
クラスタ自動スケーリングと Workload Identity Federation for GKE を有効にして Standard GKE クラスタを作成します。
gcloud container clusters create scale-to-zero \ --project=${PROJECT_ID} --location=${LOCATION} \ --machine-type=n1-standard-2 \ --enable-autoscaling --min-nodes=1 --max-nodes=5 \ --workload-pool=${PROJECT_ID}.svc.id.goog想定される自動スケーリングの動作を記述する
ScaledObjectリソースを作成します。curl https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-scaledobject.yaml | envsubst | kubectl apply -f -これにより、次のオブジェクトが作成されます。
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: keda-pubsub namespace: keda-pubsub spec: maxReplicaCount: 5 scaleTargetRef: name: keda-pubsub triggers: - type: gcp-pubsub authenticationRef: name: keda-auth metadata: subscriptionName: "projects/${PROJECT_ID}/subscriptions/keda-echo-read"ScaledObjectオブジェクトに基づいて KEDA が作成するHorizontalPodAutoscaler(HPA)オブジェクトを調べます。kubectl get hpa keda-hpa-keda-pubsub -n keda-pubsub -o yaml自動スケーリングの詳細については、Kubernetes のドキュメントをご覧ください。
KEDA が Pub/Sub サブスクリプションが空であることを認識し、Deployment をゼロレプリカにスケーリングするまで待機します。
ワークロード オートスケーラーを調べます。
kubectl describe hpa keda-hpa-keda-pubsub -n keda-pubsubコマンド レスポンスで、
ScalingActive条件が false になっていることを確認します。関連するメッセージは、KEDA が Deployment を 0 にスケーリングしたことを HorizontalPodAutoscaler が認識したことを示しています。この時点で、Deployment が 1 つの Pod にスケールバックされるまで、オペレーションが停止します。Name: keda-hpa-keda-pubsub Namespace: keda-pubsub Metrics: ( current / target ) "s0-gcp-ps-projects-[...]]" (target average value): 0 / 10 Min replicas: 1 Max replicas: 5 Deployment pods: 5 current / 5 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True ScaleDownStabilized recent recommendations were higher than current one [...] ScalingActive False ScalingDisabled scaling is disabled since the replica count of the target is zero ScalingLimited True TooManyReplicas the desired replica count is more than the maximum replica countPub/Sub トピックにメッセージをキューに追加します。
for num in {1..20} do gcloud pubsub topics publish keda-echo --project=${PROJECT_ID} --message="Test" doneDeployment がスケールアップされていることを確認します。
kubectl get deployments -n keda-pubsub出力で「Ready」列に 1 つのレプリカが表示されていることを確認します。
NAME READY UP-TO-DATE AVAILABLE AGE keda-pubsub 1/1 1 1 2dGPU が割り当てられた
g2-standard-4ノードを含むノードプールを作成し、0~2 個のノードを提供するクラスタ自動スケーリングを構成します。gcloud container node-pools create gpu --machine-type=g2-standard-4 \ --location=${LOCATION} --cluster=scale-to-zero \ --min-nodes 0 --max-nodes 2 --num-nodes=1 --enable-autoscaling公式の Ollama Helm チャート リポジトリを追加し、ローカル Helm クライアントのリポジトリを更新します。
helm repo add ollama-helm https://otwld.github.io/ollama-helm/ helm repo updateHelm チャートを使用して Ollama サーバーをデプロイします。
helm install ollama ollama-helm/ollama --create-namespace --namespace ollama \ -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/helm-values-ollama.yamlhelm-values-ollama.yaml構成では、読み込む LLM モデル、GPU 要件、Ollama サーバーの TCP ポートを指定します。想定される自動スケーリングの動作を記述する
HTTPScaledObjectリソースを作成します。kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/keda-ollama-httpscaledobject.yamlこれにより、次のフィールドを定義する
HTTPScaledObjectオブジェクトが作成されます。scaleTargetRef: KEDA-HTTP がリクエストを転送する Service を指定します。この例では、ホストollama.ollamaを持つすべてのリクエストが Ollama サーバーに転送されます。scaledownPeriod: リクエストを受信していないときにスケールダウンする速度(秒単位)を指定します。replicas: Ollama Deployment で維持する Pod の最小数と最大数を指定します。scalingMetric: この例ではリクエスト レートなど、自動スケーリングの実行に使用される指標を指定します。その他の指標オプションについては、KEDA-HTTP のドキュメントをご覧ください。
kind: HTTPScaledObject apiVersion: http.keda.sh/v1alpha1 metadata: namespace: ollama name: ollama spec: hosts: - ollama.ollama scaleTargetRef: name: ollama kind: Deployment apiVersion: apps/v1 service: ollama port: 11434 replicas: min: 0 max: 2 scaledownPeriod: 3600 scalingMetric: requestRate: targetValue: 20次のコマンドを実行して、KEDA-HTTP が前の手順で作成した
HTTPScaledObjectを正常に処理したことを確認します。kubectl get hpa,scaledobject -n ollama出力には、
HorizontalPodAutoscaler(KEDA によって作成)とScaledObject(KEDA-HTTP によって作成)のリソースが含まれます。NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE horizontalpodautoscaler.autoscaling/keda-hpa-ollama Deployment/ollama 0/100 (avg) 1 2 1 2d NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE FALLBACK PAUSED AGE scaledobject.keda.sh/ollama apps/v1.Deployment ollama 0 2 external-push True False False Unknown 2dDeployment が Pod を 0 にスケールダウンしていることを確認します。
scaledownPeriodフィールドで設定した時間待ってから、コマンドを実行します。kubectl get deployments -n ollama出力は、KEDA が Ollama Deployment をスケールダウンし、Pod が実行されていないことを示しています。
NAME READY UP-TO-DATE AVAILABLE AGE ollama 0/0 0 0 2dPub/Sub サブスクリプションとトピックをクリーンアップします。
gcloud pubsub subscriptions delete keda-echo-read gcloud pubsub topics delete keda-echoGKE クラスタを削除します。
gcloud container clusters delete scale-to-zero --location=${LOCATION}- GKE で LLM 推論ワークロードを自動スケーリングする方法を確認する。
- KEDA の GitHub リポジトリとドキュメントを確認する。
環境設定
Cloud Shell を使用して環境を設定するには、次の操作を行います。
KEDA をインストールする
KEDA は、Kubernetes HorizontalPodAutoscaler を補完するコンポーネントです。KEDA を使用すると、Deployment をゼロ Pod にスケールダウンし、ゼロ Pod から 1 Pod にスケールアップできます。Deployment は、クラスタ内のノードに分散された Pod の複数のレプリカを実行できる Kubernetes API オブジェクトです。標準の HorizontalPodAutoscaler アルゴリズムは、GKE が 1 つ以上の Pod を作成した後に適用されます。
GKE が Deployment を 0 個の Pod にスケーリングすると、実行中の Pod がないため、自動スケーリングは CPU 使用率などの Pod 指標に依存できません。その結果、KEDA では、Kubernetes External Metrics API の実装を使用して、クラスタの外部から指標を取得できます。この API を使用すると、Pub/Sub サブスクリプションの未処理メッセージ数などの指標に基づいて自動スケーリングできます。サポートされているすべての指標ソースの一覧については、KEDA のドキュメントをご覧ください。
Helm または kubectl を使用して、クラスタに KEDA をインストールします。
Helm
次のコマンドを実行して KEDA Helm リポジトリを追加し、KEDA Helm チャートをインストールして、KEDA サービス アカウントに Cloud Monitoring への読み取りアクセス権を付与します。
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --create-namespace --namespace keda
gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
--role roles/monitoring.viewer \
--member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/keda/sa/keda-operator
このコマンドは、クラスタに Workload Identity Federation for GKE を設定することを要求する認可ルールも設定します。
kubectl
次のコマンドを実行して kubectl apply を使用して KEDA をインストールし、KEDA サービス アカウントに Cloud Monitoring への読み取りアクセス権を付与します。
kubectl apply --server-side -f https://github.com/kedacore/keda/releases/download/v2.15.1/keda-2.15.1.yaml
gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
--role roles/monitoring.viewer \
--member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/keda/sa/keda-operator
このコマンドは、クラスタに Workload Identity Federation for GKE を設定することを要求する認可ルールも設定します。
すべての KEDA リソースが keda Namespace にあることを確認します。
kubectl get all -n keda
KEDA の設計とリソースの詳細については、KEDA のドキュメントをご覧ください。
Pub/Sub ワークロードをゼロにスケーリングする
このセクションでは、Pub/Sub サブスクリプションからのメッセージを処理し、各メッセージを処理して完了を確認するワークロードについて説明します。ワークロードは動的にスケーリングされます。未確認メッセージの数が増えると、自動スケーリングにより Pod がインスタンス化され、タイムリーな処理が保証されます。
ゼロにスケーリングすると、しばらくメッセージが受信されていないときに Pod がインスタンス化されなくなります。これにより、Pod が長時間アイドル状態にならないため、リソースを節約できます。
Pub/Sub ワークロードをデプロイする
Pub/Sub トピックでキューに追加されたメッセージを処理するサンプル ワークロードをデプロイします。実際のワークロードをシミュレートするため、このサンプル プログラムはメッセージを確認する前に 3 秒間待機します。ワークロードは、keda-pubsub-sa サービス アカウントで実行するように構成されています。
次のコマンドを実行して Pub/Sub トピックとサブスクリプションを作成し、権限を構成して、keda-pubsub Namespace でワークロードを開始する Deployment を作成します。
gcloud pubsub topics create keda-echo
gcloud pubsub subscriptions create keda-echo-read --topic=keda-echo
gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
--role=roles/pubsub.subscriber \
--member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/keda-pubsub/sa/keda-pubsub-sa
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-with-workload-identity.yaml
ゼロへのスケーリングを構成する
Pub/Sub ワークロードをゼロにスケーリングするように構成するには、KEDA を使用して ScaledObject リソースを定義し、Deployment のスケーリング方法を指定します。KEDA は、基盤となる HorizontalPodAutoscaler(HPA)オブジェクトを自動的に作成して管理します。
スケールアップをトリガーする
Deployment をスケールアップするには:
KEDA は、キューが空でないことを確認した後、Deployment をスケールアップします。
LLM ワークロードをゼロにスケーリングする
このセクションでは、GPU が割り当てられた Ollama サーバーをデプロイする大規模言語モデル(LLM)ワークロードについて説明します。Ollama を使用すると、Gemma や Lamma 2 などの一般的な LLM を実行できます。また、主に HTTP を介して機能を公開します。
KEDA-HTTP アドオンをインストールする
非アクティブな期間中に HTTP サービスをゼロ Pod にスケールダウンすると、リクエストを処理するバックエンドがないため、リクエストが失敗します。
このセクションでは、KEDA-HTTP アドオンを使用してこの問題を解決する方法について説明します。KEDA-HTTP は、ユーザー リクエストを受信してゼロへのスケーリングをするように構成された Service に転送する HTTP プロキシを開始します。Service に Pod がない場合、プロキシは Service のスケールアップをトリガーし、Service が少なくとも 1 つの Pod にスケールアップするまでリクエストをバッファリングします。
Helm を使用して KEDA-HTTP アドオンをインストールします。詳細については、KEDA-HTTP のドキュメントをご覧ください。
helm repo add ollama-helm https://otwld.github.io/ollama-helm/
helm repo update
# Set the proxy timeout to 120s, giving Ollama time to start.
helm install http-add-on kedacore/keda-add-ons-http \
--create-namespace --namespace keda \
--set interceptor.responseHeaderTimeout=120s
Ollama LLM ワークロードをデプロイする
Ollama LLM ワークロードをデプロイするには:
ゼロへのスケーリングを構成する
Ollama ワークロードをゼロにスケーリングするように構成するには、KEDA-HTTP が HTTPScaledObject を使用します。
スケールアップをトリガーする
Deployment のスケールアップを促すには、KEDA-HTTP アドオンによって設定されたプロキシを使用して Ollama サービスを呼び出します。これにより、リクエスト レート指標の値が増加し、最初の Pod の作成がトリガーされます。
プロキシは外部に公開されていないため、kubectl ポート転送機能を使用してプロキシにアクセスします。
kubectl port-forward svc/keda-add-ons-http-interceptor-proxy -n keda 8080:8080 &
# Set the 'Host' HTTP header so that the proxy routes requests to the Ollama server.
curl -H "Host: ollama.ollama" \
http://localhost:8080/api/generate \
-d '{ "model": "gemma:7b", "prompt": "Hello!" }'
curl コマンドは、プロンプト「Hello!」を Gemma モデルに送信します。レスポンスで返される回答トークンを確認します。API の仕様については、Ollama ガイドをご覧ください。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。