水平 Pod 自動スケーリングの構成

このページでは、水平 Pod 自動スケーリングを使用して、さまざまなタイプの指標で Deployment を自動スケーリングする方法について説明します。同じガイドラインを使用して、スケーラブルな Deployment オブジェクトの HorizontalPodAutoscaler を構成できます。

始める前に

作業を始める前に、次のことを確認してください。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Google Kubernetes Engine API の有効化
  • Google Cloud CLI がインストールされていることを確認します。
  • 次のいずれかの方法で、プロジェクトにデフォルトの Google Cloud CLI 設定をセットアップします。
    • プロジェクトのデフォルトの設定全般を確認する場合は、gcloud init を使用します。
    • gcloud config を使用して、プロジェクト ID、ゾーン、リージョンを個別に設定します。

    gcloud init

    1. gcloud init を実行して、次の操作を行います。

      gcloud init

      リモート サーバーで SSH を使用している場合は、--console-only フラグを指定して、コマンドがブラウザを起動しないようにします。

      gcloud init --console-only
    2. Google Cloud アカウントを使用できるように、gcloud CLI の承認手順を行います。
    3. 新しい構成を作成するか、既存の構成を選択します。
    4. Google Cloud プロジェクトを選択します。
    5. デフォルトの Compute Engine ゾーンを選択します。
    6. デフォルトの Compute Engine リージョンを選択します。

    gcloud config

    1. デフォルトのプロジェクト ID を設定します。
      gcloud config set project PROJECT_ID
    2. デフォルトの Compute Engine リージョン(例: us-central1)を設定します。
      gcloud config set compute/region COMPUTE_REGION
    3. デフォルトの Compute Engine ゾーン(例: us-central1-c)を設定します。
      gcloud config set compute/zone COMPUTE_ZONE
    4. gcloud を最新バージョンに更新します。
      gcloud components update

    デフォルトの場所を設定することで、gcloud CLI のエラー(One of [--zone, --region] must be supplied: Please specify location など)を防止できます。

HorizontalPodAutoscaler オブジェクト用の API バージョン

Google Cloud コンソールを使用する場合、HorizontalPodAutoscaler オブジェクトは、autoscaling/v2beta2 API を使用して作成されます。

kubectl を使用して HorizontalPodAutoscaler を作成するか、HorizontalPodAutoscaler の情報を表示する際は、autoscaling/v1 API または autoscaling/v2beta2 API を指定できます。

  • apiVersion: autoscaling/v1 はデフォルトであり、CPU 使用率のみに基づく自動スケーリングを可能にします。他の指標に基づいて自動スケーリングするには、apiVersion: autoscaling/v2beta2 の使用をおすすめします。Deployment の構成の例では apiVersion: autoscaling/v1 を使用しています。

  • 新しい HorizontalPodAutoscaler オブジェクトを作成するには、apiVersion: autoscaling/v2beta2 の使用をおすすめします。これを使用すると、カスタム指標や外部指標を含む複数の指標に基づく自動スケーリングが可能になります。このトピックのその他の例では、apiVersion: autoscaling/v2beta2 を使用しています。

サポートされている API バージョンを確認するには、kubectl api-versions コマンドを使用します。

apiVersion: autoscaling/v2beta2 を使用する HorizontalPodAutoscaler の詳細を表示するときに、どの API を使用するかを指定できます。

サンプル Deployment の作成

HorizontalPodAutoscaler を作成するには、その前に、モニタリング対象のワークロードを作成する必要があります。このトピックの例では、次の nginx Deployment にいくつかの異なる HorizontalPodAutoscaler 構成を適用します。それぞれの例で、リソース使用率に基づく HorizontalPodAutoscaler、カスタム指標または外部指標に基づく HorizontalPodAutoscaler、複数の指標に基づく HorizontalPodAutoscaler を紹介します。

以下の行を nginx.yaml という名前のファイルに保存します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
        resources:
          # You must specify requests for CPU to autoscale
          # based on CPU utilization
          requests:
            cpu: "250m"

