Kubernetesにおけるオートスケーリングの概要

2024年4月9日(火)
吉村 翔太 (よしむら・しょうた)
第1回の今回は、Kubernetesを用いたアプリケーション管理に革命をもたらす「オートスケール」について、水平スケール、垂直スケール、多次元スケールの各技術を解説します。

はじめに

Kubernetesにはリソースの利用状況に応じてオートスケールする仕組みがあります。この仕組みを上手く利用することで、従来は手動で行なっていた「パフォーマンス管理」や「キャパシティー・プランニング」の一部を自動化することができます。本連載では、Kubernetesのオートスケールに関して説明していきます。

Kubernetesにおけるオートスケール

Kubernetesのオートスケールは、スケールする対象が異なる以下の2種類があります。

  1. Podのオートスケール
    Podのリソース使用量を評価して、Podに対するリソースの割り当てをコントロールします。
  2. クラスタのオートスケール
    クラスタのリソース使用量を評価し、ノードの増減等を行うことでクラスタで利用できるリソース量をコントロールします。

Kubernetesでオートスケールを利用する場合は、まずアプリケーションの性能要件に合わせてPodのオートスケールを設定します。その際にPodへのリソースの割り当ての増加により、クラスタ内のリソースが枯渇するのを防ぐためにクラスタのオートスケールを設定するというのがよくあるユースケースです。

オートスケールを実施する目的

リソースを「増やす」と「減らす」では、それぞれの仕組みや挙動が異なる点に注意が必要ですが、それぞれを設定する目的が異なる点も意識する必要があります。実際のユースケースでは以下の目的を持って設定することが多いと思います。

  1. リソースを増やす
    リソース不足によって、アプリケーションが期待される性能発揮できなくなるのを防ぐために設定します。
  2. リソースを減らす
    余剰リソースを削減することで、コストの最適化を行います。

これから紹介するオートスケールに関するどの機能を利用するにしても、まずは自分たちがリソースの増減によってどういう状態を実現していきたいかをはっきりさせる必要があります。

Podのオートスケール

Podのオートスケール方法である、以下の3つの方法について概要を説明します。

  • 水平スケール: HorizontalPodAutoscaler(HPA)
  • 垂直スケール: VerticalPodAutoscaler(VPA)
  • 多次元(水平垂直)スケール: MultidimensionalPodAutoscaler(MPA)

Podの水平スケール

KubernetesではPodを水平スケールさせるHorizontalPodAutoscaler(HPA)という仕組みが標準で用意されています。Podのリソースの使用状況に応じてPod数を自動で増減するように設定できます。以前はv1と呼ばれる仕組みがありましたが、現在はKubernetes v1.23からGAとなったHPAのv2という仕組みを利用するようにしてください。

HPAのv2を利用する場合は、以下のようなマニフェストを利用して設定します。

・HPAのリソースの例
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-sample
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-sample
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

こちらの機能は、CPUの使用率が増えた場合にPod数を増やしたいなどのユースケースでよく使われます。

【参考】HPAに関するKubernetesの公式ドキュメントの説明

Podの垂直スケール

KubernetesではPodを垂直スケールさせるVerticalPodAutoscaler(VPA)が用意されていますが、こちらはHPAとは異なり標準では利用できる状態になっていません。コミュニティで開発されているVPAのコントローラーを自分でKubernetesクラスタにデプロイすることで利用できるようになります。利用するKubernetesサービスによっては有効化するだけでVPAを利用できるものもあります。VPAは現在1.0(GA)となっており、Kubernetes v1.25以上が動作環境になります。

VPAを利用する場合は、以下のようなマニフェストを利用して設定します。

・VPAのリソースの例
apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
  name: vpa-sample
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: vpa-sample
  resourcePolicy:
    containerPolicies:
      - containerName: '*'
        minAllowed:
          cpu: 100m
          memory: 50Mi
        maxAllowed:
          cpu: 1
          memory: 500Mi
        controlledResources: ["cpu", "memory"]

こちらの機能はアプリケーションのメモリ使用量が増えた場合に、より多くのメモリを割り当てたいなどのユースケースで使われます。ただ、Podのリソースの割り当てを変更する際に、Podを再作成するのか、既存のPodのリソース量を変更するのかなど、水平スケールと比べてより多くのことを検討して使用する必要があるので、注意が必要です。

【参考】コミュニティで開発されているVPAに関するGithubのリポジトリ

Podの多次元(水平垂直)スケール

KubernetesではPodを多次元(水平垂直)スケールするMultidimensionalPodAutoscaler(MPA)という仕組みがコミュニティで提案されています。こちらの機能は提案のみで、まだコミュニティで実装の開発はされていません。しかし、Google Kubernetes Engine(GKE)の場合は独自に実装されたものがあり、利用できます。

