このチュートリアルでは、ワークロードがアイドル状態のときに自動的にゼロ レプリカにスケーリングし、需要の増加に応じてスケールアップするように構成して、Google Kubernetes Engine(GKE)でリソース使用率を最適化する方法について説明します。このアプローチでは、水平 Pod オートスケーラー(HPA)を GKE のマネージド自動スケーリング インフラストラクチャと統合して、外部指標に基づいてスケーリングを管理します。
minReplicas フィールドの値を 0 に設定し、HPA マニフェスト内で External タイプまたは Object タイプの指標を定義して、ゼロにスケーリングするようにデプロイを構成します。GKE は、AutoscalingMetric カスタム リソースを介してこれらの指標をモニタリングします。これにより、アプリケーションのリソース管理を効率的に行うことができます。
この構成では、KEDA などのサードパーティの指標アダプタを使用して GKE ワークロードをスケーリングする必要はありません。このソリューションは、指標の取り込みとスケーリングの推奨事項を GKE コントロール プレーンで直接管理し、クラスタ管理のオーバーヘッドを削減します。
このチュートリアルでは、Pub/Sub キューからメッセージを処理する非同期ワーカー アプリケーションの例をデプロイします。AutoscalingMetric カスタム リソースを使用して、キューの深さ(pubsub.googleapis.com:num_undelivered_messages)をモニタリングするように水平 Pod オートスケーラーを構成します。
- サブスクリプションにメッセージが到着した場合: GKE は、キューを処理するためにワーカー Pod をスケールアップします。
- キューが空の場合: GKE は、ワーカーの Deployment を自動的にゼロ レプリカにスケールダウンします。
このチュートリアルは、ワークロードがアイドル状態のときにゼロにスケーリングして GKE のリソース使用率を最適化するアプリケーション デベロッパー、プラットフォーム管理者とオペレーター、DevOps を対象としています。
考慮事項
ワークロードをゼロにスケーリングするように構成する前に、次の考慮事項を確認してください。
- HPA を使用してワークロードをゼロにスケーリングするには、新規クラスタとアップグレードされた既存のクラスタの両方で、GKE クラスタのコントロール プレーンとノードがバージョン 1.37 以降を実行している必要があります。既存のクラスタを使用する場合は、そのバージョンを確認するか、クラスタまたはそのノードをバージョン 1.37 以降にアップグレードします。
- HPA マニフェストは、
minReplicas: 0設定と外部指標をサポートするためにapiVersion: autoscaling/v2構成を使用する必要があります。 - ノードプールをダウングレードして 1.37 より前のバージョンにする前に、ゼロとの間でスケーリングするように構成された HPA マニフェストを更新し、
minReplicasフィールドを1以上に設定します。1.37 より前のバージョンではminReplicas: 0設定がサポートされていないため、ワークロードがゼロ レプリカのままになることがあります。 - 水平 Pod 自動スケーラーで、
External指標またはObject指標(キューの深さなど)を 1 つ以上構成する必要があります。ワークロードに Pod がない場合、GKE は CPU またはメモリ(Resource)指標を収集できません。そのため、リソース指標だけではゼロからのスケールアップをトリガーできません。 - AutoscalingMetric、HorizontalPodAutoscaler、ターゲット Deployment は同じ Kubernetes Namespace に存在する必要があります。
始める前に
-
Google Cloud CLI をインストールします。
-
フェデレーション ID(連携 ID)を使用するように gcloud CLI を構成します。
詳細については、連携 ID を使用して gcloud CLI にログインするをご覧ください。
-
gcloud CLI を初期化するには、次のコマンドを実行します。
gcloud init -
Google Cloud プロジェクトを作成または選択します。
プロジェクトの選択または作成に必要なロール
- プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
-
プロジェクトを作成する: プロジェクトを作成するには、
resourcemanager.projects.create権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。
-
Google Cloud プロジェクトを作成します。
gcloud projects create PROJECT_ID
PROJECT_IDは、作成する Google Cloud プロジェクトの名前に置き換えます。 -
作成した Google Cloud プロジェクトを選択します。
gcloud config set project PROJECT_ID
PROJECT_IDは、 Google Cloud プロジェクトの名前に置き換えます。
GKE API と Pub/Sub API を有効にします。
API を有効にするために必要なロール
API を有効にするには、
serviceusage.services.enable権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を介してこの権限がすでに付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を介してこの権限を取得できます。ロールを付与する方法をご覧ください。gcloud services enable container.googleapis.com
pubsub.googleapis.com
必要なロール
このチュートリアルを完了するために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。
- GKE クラスタ管理者 (
roles/container.clusterAdmin) - Pub/Sub 管理者 (
roles/pubsub.admin) - プロジェクト IAM 管理者 (
roles/resourcemanager.projectIamAdmin) - サービス アカウント ユーザー(
roles/iam.serviceAccountUser)
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
環境の設定
わかりやすくするため、このチュートリアルのコマンドでは、すべてのリソース(GKE クラスタ、Pub/Sub トピック、サブスクリプション)を 1 つの Google Cloud プロジェクト(PROJECT_ID)内に作成します。
環境の設定手順は次のとおりです。
環境変数を設定します。
export PROJECT_ID=PROJECT_ID export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)') export LOCATION=LOCATION次のように置き換えます。
PROJECT_ID: Google Cloudのプロジェクト ID。LOCATION: GKE クラスタを作成するリージョンまたはゾーン(us-central1など)。Autopilot クラスタの場合は、リージョンを指定します。
Workload Identity Federation for GKE を有効にして、バージョン 1.37 以降を実行する GKE クラスタを作成します。フルマネージドの Kubernetes エクスペリエンスを実現し、ワークロードがゼロにスケーリングされたときにコスト削減を最大化するには、Autopilot クラスタを使用することをおすすめします。ワークロードに最適な運用モードを選択するには、GKE の運用モードを選択するをご覧ください。
Autopilot
Autopilot クラスタを作成します。
gcloud container clusters create-auto scale-to-zero \ --project=${PROJECT_ID} \ --location=${LOCATION}Workload Identity Federation for GKE は、Autopilot クラスタではデフォルトで有効になっています。
標準
Workload Identity Federation for GKE を有効にして Standard クラスタを作成します。
gcloud container clusters create scale-to-zero \ --project=${PROJECT_ID} \ --location=${LOCATION} \ --workload-pool=${PROJECT_ID}.クラスタと通信を行うように
kubectlを構成します。gcloud container clusters get-credentials scale-to-zero \ --project=${PROJECT_ID} \ --location=${LOCATION}
Pub/Sub リソースを作成する
このチュートリアルでは、外部指標ソースの例として Pub/Sub キューの深さを使用します。
Pub/Sub トピックとサブスクリプションを作成する手順は次のとおりです。
Pub/Sub トピックを作成します。
gcloud pubsub topics create my-worker-topic \ --project=${PROJECT_ID}トピックに関連付けられたサブスクリプションを作成します。
gcloud pubsub subscriptions create my-worker-subscription \ --topic=my-worker-topic \ --project=${PROJECT_ID}
Workload Identity Federation for GKE を設定する
ワーカー アプリケーションが Google Cloud API で認証を行い、Pub/Sub からメッセージを消費できるように、Workload Identity Federation for GKE を構成します。
GKE は、同じプロジェクト内の AutoscalingMetric リソースの Cloud Monitoring による認証を自動的に処理します。自動スケーリングの指標の定義の詳細については、Cloud Monitoring からカスタム指標または外部指標を取得するをご覧ください。
ワーカー ワークロード用に Workload Identity Federation for GKE を構成する手順は次のとおりです。
defaultNamespace にワーカー アプリケーション用の Kubernetes サービス アカウントを作成します。kubectl create serviceaccount async-worker-sa \ --namespace defaultアプリケーションが Pub/Sub サブスクリプションからメッセージを受信できるように、Kubernetes サービス アカウントに
roles/pubsub.subscriberロールを付与します。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}./subject/ns/default/sa/async-worker-sa
詳細については、Workload Identity Federation for GKE を使用するようにアプリケーションを構成するをご覧ください。
サンプル Deployment の作成
HPA オブジェクトを作成する前に、モニタリング対象のワークロードを作成する必要があります。
Deployment のサンプルを作成する手順は次のとおりです。
次のマニフェストを
async-worker.yamlとして保存します。apiVersion: apps/v1 kind: Deployment metadata: name: async-worker namespace: default spec: replicas: 3 selector: matchLabels: app: async-worker template: metadata: labels: app: async-worker spec: containers: - name: async-worker image: nginx:latest ports: - containerPort: 80 resources: limits: memory: 100Mi requests: cpu: 50m memory: 100Miasync-worker.yamlDeployment を適用します。kubectl apply -f async-worker.yaml
ゼロにスケーリングするワークロードを構成する
このセクションでは、Pub/Sub キューが空になったときにゼロにスケールダウンし、新しいメッセージが到着したときにスケールアップするように async-worker Deployment を構成します。
AutoscalingMetric リソースを作成する
GKE でモニタリングする外部シグナルを定義するには、AutoscalingMetric カスタム リソースを作成します。次のマニフェストの例では、指標は my-worker-subscription サブスクリプションの未配信の Pub/Sub メッセージの数を Cloud Monitoring にクエリします。
AutoscalingMetric リソースを作成する手順は次のとおりです。
次のマニフェストを
pubsub-metric.yamlファイルとして保存します。apiVersion: autoscaling.gke.io/v1beta1 kind: AutoscalingMetric metadata: name: pubsub-queue-depth namespace: default spec: metrics: - promql: name: pubsub-undelivered query: > { "pubsub.googleapis.com/subscription/num_undelivered_messages", subscription_id="my-worker-subscription" }pubsub-metric.yamlマニフェストを適用します。kubectl apply -f pubsub-metric.yaml指標のステータスを確認し、指標識別子を取得します。
kubectl describe autoscalingmetric pubsub-queue-depth出力の
Statusセクションで、エラーがリストされていないことを確認し、autoscaling.gke.io|CUSTOM_RESOURCE_NAME|METRIC_NAME形式のHpa Name値をメモします。この外部指標識別子は、次のセクションで HorizontalPodAutoscaler オブジェクトを作成するときに参照します。Statusセクションで構成エラーが報告された場合や、指標が想定どおりに取得されない場合は、自動スケーリング用に取得された指標のトラブルシューティングをご覧ください。
水平 Pod オートスケーラーを構成する
自動スケーリングの動作を構成するには、Deployment をターゲットとする HorizontalPodAutoscaler リソースを作成します。
水平 Pod オートスケーラーを構成する手順は次のとおりです。
次のマニフェストを
worker-hpa.yamlファイルとして保存します。apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: async-worker-hpa namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: async-worker minReplicas: 0 maxReplicas: 20 metrics: - type: External external: metric: name: autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered target: type: AverageValue averageValue: "10"このマニフェストでは、次のキーフィールドを構成します。
minReplicas: 0: コントローラが Deployment を0レプリカにスケールダウンできるようにすることで、需要がゼロになったときにゼロへのスケーリングを有効にします。type: External: 外部指標ソースを構成します。これにより、ワークロードに Pod がない場合に HPA がスケールアップをトリガーできます。name: autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered:autoscaling.gke.io|CUSTOM_RESOURCE_NAME|METRIC_NAME識別子形式を使用して、HPA を前のステップで作成した AutoscalingMetric リソースに直接マッピングします。
worker-hpa.yamlマニフェストを適用します。kubectl apply -f worker-hpa.yaml
ゼロスケールの動作と条件を確認する
Pub/Sub サブスクリプション内のすべてのメッセージが処理されると、水平 Pod オートスケーラーは需要がゼロであることを評価し、Deployment を 0 レプリカにスケールダウンします。
水平 Pod オートスケーラーがゼロ状態をアクチュエートしたことを確認するには、次のコマンドを実行して async-worker-hpa リソースのステータス条件を調べます。
kubectl describe hpa async-worker-hpa
出力は次のようになります。
Name: async-worker-hpa
Namespace: default
Reference: Deployment/async-worker
Metrics: ( current / target )
"autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered" (external metric): 0 / 10
Min replicas: 0
Max replicas: 20
Deployment pods: 0 current / 0 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from external metric
ScaledToZero True ScaledToZero the HPA has scaled the target resource to 0 replicas due to zero metric demand
ScaledToZero 条件について
ScaledToZero 条件は、水平方向 Pod オートスケーラーがワークロードをゼロ レプリカにスケーリングしたかどうかを示します。
ScaledToZero: True(Reason: ScaledToZero): 外部指標の需要がゼロになったため、HPA コントローラがワークロードを0レプリカに正常にスケーリングしたことを示します。HPA はアクティブな状態(ScalingActive: True)を維持し、GKE を継続的にポーリングして、ワークロードの需要が増加したタイミングを検出します。ScaledToZero: False: ワークロードが 1 つ以上のレプリカにスケールアップされたことを示します。
たとえば、kubectl scale --replicas=0 コマンドを使用して Deployment をゼロ レプリカに手動でスケーリングすると、HPA は競合する変更を防ぐために自動スケーリング(ScalingActive:
False)を一時停止します。自動スケーリングを再開するには、デプロイを 1 つ以上のレプリカ(kubectl scale deployment
async-worker --replicas=1)にスケールバックします。
ワークロードがゼロにスケールダウンできない場合や、ゼロからスケールアップできない場合のトラブルシューティング シナリオについては、HPA を使用して GKE ワークロードをゼロにスケールダウンするトラブルシューティングをご覧ください。HorizontalPodAutoscaler が外部指標の欠落または無効を報告する場合は、自動スケーリング用に取得された指標のトラブルシューティングをご覧ください。
クリーンアップ
このチュートリアルで使用したリソースについて Google Cloud アカウントに課金されないようにするには、次の操作を行います。
GKE クラスタを削除します。
gcloud container clusters delete scale-to-zero \ --project=${PROJECT_ID} \ --location=${LOCATION}Pub/Sub サブスクリプションとトピックを削除します。
gcloud pubsub subscriptions delete my-worker-subscription \ --project=${PROJECT_ID} gcloud pubsub topics delete my-worker-topic \ --project=${PROJECT_ID}
次のステップ
- GKE 容量バッファを使用してコールド スタート レイテンシを軽減する方法について説明します。
- HPA を使用してゼロとの間でスケーリングを行う際にスケーリングの問題を診断する方法を学習する。