このマニフェストは CPU リクエストの値を指定しています。リソース使用量のパーセンテージに基づいて自動スケーリングを行うには、そのリソースに対するリクエストを指定する必要があります。リクエストを指定しない場合は、リソース使用量の絶対値(CPU 使用量を表すミリ CPU など)のみに基づいて自動スケーリングを実行できます。

Deployment を作成するには、次のようにして nginx.yaml マニフェストを適用します。

kubectl apply -f nginx.yaml

Deployment の spec.replicas を 3 に設定しているので、3 つの Pod がデプロイされます。これを確認するには、kubectl get deployment nginx コマンドを実行します。

このトピックの例では、それぞれ異なる HorizontalPodAutoscaler をサンプル nginx Deployment に適用します。

リソース使用率に基づく自動スケーリング

この例では、CPU 使用率が 50% を超えたときに nginx Deployment を自動スケーリングする HorizontalPodAutoscaler オブジェクトを作成して、レプリカが常に最低 1 個、最大で 10 個存在するようにします。

CPU をターゲットとする HorizontalPodAutoscaler を作成するには、Cloud コンソール、kubectl apply コマンド、または kubectl autoscale コマンド(平均 CPU の場合のみ)を使用できます。

Console

  1. Cloud コンソールの [ワークロード] ページに移動します。

    [ワークロード] に移動

  2. nginx Deployment の名前をクリックします。

  3. [アクション] > [自動スケーリング] をクリックします。

  4. 次の値を指定します。

    • レプリカの最小数: 1
    • レプリカの最大数: 10
    • 自動スケーリング指標: CPU
    • ターゲット: 50
    • 単位: %
  5. [完了] をクリックします。

  6. [自動スケーリング] をクリックします。

kubectl apply

次の YAML マニフェストを nginx-hpa.yaml という名前のファイルとして保存します。

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

HPA を作成するには、次のコマンドを使用してマニフェストを適用します。

kubectl apply -f nginx-hpa.yaml

kubectl autoscale

平均 CPU 使用率のみをターゲットとする HorizontalPodAutoscaler オブジェクトを作成するには、kubectl autoscale コマンドを使用できます。

kubectl autoscale deployment nginx --cpu-percent=50 --min=1 --max=10

クラスタ内の HorizontalPodAutoscaler のリストを取得するには、次のコマンドを使用します。

kubectl get hpa

出力は次のようになります。

NAME    REFERENCE          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx   Deployment/nginx   0%/50%    1         10        3          61s

HorizontalPodAutoscaler に関する詳細を取得するには、Cloud コンソールまたは kubectl コマンドを使用できます。

Console

  1. Cloud コンソールの [ワークロード] ページに移動します。

    [ワークロード] に移動

  2. nginx Deployment の名前をクリックします。

  3. [オートスケーラー] セクションに HorizontalPodAutoscaler の構成が表示されます。

  4. 自動スケーリング イベントの詳細を [イベント] タブで確認できます。

kubectl get

HorizontalPodAutoscaler に関する詳細を取得するには、-o yaml フラグを指定した kubectl get hpa を使用します。status フィールドに、現在のレプリカ数と最近の自動スケーリング イベントに関する情報が表示されます。

kubectl get hpa nginx -o yaml

出力は次のようになります。

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  annotations:
    autoscaling.alpha.kubernetes.io/conditions: '[{"type":"AbleToScale","status":"True","lastTransitionTime":"2019-10-30T19:42:59Z","reason":"ScaleDownStabilized","message":"recent
      recommendations were higher than current one, applying the highest recent recommendation"},{"type":"ScalingActive","status":"True","lastTransitionTime":"2019-10-30T19:42:59Z","reason":"ValidMetricFound","message":"the
      HPA was able to successfully calculate a replica count from cpu resource utilization
      (percentage of request)"},{"type":"ScalingLimited","status":"False","lastTransitionTime":"2019-10-30T19:42:59Z","reason":"DesiredWithinRange","message":"the
      desired count is within the acceptable range"}]'
    autoscaling.alpha.kubernetes.io/current-metrics: '[{"type":"Resource","resource":{"name":"cpu","currentAverageUtilization":0,"currentAverageValue":"0"}}]'
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"autoscaling/v1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"maxReplicas":10,"minReplicas":1,"scaleTargetRef":{"apiVersion":"apps/v1","kind":"Deployment","name":"nginx"},"targetCPUUtilizationPercentage":50}}
  creationTimestamp: "2019-10-30T19:42:43Z"
  name: nginx
  namespace: default
  resourceVersion: "220050"
  selfLink: /apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/nginx
  uid: 70d1067d-fb4d-11e9-8b2a-42010a8e013f
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  targetCPUUtilizationPercentage: 50
status:
  currentCPUUtilizationPercentage: 0
  currentReplicas: 3
  desiredReplicas: 3

