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


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

始める前に

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

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。

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

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

kubectl を使用して HorizontalPodAutoscaler を作成したり情報を表示したりする場合、autoscaling/v1 API または autoscaling/v2 API を指定できます。

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

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

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

apiVersion: autoscaling/v2 を使用する 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 を作成するには、Google Cloud コンソール、kubectl apply コマンド、または kubectl autoscale コマンド(平均 CPU の場合のみ)を使用できます。

コンソール

  1. Google 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 に関する詳細を取得するには、Google Cloud コンソールまたは kubectl コマンドを使用できます。

コンソール

  1. Google 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 を削除するの詳細をご確認ください。

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

トラフィック ベースの自動スケーリングは、ロードバランサから得られるトラフィック使用率のシグナルを使って Pod の自動スケーリングを行う GKE の機能です。

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

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

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

要件

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

  • GKE バージョン 1.24 以降でサポートされる。
  • GKE クラスタで Gateway API が有効になっている。
  • Gateway API と、gke-l7-global-external-managedgke-l7-regional-external-managedgke-l7-rilb、または gke-l7-gxlb の GatewayClass を使用してデプロイされたロードバランサを通過するトラフィックでサポートされる。

制限事項

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

  • マルチクラスタの GatewayClass(gke-l7-global-external-managed-mcgke-l7-regional-external-managed-mcgke-l7-rilb-mcgke-l7-gxlb-mc)ではサポートされていません。
  • ClusterIP または LoadBalancer タイプの Service を使用したトラフィックではサポートされていません。

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

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

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

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

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

  1. Standard クラスタの場合は、GatewayClasses がクラスタにインストールされていることを確認します。Autopilot クラスタの場合、デフォルトで GatewayClasses がインストールされます。

    kubectl get gatewayclass
    

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

    NAME                               CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed     networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed   networking.gke.io/gateway   True       16h
    gke-l7-gxlb                        networking.gke.io/gateway   True       16h
    gke-l7-rilb                        networking.gke.io/gateway   True       16h
    

    この出力が表示されない場合は、GKE クラスタで Gateway API を有効にします

  2. クラスタにサンプル アプリケーションと 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 の容量。この機能がプレビュー版の期間中、Service でアノテーションを使用します。この機能が一般提供されると、アノテーションはサービス ポリシーに置き換えられます。Gateway の機能の詳細については、GatewayClass の機能をご覧ください。
    • インターネット上のアプリケーションにアクセスするための外部ゲートウェイ。ゲートウェイ ロードバランサを使用する方法の詳細については、ゲートウェイのデプロイをご覧ください。
    • すべてのトラフィックを照合し、store-autoscale Service に送信する HTTPRoute。

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

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

    apiVersion: autoscaling/v2
    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 では、各レプリカが 6 RPS のトラフィックを受け取るよう、Deployment は 5 つのレプリカにスケーリングされます。これは Pod あたり 60% の使用率であり、目標とする 70% を下回っているため、Pod は適切にスケーリングされています。トラフィックの変動によっては、自動スケーリングされるレプリカの数も変動する場合があります。レプリカ数の計算方法の詳細な説明については、自動スケーリングの動作をご覧ください。

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

カスタム指標と外部指標用の HorizontalPodAutoscaler を作成するには、指標に基づいて Pod の自動スケーリングを最適化するをご覧ください。

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

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

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

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

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

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

kubectl describe hpa.v2.autoscaling HPA_NAME

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

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

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

Name:                                                  nginx
Namespace:                                             default
Labels:                                                <none>
Annotations:                                           kubectl.kubernetes.io/last-applied-configuration:
                                                         {"apiVersion":"autoscaling/v2","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 を削除するには、Google Cloud コンソールまたは kubectl delete コマンドを使用できます。

コンソール

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

  1. Google 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 が必要な計算を実行できないため、その指標に関連する処理を行いません。

次のステップ