Kubernetes Horizontal Pod Autoscaler (HPA) チューニングの実践ガイド
Kubernetesは、アプリケーションのデプロイ、管理、スケーリングの方法に革命をもたらしました。そのスケーリング機能の中核をなすのがHorizontal Pod Autoscaler(HPA)です。これは、CPU使用率やその他の選択されたメトリックに基づいて、デプロイメント、レプリケーションコントローラー、レプリセット、またはステートフルセットのPodレプリカ数を自動的に調整する強力なメカニズムです。HPAは変動する負荷に対応するために immense なメリットを提供しますが、その真の可能性は careful な設定とチューニングによって解き放たれます。
このガイドでは、Kubernetes Horizontal Pod Autoscaler の設定と最適化の実践的な側面に掘り下げていきます。基本的な概念、コアパラメータ、高度なチューニング戦略、およびベストプラクティスをカバーし、アプリケーションが需要に効率的に適応し、変動する負荷下でパフォーマンスを維持し、インフラストラクチャコストを最適化できるようにします。この記事の終わりには、HPAを最大限に活用する方法について solid な理解が得られるでしょう。
Horizontal Pod Autoscaler (HPA) の理解
HPAは、現在の需要に合わせてアプリケーションのPod数を自動的にスケールアップまたはスケールダウンします。指定されたメトリックを継続的に監視し、ターゲット値と比較します。観測されたメトリックがターゲットを超えた場合、HPAはスケールアップイベントを開始します。それを下回った場合、スケールダウンをトリガーします。この動的な調整により、アプリケーションは過剰なプロビジョニングなしに最適なパフォーマンスを発揮するために十分なリソースを確保できます。
HPAは以下に基づいてスケールできます:
- リソースメトリック: 主にCPU使用率とメモリ使用率(
metrics.k8s.ioAPI経由で利用可能、通常はKubernetes Metrics Serverによって提供されます)。 - カスタムメトリック:
custom.metrics.k8s.ioAPI(例:リクエスト/秒、キューの深さ、アクティブな接続数)を通じて公開されるアプリケーション固有のメトリック。これらは通常、prometheus-adapterのようなアダプターが必要です。 - 外部メトリック:
external.metrics.k8s.ioAPI(例:Google Cloud Pub/Subキューサイズ、AWS SQSキュー長)を通じて公開されるクラスター外のソースからのメトリック。これらも外部メトリックを取得できるカスタムメトリックAPIサーバーが必要です。
効果的なHPAチューニングのための前提条件
HPAの設定に入る前に、これらの基本的な要素が整っていることを確認してください:
1. 正確なリソースリクエストと制限の定義
これはおそらく最も重要な前提条件です。 HPAは、使用率のパーセンテージを計算するために、正しく定義されたCPUとメモリのリクエストに大きく依存します。PodにCPUリクエストが定義されていない場合、HPAはそのCPU使用率を計算できず、CPUベースのスケーリングは不可能になります。
- リクエスト: コンテナに保証される最小リソースを定義します。HPAはこれらの値を使用してPodあたりのターゲット使用率を決定します。
- 制限: コンテナが消費できる最大リソースを定義します。制限は、単一のPodが過剰なリソースを消費して、同じノード上の他のPodに影響を与えることを防ぎます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image:latest
resources:
requests:
cpu: "200m" # CPUコアの20%
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
2. Kubernetes Metrics Server のインストール
HPAがCPUおよびメモリ使用率メトリックを使用するには、Kubernetes Metrics Server がクラスターにインストールされている必要があります。これはKubeletsからリソースメトリックを収集し、metrics.k8s.io APIを通じて公開します。
3. アプリケーションオブザーバビリティ
カスタムメトリックまたは外部メトリックの場合、アプリケーションは関連するメトリック(例:Prometheusエンドポイント経由)を公開する必要があり、これらのメトリックをKubernetes APIに収集して公開する方法(通常はPrometheusアダプターまたはカスタムメトリックAPIサーバーを使用)が必要です。
HPA の設定:コアパラメータ
HPAマニフェストの基本的な構造を見てみましょう:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
主要なパラメータ:
scaleTargetRef: HPAがスケールするターゲットリソース(例:Deployment)を定義します。そのapiVersion、kind、およびnameを指定します。minReplicas: HPAがスケールダウンするPodの最小数。負荷がゼロの場合でも、高可用性のために少なくとも1つまたは2つに設定することが良いプラクティスです。maxReplicas: HPAがスケールアップするPodの最大数。これは、暴走するスケーリングを防ぎ、コストを制限するためのセーフガードとして機能します。metrics: HPAが監視すべきメトリックを定義する配列。type:Resource、Pods、Object、またはExternalのいずれかです。resource.name:Resourceタイプの場合、cpuまたはmemoryを指定します。target.type:Resourceタイプの場合、Utilization(リクエストされたリソースのパーセンテージ)またはAverageValue(絶対値)。averageUtilization:Utilizationタイプの場合、ターゲットパーセンテージ。HPAはcurrent_utilization / target_utilization * current_pods_countに基づいて必要なPod数を計算します。
レスポンシブネスと安定性のためのHPAチューニング
基本的な設定を超えて、HPAは特にautoscaling/v2(または古いバージョンではv2beta2)で、スケーリング動作をより細かく管理するための高度なチューニングオプションを提供し、「スラッシング」(急速なスケールアップとスケールダウンのサイクル)を防ぎます。
1. CPUとメモリのターゲット(averageUtilization / averageValue)
適切なターゲット使用率の設定は重要です。低いターゲットは早期のスケーリング(より応答性が高いが、コストがかかる可能性がある)を意味し、高いターゲットは遅いスケーリング(応答性が低いが、安価だがパフォーマンス低下のリスクがある)を意味します。
- 最適なターゲットの決定方法: ロードテストとプロファイリングが最良の友です。リソース使用率とパフォーマンスメトリック(レイテンシ、エラー率)を監視しながら、アプリケーションへの負荷を徐々に増やしてください。アプリケーションのパフォーマンスが低下し始めるCPU/メモリ使用率を特定します。このしきい値より下にHPAターゲットを設定します。通常、CPUの場合は60-80%の範囲です。
- バランス: 予期しないスパイクのための十分なヘッドルームを残すが、常に過剰プロビジョニングされているほど低くないターゲットを目指してください。
2. スケーリング動作(behaviorフィールド)
HPA autoscaling/v2で導入された behavior フィールドは、スケーリングアップおよびダウンイベントの細かい制御を提供し、「スラッシング」(急速なスケールアップとスケールダウンのサイクル)を防ぎます。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 60 # 再度スケールアップする前に60秒待機
policies:
- type: Pods
value: 4
periodSeconds: 15 # 15秒ごとに最大4つのPodを追加
- type: Percent
value: 100
periodSeconds: 15 # または、現在のPod数を15秒ごとに2倍にする(どちらかrestrictiveでない方)
scaleDown:
stabilizationWindowSeconds: 300 # スケールダウンする前に5分待機
policies:
- type: Percent
value: 50
periodSeconds: 60 # 60秒ごとにPodの最大50%を削除
selectPolicy: Max # '最も積極的な'(少ない数の)Podを許可するポリシーを選択
scaleUp設定:
stabilizationWindowSeconds: これは、急速なスケールアップとスケールダウンのサイクル(フラッピング)を防ぎます。HPAはスケールアップ時にこのウィンドウからのメトリックを考慮し、高いメトリックが持続する場合にのみスケールアップすることを確認します。典型的な値は30-60秒です。policies: スケールアップイベント中にPodがどのように追加されるかを定義します。複数のポリシーを定義でき、HPAは最も多くのPodを許可するポリシー(最も積極的なスケールアップ)を使用します。type: Pods: 固定数のPodでスケールアップします。valueは追加するPod数を示します。periodSecondsは、このポリシーが適用される時間ウィンドウを定義します。type: Percent: 現在のPod数のパーセンテージでスケールアップします。valueはそのパーセンテージです。
scaleDown設定:
stabilizationWindowSeconds:scaleDownにとってより重要であり、スケールダウンを検討する前に、ターゲットを下回るメトリックをHPAが観測する必要がある時間を指定します。一時的な低迷時の時期尚早なスケールダウンを防ぎ、「コールドスタート」とパフォーマンスの低下を回避するために、より長いウィンドウ(例:300-600秒)を使用します。これは安定した環境にとって重要な設定です。policies:scaleUpと同様に、Podがどのように削除されるかを定義します。HPAは、selectPolicyがMinの場合、最小数のPod(最も積極的なスケールダウン)をもたらすポリシーを使用します。Maxの場合、最大数のPod(最も積極的でないスケールダウン)をもたらすポリシーを選択します。type: Pods: 固定数のPodを削除します。type: Percent: 現在のPodのパーセンテージを削除します。
-
selectPolicy: 複数のscaleDownポリシーが定義されている場合に適用するポリシーを決定します。Minはデフォルトであり、より保守的なダウンサイリングに一般的に推奨されます。Maxは、最も多くのPod(最も積極的でないダウンサイリング)をもたらすポリシーを選択します。 -
警告: 積極的な
scaleDownポリシーまたは短いstabilizationWindowSeconds(scaleDownの場合)には注意してください。アプリケーションの初期化時間が長い場合やステートフルな接続を処理する場合、急速なダウンサイリングはサービスの中断やユーザーへのレイテンシ増加につながる可能性があります。
高度なHPAメトリックと戦略
CPUとメモリは一般的ですが、多くのアプリケーションは、実際のワークロードを反映するカスタムまたは外部メトリックでより良くスケールします。
1. カスタムメトリック
CPU/メモリがアプリケーションの負荷またはパフォーマンスのボトルネックの直接的な指標ではない場合、カスタムメトリックを使用します。例:HTTPリクエスト/秒(QPS)、アクティブ接続数、メッセージキューの深さ、バッチジョブのバックログ。
カスタムメトリックを使用するには:
1. アプリケーションはこれらのメトリックを公開する必要があります(例:Prometheusエクスポーター経由)。
2. これらのメトリックをスクレイプしてcustom.metrics.k8s.io APIを通じて公開できるカスタムメトリックアダプター(例:prometheus-adapter)をデプロイします。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa-qps
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 15
metrics:
- type: Pods # メトリックがデプロイメント全体のものである場合はObject
pods:
metric:
name: http_requests_per_second # アプリケーション/アダプターによって公開されるメトリックの名前
target:
type: AverageValue
averageValue: "10k" # Podあたり毎秒10,000リクエストをターゲット
2. 外部メトリック
外部メトリックは、アプリケーションのワークロードがKubernetes上で直接実行されていない外部システムによって駆動されている場合に役立ちます。例:AWS SQSキューの深さ、Kafkaトピックのラグ、Pub/Subサブスクリプションのバックログ。
外部メトリックを使用するには:
1. 外部システムからメトリックを取得できるカスタムメトリックAPIサーバーが必要です(例:AWS CloudWatchまたはGCP Monitoringの特定のアダプター)。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-worker-hpa-sqs
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-worker
minReplicas: 1
maxReplicas: 20
metrics:
- type: External
external:
metric:
name: aws_sqs_queue_messages_visible # 外部ソースからのメトリック名
selector:
matchLabels:
queue: my-queue-name
target:
type: AverageValue
averageValue: "100" # Podあたりキューに100メッセージが表示されていることをターゲット
3. 複数メトリック
HPAは複数のメトリックを同時に監視するように設定できます。複数のメトリックが指定されている場合、HPAは各メトリックについて独立して必要なレプリカ数を計算し、これらの必要なレプリカ数のうち最高値を選択します。これにより、アプリケーションは観測されたすべての負荷次元に対して十分にスケールすることが保証されます。
# ... (HPAの定型文)
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "10k"
モニタリングと検証
効果的なHPAチューニングは、継続的な監視と検証を必要とする反復プロセスです:
- HPAイベントの観測:
kubectl describe hpa <hpa-name>を使用して、HPAのステータス、イベント、およびスケーリングの決定を表示します。これにより、HPAがスケールアップまたはスケールダウンした理由についての valuable な洞察が得られます。 - メトリックとレプリカの監視: オブザーバビリティスタック(例:Prometheus、Grafana)を使用して、アプリケーションのリソース使用率(CPU、メモリ)、カスタム/外部メトリック、およびPodレプリカの実際の数を経時的に可視化します。これらを入ってくる負荷の変化と相関させます。
- ロードテスト: 予想される負荷とピーク負荷をシミュレートして、HPAの応答性を検証し、アプリケーションがストレス下で期待どおりに動作することを確認します。これらのテストに基づいてHPAパラメータを調整します。
HPAチューニングのベストプラクティス
- 明確に定義されたリソースリクエスト/制限から始める: これらは、正確なリソースベースのHPAの基盤です。これらがなければ、HPAはCPU/メモリに対して効果的に機能できません。
- 現実的な
minReplicasとmaxReplicasを設定する:minReplicasは可用性のベースラインを提供し、maxReplicasは暴走コストとリソース枯渇に対するセーフティネットとして機能します。 - ターゲット使用率を徐々に調整する: 少し保守的なCPUターゲット(例:60-70%)から始めて、反復します。レイテンシや処理スパイクのバッファを残さないため、100%の使用率を目指さないでください。
stabilizationWindowSecondsを活用する: 急速なスケーリングの振動を防ぐために不可欠です。安定性を確保するために、scaleDown(例:5〜10分)よりもscaleUp(例:1〜2分)に長いウィンドウを使用します。- アプリケーション固有のメトリックを優先する: CPUまたはメモリがアプリケーションのパフォーマンスボトルネックに直接相関しない場合は、より正確で効率的なスケーリングのためにカスタムまたは外部メトリックを使用します。
- 監視、テスト、反復: HPAチューニングは一度きりの設定ではありません。アプリケーションの動作、トラフィックパターン、および基盤となるインフラストラクチャは変化する可能性があります。HPAのパフォーマンスを定期的にレビューし、必要に応じて設定を調整します。
- アプリケーションのスケーリング特性を理解する: リクエストに対して線形にスケールしますか?起動時間が長いですか?ステートフルですか?これらの特性はHPA戦略に影響します。
結論
Kubernetes Horizontal Pod Autoscalerは、Kubernetes環境で回復力があり、コスト効率が高く、パフォーマンスの高いアプリケーションを構築するための重要なコンポーネントです。そのコアメカニズムを理解し、正確なリソースリクエストを定義し、スケーリング動作パラメータを careful にチューニングすることで、アプリケーションが精密に変動する負荷に自動的に適応することを保証できます。
効果的なHPAチューニングは、測定、観測、および調整の継続的な旅です。反復プロセスを受け入れ、適切な場所で高度なメトリックを活用し、アプリケーションのパフォーマンスを継続的に監視して、Kubernetes内での動的スケーリングの可能性を最大限に引き出してください。