このチュートリアルでは、アイドル時にゼロレプリカに自動スケーリングし、需要の増加に応じてスケールアップするようにワークロードを構成して、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 より前のバージョンにする前に、
minReplicasフィールドを1以上に設定して、ゼロとの間でスケーリングするように構成された HPA マニフェストを更新します。1.37 より前のバージョンではminReplicas: 0設定がサポートされていないため、ワークロードがゼロ レプリカのままになることがあります。 - 水平 Pod 自動スケーラーで、少なくとも 1 つの
External指標またはObject指標(キューの深さなど)を構成する必要があります。ワークロードに Pod がない場合、GKE は CPU 指標またはメモリ(Resource)指標を収集できないため、リソース指標だけではゼロからのスケールアップをトリガーできません。 - AutoscalingMetric、HorizontalPodAutoscaler、ターゲットの Deployment は、同じ Kubernetes Namespace に存在する必要があります。
始める前に
- Google Cloud アカウントにログインします。 Google Cloudを初めて使用する場合は、 アカウントを作成して、実際のシナリオで Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分も差し上げます。
-
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず フェデレーション 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 -
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず フェデレーション 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 トピック、サブスクリプション)を単一の 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}.svc.id.googクラスタと通信を行うように
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}.svc.id.goog/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指標のステータスを確認し、指標 ID を取得します。
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 サブスクリプション内のすべてのメッセージが処理されると、HorizontalPodAutoscaler は需要がゼロであることを評価し、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 条件は、HorizontalPodAutoscaler がワークロードをゼロ レプリカにスケーリングしたかどうかを示します。
ScaledToZero: True(Reason: ScaledToZero): 外部指標の需要がゼロになったため、HPA コントローラがワークロードを0レプリカに正常にスケーリングしたことを示します。HPA はアクティブな状態(ScalingActive: True)を維持し、GKE を継続的にポーリングして、ワークロードの需要が増加したタイミングを検出します。ScaledToZero: False: ワークロードが 1 つ以上のレプリカにスケールアップされたことを示します。
たとえば、kubectl scale --replicas=0 コマンドを使用して Deployment を手動でゼロレプリカにスケーリングすると、HPA は自動スケーリング(ScalingActive:
False)を一時停止して、競合する変更を防ぎます。自動スケーリングを再開するには、Deployment を 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 を使用してゼロとの間でスケーリングを行う際にスケーリングの問題を診断する方法を学習する。