このトピックの残りの例を実行する前に、次のようにして HPA を削除してください。

kubectl delete hpa nginx

HorizontalPodAutoscaler を削除しても、Deployment のレプリカ数は変わりません。Deployment が HorizontalPodAutoscaler 適用前の状態に自動的に戻ることはありません。

HorizontalPodAutoscaler を削除するの詳細をご確認ください。

ロードバランサのトラフィックに基づく自動スケーリング

トラフィック ベースの自動スケーリングは GKE の機能であり、ロードバランサによるトラフィック使用率のシグナルを Pod の自動スケーリングに統合します。

トラフィックは CPU とメモリを補完する負荷の主要な指標であるため、トラフィックを自動スケーリング シグナルとして使用することが有効な場合があります。GKE との統合が組み込まれているため、設定が容易であり、トラフィックの急増に対して自動スケーリングで迅速に対応し需要を満たすことができます。

トラフィック ベースの自動スケーリングは、ゲートウェイ コントローラと、そのグローバル トラフィック管理機能によって有効化されます。詳細については、トラフィック ベースの自動スケーリングをご覧ください。

ロードバランサのトラフィックに基づく自動スケーリングは、ゲートウェイのワークロードでのみ使用できます。

要件

トラフィック ベースの自動スケーリングには次の要件があります。

  • GKE バージョン 1.22 以降でサポートされています。
  • GKE Gateway コントローラ(gke-l7-rilbgke-l7-gxlb)を使用してデプロイされたロードバランサを通過するトラフィックに対してサポートされます。
  • 複数クラスタの GatewayClass(gke-l7-rilb-mcgke-l7-gxlb-mc)ではサポートされていません。
  • ClusterIP または LoadBalancer タイプの Service を使用したトラフィックではサポートされていません。
  • Service の容量は、Service で構成する必要があります。

トラフィック ベースの自動スケーリングをデプロイする

次の演習では、HorizontalPodAutoscaler を使用し、受信したトラフィックに基づいて store-autoscale Deployment を自動スケーリングします。Gateway は、インターネットから Pod に向かう上り(内向き)トラフィックを受け入れます。オートスケーラーは、Gateway からのトラフィック信号を、store-autoscale Service リソースで構成されている Pod ごとのトラフィック容量と比較します。Gateway へのトラフィックを生成することで、デプロイされる Pod の数を変化させます。

次の図では、トラフィック ベースの自動スケーリングの仕組みを示します。

トラフィック ベースの自動スケーリング

トラフィック ベースの自動スケーリングをデプロイするには、次の手順を行います。

  1. クラスタに Gateway API CRD をインストールします。この手順は、クラスタで GKE Gateway Controller を使用するために必要です。

  2. GatewayClasses がインストールされていることを確認します。

    kubectl get gatewayclass
    

    この出力により、GKE GatewayClass リソースがクラスタで使用できる状態であることを確認できます。

    NAME          CONTROLLER
    gke-l7-rilb   networking.gke.io/gateway
    gke-l7-gxlb   networking.gke.io/gateway
    
  3. クラスタにサンプル アプリケーションと Gateway ロードバランサをデプロイします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-autoscale.yaml
    

    このサンプル アプリケーションでは、次のように作成されます。

    • 2 つのレプリカを持つ Deployment。
    • max-rate-per-endpoint10 に設定された Service の容量。
    • インターネット上のアプリケーションにアクセスするための外部ゲートウェイ。ゲートウェイ ロードバランサを使用する方法の詳細については、ゲートウェイのデプロイをご覧ください。
    • すべてのトラフィックを照合し、store-autoscale Service に送信する HTTPRoute。

    Service の容量は、自動スケーリング イベントをトリガーする Pod ごとのトラフィック量を決定するため、トラフィック ベースの自動スケーリングを使用する場合は重要な要素です。Service の容量は、Service アノテーション networking.gke.io/max-rate-per-endpoint を使用して構成されます。この Service Annotation では、Service が Pod ごとに 1 秒あたりに受信するリクエスト数で最大トラフィックが定義されます。Service の容量は、アプリケーションによって異なります。詳細については、サービスの容量の決定をご覧ください。

  4. 次のマニフェストを hpa.yaml として保存します。

    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    metadata:
      name: store-autoscale
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: store-autoscale
      minReplicas: 1
      maxReplicas: 10
      metrics:
      - type: Object
        object:
          describedObject:
            kind: Service
            name: store-autoscale
          metric:
            name: "autoscaling.googleapis.com|gclb-capacity-utilization"
          target:
            averageValue: 70
            type: AverageValue
    

    このマニフェストでは、次のプロパティを持つ HorizontalPodAutoscaler が記述されています。

    • minReplicasmaxReplicas: この Deployment のレプリカの最小数と最大数を設定します。この構成では、Pod の数が 1~10 レプリカにスケールできます。
    • describedObject.name: store-autoscale: トラフィック容量を定義する store-autoscale Service への参照。
    • scaleTargetRef.name: store-autoscale: HorizontalPodAutoscaler によってスケールされるリソースを定義する store-autoscale Deployment への参照。
    • averageValue: 70: 容量使用率の目標平均値。これにより、新しい Pod の作成中に実行中の Pod が過剰なトラフィックを処理できるように HorizontalPodAutoscaler に増加余地が追加されます。

Horizontal Pod Autoscaler では、次のようなトラフィックの動作が発生します。

  • Pod の数は、エンドポイントあたりの最大レートである 70% になるように、1~10 個のレプリカで調整されます。これにより、max-rate-per-endpoint=10 の場合、Pod あたり 7 RPS になります。
  • Pod あたりの RPS が 7 を超える場合、Pod が最大 10 個のレプリカに達するまで、または Pod あたりの平均トラフィック数が 7 RPS になるまで、Pod がスケールアップされます。
  • トラフィックが減少すると、Pod は HorizontalPodAutoscaler アルゴリズムを使用して合理的な割合にスケールダウンします。

また、トラフィック生成ツールをデプロイして、トラフィック ベースの自動スケーリングの動作を検証することもできます。

30 RPS の場合、Deployment は 5 つのレプリカにスケールされるため、理論上各レプリカは 6 RPS のトラフィックを受信します。これは Pod あたり 60% の使用率になります。これはターゲット使用率の 70% を下回るため、Pod は適切にスケールされます。トラフィックの変動に応じて、自動スケーリングされるレプリカの数も変わる可能性があります。レプリカ数の計算方法の詳細については、自動スケーリングの動作をご覧ください。

カスタム指標または外部指標に基づく自動スケーリング

手順を詳しく説明したチュートリアルに従って、カスタム指標外部指標に基づく HorizontalPodAutoscaler を作成できます。

複数の指標に基づく自動スケーリング

この例では、CPU 使用率とカスタム指標 packets_per_second に基づいて自動スケーリングを行う HorizontalPodAutoscaler を作成します。

前の例で作成した nginx という名前の HorizontalPodAutoscaler がまだ残っている場合は、次の例を実行する前にそれを削除してください。

この例では apiVersion: autoscaling/v2beta2 が必要です。使用可能な API の詳細については、HorizontalPodAutoscaler オブジェクト用の API バージョンをご覧ください。

この YAML マニフェストを nginx-multiple.yaml という名前のファイルとして保存します。

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Resource
    resource:
      name: memory
      target:
        type: AverageValue
        averageValue: 100Mi
  # Uncomment these lines if you create the custom packets_per_second metric and
  # configure your app to export the metric.
  # - type: Pods
  #   pods:
  #     metric:
  #       name: packets_per_second
  #     target:
  #       type: AverageValue
  #       averageValue: 100

次のようにして YAML マニフェストを適用します。

kubectl apply -f nginx-multiple.yaml