MPAを利用する場合は、以下のようなマニフェストを利用して設定します。

・MPAのリソースの例
apiVersion: autoscaling.gke.io/v1beta1
kind: MultidimPodAutoscaler
metadata:
  name: mpa-sample
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mpa-sample
  goals:
    metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  constraints:
    global:
      minReplicas: 1
      maxReplicas: 5
    containerControlledResources: [ memory ]
    container:
    - name: '*'
      requests:
        minAllowed:
          memory: 1Gi
        maxAllowed:
          memory: 2Gi
  policy:
    updateMode: Auto

こちらの機能を使う場合はHPAとVPAを併用した場合の課題について理解する必要があります。HPAとVPAを同じPodに対して設定した場合にPodのリソースの状況によってはオートスケールによる増減が頻繁に繰り返されて不安定な状態になるリスクがあります。

そこで、水平・垂直のオートスケールで設定できるリソースの変動の条件に以下の制約を課すことで、Podに水平・垂直スケールを同時に設定してもPodの状態が安定するように配慮された機能になります。

  • 水平スケール: CPU使用量の変動に応じてのみ設定できる
  • 垂直スケール: メモリ使用量の変動に応じてのみ設定できる

こちらの機能はHPAとVPAを同時に設定した場合のリスクを抑制することに価値があるので、Podの垂直スケールを利用したけどPodの水平スケールも実施したい場合に、HPAとVPAのリソースの作成を禁止して必ずMPAのリソースを使うなどの運用ルールを整備して利用することで、より効果を発揮する機能になります。

しかし、水平スケールにCPU使用量以外の条件(例えばアプリケーション1つあたりのリクエスト数)を設定したい場合などはMPAではなくHPAの機能を拡張して利用する必要があるので、利用したい条件に応じで運用する際のルールをより細かく設定して使用する必要があります。

多次元スケールは水平・垂直スケールと比較して複雑な仕組みになるためより多くのことを検討する必要がありますが、使いこなせばより多くのことが実現できる魅力的な機能でもあります。

【参考】コミュニティ管理されているMPAの機能提案に関するドキュメント
【参考】MultidimPodAutoscalerに関するGoogle Cloudのドキュメント

クラスタのオートスケール

クラスタのオートスケール方法である、以下の3つについて概要を説明します。

  • Cluster Autoscaler(CAS)
  • Karpenter
  • GKE Autopilot

Cluster Autoscaler

Cluster Autoscalerは、クラスタのリソースの利用状況に応じてノード数を増減させる仕組みです。こちらはコミュティで参考となる実装が公開されているので、そちらを元に自分たちの環境で動作するcloudproviderと呼ばれる機能を追加で実装すると利用できるようになります。利用するKubernetesサービスによっては既に実装されており、有効化するだけで使えるサービスもあります。

こちらの機能はPodを新規作成したときにクラスタ内のリソース不足でスケジュールできない場合に、Cluster Autoscalerが外部サービス(OpenStackやAWS、GCE、Azureなど)にノードの新規作成を依頼することで、クラスタ内で使用できるリソース量を増やすというのが簡単な機能の説明になります。Cluster Autoscalerはあくまでノードの新規作成や削除の指示を出すだけなので、ノードの作成削除の時間等については外部サービスに依存します。

また、クラスタ内のリソースの状況に応じてノードの削除も行いますが、以下のような条件に該当するPodがノードに存在する場合はノードが削除されないため、思ったようにリソースの削減によるコスト削減が進まないことがあります。

・Cluster Autoscalerがノードの削減をしない条件の例
  • PodDisruptionBudget(PDB)によって制限されているPod
  • DeploymentやJob、StatefulSetなどのコントローラーによって管理されていないPod
  • LocalStorageを利用するように設定されているPod
  • スケジュールなどの様々な条件によって、他に移動できるノードが存在しないPod

上記については、対象のPodに"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"のアノテーションを追加することで除外できるため、ノードの削除が期待通りいかない場合は、削除を期待するノードで動作しているPodの状態を確認して条件に対応するように変更を加えるか、Podに該当のアノテーションを付与していくことになります。

こちらの機能は仕組みが少し複雑なので使いこなすのが少し難しいですが、うまく使いこなすと手動で行っていたキャパシティプランニングの一部を自動化できるようになるため、魅力的な機能となっています。

【参考】コミュニティで開発されているCluster Autoscalerに関するGithubのリポジトリ

Karpenter

KarpenterもCluster Autoscalerと同様に、スケジュールできないPodが存在する場合にノードを追加する機能です。

