![[アップデート] GKEのカスタムメトリクスを使ったHPAでのスケーリングが外部コンポーネントなしでできるようになったので試してみた](https://images.ctfassets.net/ct0aopd36mqt/rj0bPf9FBBkly9rT3IIkW/00a32d06aeb2bde2058545d747b15f2a/googlecloud-kubernetesengine-gke.png?w=3840&fm=webp)
[アップデート] GKEのカスタムメトリクスを使ったHPAでのスケーリングが外部コンポーネントなしでできるようになったので試してみた
はじめに
皆様こんにちは、あかいけです。
「CPU/メモリ以外のメトリクスでHPAを使ってPodをスケールさせたい」と思ったことはありますか?私はあります。
もちろんPrometheusやKEDAを使えば実現できますが、そのためのコンポーネントを別途構築・運用する必要があり、めんどくさいなぁ…と感じていました。
そして先日開催されたGoogle Cloud Next 2026でGKEに関する様々なアップデートが発表され、
その中に「Intent-based autoscaling on custom metrics(カスタムメトリクスに基づくインテントベースのオートスケーリング)」というものがありました。
どうやら、カスタムメトリクスを使ったHPAがGKEネイティブでできるようになった機能みたいです。
外部コンポーネントなしでサクッと試せるらしいので、早速使ってみました。
なお本ブログで利用しているファイルは以下リポジトリにおいているので、ご自由にご利用ください。
カスタムメトリクスでのオートスケーリングについて
従来の方法と課題
まずGKEにおいて、カスタムメトリクスを使ったHPAでのスケーリングは以前から実現可能でした。
主な方法としては以下のようなものがあります。
- Prometheus + Prometheus Adapter
- KEDA(Kubernetes Event-driven Autoscaling)
- custom-metrics-stackdriver-adapter
これらの方法は、
動かすためにコンポーネントを別途クラスターにデプロイして自前で運用しなければならないのが課題でした。
新機能の概要
今回のアップデートで追加された機能は、
GKEがカスタムメトリクスの収集をネイティブにサポートしてくれるようになったという点がメリットかなと思います。
AutoscalingMetricというCRDをデプロイするだけで、直接PodのPrometheusエンドポイントからメトリクスをスクレイピングしてHPAに連携してくれます。
PrometheusもAdapterも不要で、GKEクラスターに追加コンポーネントを入れずに使えます。
なお現時点ではゲージメトリクスのみ対応・クラスタあたり最大20メトリクスといった制約もあるため、
対象とするメトリクス数が多い場合や複雑な要件には、引き続きPrometheusやKEDAの方が適しているケースもあると思います。
前提条件と制限
- GKEバージョン
- GKE 1.35.1-gke.1396000以上(Rapidチャンネル推奨)
- メトリクス形式
- HTTP エンドポイントでアクセス可能
- Prometheus形式のゲージメトリクスのみ対応
- メトリクス数の上限
- クラスタあたり最大20ユニークメトリクス
- メトリクス名の制約
- 英数字、ハイフン、アンダースコアのみ使用可能(最大63文字)
どんなユースケースがありそう?
アップデート資料でも特にAI/MLワークロードへの活用が強調されており、具体的には以下のようなケースに向いてそうです。
- 推論キューのスケーリング
- リクエストキューの深さに応じてPodをスケール
- GPU/TPU利用率ベースのスケーリング
- 強化学習などの学習ジョブに対応
- マルチエージェントワークフロー
- 処理量に応じた動的なスケーリング
- 一般的なキュー処理システム
- ジョブキューの深さに応じたワーカーのスケール
本機能に限った話ではないですが、CPU/メモリ使用率とは異なり、アプリケーションのビジネスロジックに直結したメトリクスでスケーリングできるのが嬉しいポイントですね。
ざっくりアーキテクチャ
機能のアーキテクチャ
まず機能全体の仕組みを整理します。
AutoscalingMetric CRDで「どのPodのどのエンドポイントからどのメトリクスを収集するか」を定義すると、GKEの内部コンポーネントがPodへ直接スクレイプします。
収集したメトリクス値は autoscaling API に push され、HPA がこれを参照してスケーリングの可否を判断します。
また複数レプリカが存在する場合、GKEはPodごとに個別にスクレイプし、HPAはその平均値(AverageValue)を使ってレプリカ数を計算します。
今回の検証のアーキテクチャ
今回の検証では、キューの深さをメトリクスとして公開するシンプルなPythonアプリを使いました。
/enqueueを叩くとキューの深さが増え、HPAがスケールアウトの判断をします。
/dequeueを叩くとキューの深さが減り、HPAがスケールインの判断をします。
デプロイ
Google Cloudリソース作成
まずはGKEクラスターとイメージ格納用のArtifact Registryのリポジトリを作成します。
クラスターの作成
以下の環境変数を設定します。
export PROJECT_ID=$(gcloud config get project)
export REGION="asia-northeast1"
export CLUSTER_NAME="custom-metrics-cluster"
export REPO_NAME="custom-metrics-repo"
次にGKEクラスターを作成します。
AutoscalingMetricにはGKE 1.35.1以上が必要なため、Rapidチャンネルを指定します。
今回は検証用途なので最小構成にしています。
gcloud container clusters create ${CLUSTER_NAME} \
--project=${PROJECT_ID} \
--location=${REGION}-a \
--release-channel=rapid \
--machine-type=e2-medium \
--num-nodes=2 \ #スケーリングを考慮して2ノード
--spot
作成後はkubectlの認証情報を取得します。
gcloud container clusters get-credentials ${CLUSTER_NAME} \
--location=${REGION}-a \
--project=${PROJECT_ID}
今回作成されたクラスターのバージョンはv1.35.2-gke.1485000で、
要件の1.35.1以上を満たしていることが確認できます。
kubectl get node
NAME STATUS ROLES AGE VERSION
gke-custom-metrics-clust-default-pool-653901b9-576d Ready <none> 69s v1.35.2-gke.1485000
gke-custom-metrics-clust-default-pool-653901b9-9wz4 Ready <none> 67s v1.35.2-gke.1485000
リポジトリの作成
続いて、コンテナイメージを格納するArtifact Registryのリポジトリを作成します。
gcloud artifacts repositories create ${REPO_NAME} \
--project=${PROJECT_ID} \
--repository-format=docker \
--location=${REGION}
最後にCloud Buildを使ってアプリのイメージをビルド&プッシュします。
export IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/queue-app:latest"
gcloud builds submit \
--project=${PROJECT_ID} \
--region=${REGION} \
--tag=${IMAGE} \
app/
以下のようにSTATUSがSUCCESSになればOKです。
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
XXX-XXX-XXX-XXX-XXX 2026-05-02T05:41:41+00:00 17S gs://XXX-XXX_XXX/source/XXX.XXX.tgz asia-northeast1-docker.pkg.dev/XXX/custom-metrics-repo/queue-app (+1 more) SUCCESS
Kubernetesリソース作成
ここではAutoscalingMetricとHPAの設定に触れます。
他のリソースについては冒頭のGithubリポジトリにてご確認ください。
AutoscalingMetricの設定
AutoscalingMetricはGKEがどのPodのどのエンドポイントからメトリクスを収集するか、を定義するリソースです。
apiVersion: autoscaling.gke.io/v1beta1
kind: AutoscalingMetric
metadata:
name: queue-depth-metric
namespace: custom-metrics-demo
spec:
metrics:
- pod:
selector:
matchLabels:
app: queue-app # 対象Podのラベルセレクタ
containers:
- endpoint:
port: 8080
path: /metrics # Prometheusエンドポイントのパス
metrics:
- gauge:
name: queue-depth # HPA側で参照する名前
prometheusMetricName: app_queue_depth # Prometheusのメトリクス名
HPAの設定
HPAのメトリクス名にはautoscaling.gke.io|{AutoscalingMetric名}|{gauge名}という命名規則があります。
この点が少しクセがあるので注意が必要です。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: queue-app-hpa
namespace: custom-metrics-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-app
minReplicas: 1
maxReplicas: 5
behavior:
scaleDown:
stabilizationWindowSeconds: 60 # 検証用に短縮(デフォルト300秒)
scaleUp:
stabilizationWindowSeconds: 0 # 即時スケールアウト
metrics:
- type: Pods
pods:
metric:
# autoscaling.gke.io|{AutoscalingMetric名}|{gauge名}
name: autoscaling.gke.io|queue-depth-metric|queue-depth
target:
type: AverageValue
averageValue: "5" # Pod あたりの平均 queue_depth が 5 を超えたらスケールアウト
デプロイ
namespace → app → HPAの順に適用します。
kubectl apply -f manifests/namespace.yaml
kubectl apply -f manifests/deployment.yaml
kubectl apply -f manifests/service.yaml
kubectl apply -f manifests/autoscaling-metric.yaml
kubectl apply -f manifests/hpa.yaml
デプロイ後にAutoscalingMetricの状態を確認します。
kubectl describe autoscalingmetric queue-depth-metric -n custom-metrics-demo
Metric StatusesにHPA側で使用するメトリクス名が表示されていれば、GKEがPodからメトリクスを正常に収集できている状態です。
Status:
Metric Statuses:
Hpa Name: autoscaling.gke.io|queue-depth-metric|queue-depth
Name: queue-depth
HPAの状態も確認します。
kubectl describe hpa queue-app-hpa -n custom-metrics-demo
ValidMetricFoundと表示されていれば、HPAがカスタムメトリクスを正常に取得できています。
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ScaleDownStabilized recent recommendations were higher than current one, applying the highest recent recommendation
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from pods metric autoscaling.gke.io|queue-depth-metric|queue-depth
ScalingLimited False DesiredWithinRange the desired count is within the acceptable range
使ってみた
では実際にキューを操作してスケールアウト/スケールインを確認してみます。
まずポートフォワードでローカルからサービスにアクセスできるようにします。
kubectl port-forward svc/queue-app 8080:8080 -n custom-metrics-demo
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
また別ターミナルからHPAのステータスをウォッチしておきます。
kubectl get hpa queue-app-hpa -n custom-metrics-demo -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
queue-app-hpa Deployment/queue-app 0/5 1 5 1 4m41s
スケールアウトの確認
別ターミナルから/enqueueを15回呼び出して、キューをためます。
for i in $(seq 1 15); do
curl -s -X POST http://localhost:8080/enqueue
echo ""
done
# 現在の値を確認
curl -s http://localhost:8080/metrics
# HELP app_queue_depth Current number of pending items in the queue
# TYPE app_queue_depth gauge
app_queue_depth 15
queue_depthが15になりました。
今回のHPAはaverageValue: 5で設定しているので、ceil(1 * 15 / 5) = 3レプリカへのスケールアウトするはずです。
その後ウォッチしていたHPAのステータスを見ていると、10秒程度でスケールアウトしました。
(stabilizationWindowSecond=0にしているので、想定通り)
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
queue-app-hpa Deployment/queue-app 0/5 1 5 1 4m41s
queue-app-hpa Deployment/queue-app 15/5 1 5 1 5m16s
queue-app-hpa Deployment/queue-app 15/5 1 5 3 5m26s #ここでスケールアウト
queue-app-hpa Deployment/queue-app 5/5 1 5 3 6m20s
Podが3台に増えていることが確認できます。
kubectl get pod -n custom-metrics-demo
NAME READY STATUS RESTARTS AGE
queue-app-777cb4ccc-jf62q 1/1 Running 0 2m47s
queue-app-777cb4ccc-mv8ck 1/1 Running 0 8m3s
queue-app-777cb4ccc-zz49r 1/1 Running 0 2m47s
スケールインの確認
では次に/dequeueを15回呼び出してキューを空にします。
for i in $(seq 1 15); do
curl -s -X POST http://localhost:8080/dequeue
echo ""
done
# 現在の値を確認
curl -s http://localhost:8080/metrics
# HELP app_queue_depth Current number of pending items in the queue
# TYPE app_queue_depth gauge
app_queue_depth 0
その後ウォッチしていたHPAのステータスを見ていると、1分程度でスケールインしました。
(stabilizationWindowSecond=60にしているので、想定通り)
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
queue-app-hpa Deployment/queue-app 0/5 1 5 1 4m41s
queue-app-hpa Deployment/queue-app 15/5 1 5 1 5m16s
queue-app-hpa Deployment/queue-app 15/5 1 5 3 5m26s
queue-app-hpa Deployment/queue-app 5/5 1 5 3 6m20s
queue-app-hpa Deployment/queue-app 0/5 1 5 3 9m6s
queue-app-hpa Deployment/queue-app 0/5 1 5 3 9m56s
queue-app-hpa Deployment/queue-app 0/5 1 5 1 10m #スケールイン
Podも1台に減っていることが確認できます。
kubectl get pod -n custom-metrics-demo
NAME READY STATUS RESTARTS AGE
queue-app-777cb4ccc-zz49r 1/1 Running 0 5m29s
さいごに
以上、GKEのカスタムメトリクスを使ったHPAでのスケーリングが外部コンポーネントなしでできるようになったので試してみました。
従来はPrometheusやCustom Metrics Adapterの構築・運用が必要だったところ、AutoscalingMetric CRDを定義するだけでGKEが直接Podからメトリクスを収集してHPAに連携してくれるのはとてもシンプルで良いと思います。
なお現時点ではゲージ型のみ・クラスタあたり最大20メトリクスといった制約はありますが、シンプルなユースケースであれば追加コンポーネントなしで十分活用できそうです。