HorizontalPodAutoscaler が作成されると、HorizontalPodAutoscaler は nginx Deployment の平均 CPU 使用率、平均メモリ使用率、およびカスタム指標 packets_per_second(コメント化解除した場合)をモニタリングします。より大規模な自動スケーリング イベントを生じさせる値を持つ指標に基づいて、HorizontalPodAutoscaler は Deployment を自動スケーリングします。

HorizontalPodAutoscaler に関する詳細を表示する

HorizontalPodAutoscaler の構成と統計情報を表示するには、次のコマンドを使用します。

kubectl describe hpa HPA_NAME

HPA_NAME は実際の HorizontalPodAutoscaler オブジェクトの名前に置き換えます。

apiVersion: autoscaling/v2beta2 を使用する、複数の指標に基づく HorizontalPodAutoscaler の場合、kubectl describe hpa コマンドによって CPU の指標のみが表示されます。すべての指標を表示するには、代わりに次のコマンドを使用します。

kubectl describe hpa.v2beta2.autoscaling HPA_NAME

HPA_NAME は実際の HorizontalPodAutoscaler オブジェクトの名前に置き換えます。

各 HorizontalPodAutoscaler の現在のステータスが Conditions フィールドに表示され、自動スケーリング イベントが Events フィールドにリストされます。

出力は次のようになります。

Name:                                                  nginx
Namespace:                                             default
Labels:                                                <none>
Annotations:                                           kubectl.kubernetes.io/last-applied-configuration:
                                                         {"apiVersion":"autoscaling/v2beta2","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"s...
CreationTimestamp:                                     Tue, 05 May 2020 20:07:11 +0000
Reference:                                             Deployment/nginx
Metrics:                                               ( current / target )
  resource memory on pods:                             2220032 / 100Mi
  resource cpu on pods  (as a percentage of request):  0% (0) / 50%
Min replicas:                                          1
Max replicas:                                          10
Deployment pods:                                       1 current / 1 desired
Conditions:
  Type            Status  Reason              Message
  ----            ------  ------              -------
  AbleToScale     True    ReadyForNewScale    recommended size matches current size
  ScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from memory resource
  ScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable range
Events:                                                <none>

HorizontalPodAutoscaler を削除する

HorizontalPodAutoscaler は、Cloud コンソールまたは kubectl delete コマンドを使用して削除できます。

Console

次の手順に沿って、nginx HorizontalPodAutoscaler を削除します。

  1. Cloud コンソールの [ワークロード] ページに移動します。

    [ワークロード] に移動

  2. nginx Deployment の名前をクリックします。

  3. [アクション] > [自動スケーリング] をクリックします。

  4. [削除] をクリックします。

kubectl delete

nginx HorizontalPodAutoscaler を削除するには、次のコマンドを使用します。

kubectl delete hpa nginx

HorizontalPodAutoscaler を削除しても、Deployment(または他のデプロイメント オブジェクト)は既存のスケールのままに維持されます。Deployment の元のマニフェストのレプリカ数には戻りません。手動で Deployment を再び 3 つの Pod にスケーリングするには、kubectl scale コマンドを使用できます。

kubectl scale deployment nginx --replicas=3

クリーンアップ

  1. HorizontalPodAutoscaler をまだ削除していない場合は、削除します。

    kubectl delete hpa nginx
    
  2. nginx Deployment を削除します。

    kubectl delete deployment nginx
    
  3. 必要であれば、クラスタを削除します。

トラブルシューティング

HorizontalPodAutoscaler を設定すると、次のような警告メッセージが表示されることがあります。

unable to fetch pod metrics for pod

指標サーバーの起動時にこのメッセージが表示されるのは、正常な状態です。ただし、メッセージが継続して表示され、ワークロードの Pod がスケーリングされない場合は、ワークロード内のコンテナごとにリソース リクエストを指定していることを確認してください。水平 Pod 自動スケーリングでリソース使用率をターゲットとして使用するには、ワークロード内の各 Pod で実行されるコンテナごとに、そのリソースのリクエスト数を構成する必要があります。そうでないと、HorizontalPodAutoscaler が必要な計算を実行できないため、その指標に関連する処理を行いません。

次のステップ