Cluster Autoscalerに対応するノードプール内のノード数を増減させることでクラスタ内で利用できるリソースをコントロールするという考え方になります。その結果どういうことが起こるかというと、ノードを追加するときに既存のクラスタのノードと同一の量のCPUとメモリが搭載されているノードを追加するような形になります。例えば、メモリがもっと少ないノードを追加するだけで十分な場合に、過剰なリソースのノードが追加されて期待しているよりも多くのコストがかかるケースなどがあります。

Karpenterでは、クラスタにノードを追加する際により柔軟に追加するノードの候補を選択してくれるため、ノード追加時に余剰のリソースが発生しづらいという特徴があります。

Karpenterは元々AWSで開発されていましたが、コア機能部分についてはコミュニティに寄贈されました。開発の経緯もあり今まではAWSのみで利用可能でしたが、現在はAzureでも利用できるようになっています。

Karpenterはまだバージョンが1.0になっていませんが、今後はKarpenterが利用できるKubernetesサービスを利用する際はCluster AutoscalerではなくはKarpenterを利用することが一般的になることも考えられる注目の機能です。

【参考】コミュニティで開発されているKarpenterに関するGithubのリポジトリ
【参考】Karpenterの公式ドキュメント
【参考】AWSのKarpenterに関するGithubのリポジトリ
【参考】AzureのKarpenterに関するGithubのリポジトリ

GKE Autopilot

こちらはKubernetesの標準機能ではなく、GKEでのみ利用できるノードのリソース管理する機能です。実装が公開されていないため表面的な挙動からの推察にはなりますが、Cluster Autoscalerに独自の機能を追加し、拡張した機能というイメージになります。

GKE Autopilotはクラスタの運用に幾つかの制限を課す代わりに、ノードのリソース管理をGKE側に任せることができる機能です。

・GKE Autopilotを利用する際に発生する制約の一部
  • Kubernetes Pod Security StandardsのPrivilegedが利用できない(強い権限を持つPodを利用できない)
  • ノードにSSHでアクセスできない

機能がリリースされた当初は多くの制限がありましたが、現在はだいぶ条件が緩和されて色々なユースケースで使えるようになっています。リソースの使用量が大きく変動する場合などは、自分たちでCluster Autoscalerを細く設定したり、手動でノードの追加を実装しないと要件を満たせないケースなどはありますが、上手く利用するとノード管理が楽になる有用な機能になります。

【参考】Autopilotに関するGoogle Cloudのドキュメント

Kubernetes以外でコンテナを管理してくれるプロダクト

多くの場合ではKubernetesを運用することが目的ではなく、コンテナでアプリケーションを運用する目的を達成するための手段としてKubernetesを利用していると思います。そのため、Kubernetesのオートスケールの機能の利用を検討する場合は、各ベンダーから提供されている以下のようなコンテナを動かせる機能も候補に挙げて検討を行い、要件により適したものを選択していくと運用を楽にしていくことができると思います。

本連載ではKubernetesにおけるオートスケーリングに焦点を当てていくため上記についてはあまり触れませんが、実際のプロダクト運用を考える際には検討してみると良いと思います。

おわりに

今回は連載の第1回ということで、オートスケーリングに関する全体の概要について触れていきました。オートスケーリングについては色々な場所でドキュメントが管理されているので、みなさんの知らない情報が1つか2つ程度はあったのではないでしょうか。次回以降は、今回紹介した各項目について、深掘りしていきたいと思います。

また、今回の記事に関する感想や「こんな内容について書いてほしい!」などの要望があれば、下記の「Xポスト」ボタンを押して、ぜひお知らせいただけると嬉しいです。

著者
吉村 翔太 (よしむら・しょうた)
ソフトウェアエンジニア
SIerでインフラエンジニアとしてシステム開発に従事したのちに、通信事業者の研究開発部門でHadoopやKafkaを用いたデータ分析基盤の開発に従事。現在は、CloudNative関連の技術の研究開発を行う会社で国内最大規模のプライベートKubernetes as a Serviceの開発に従事している。他にもCloud Native Developers JP等のCNCF関連のプロダクトに関するコミュニティの運営や登壇を行っており、過去にはObsrvability Conference 2022で「Kubernetes Observability入門」、CloudNative Days Tokyo 2019で「Kubernetes Logging入門」等の登壇を行なっている。
X(旧Twitter): @yosshi_
GitHub: @yosshi825

連載バックナンバー

仮想化/コンテナ技術解説
第1回

Kubernetesにおけるオートスケーリングの概要

2024/4/9
第1回の今回は、Kubernetesを用いたアプリケーション管理に革命をもたらす「オートスケール」について、水平スケール、垂直スケール、多次元スケールの各技術を解説します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています