Kubernetes Horizontal Pod Autoscaler(HPA)は、平均CPU使用率や平均メモリ使用率、あるいは任意のカスタムメトリクスをもとに、Deployment/StatefulSetのPodを需要に応じて自動でスケールアップ・スケールダウンする仕組みです。これによりworkloadsの管理は大きく変わりました。
従来の実装
Podのリソース使用量は、Pod内の各コンテナの使用量を合算した値として算出されます。しかしこの方式は、コンテナ間で使用量に強い相関がなかったり、増減のペースが揃っていなかったりするworkloadsには必ずしも適していません。
たとえば、ログを処理するサイドカーコンテナはほとんどリソースを消費しない一方で、メインのブログアプリケーションのコンテナが処理の大半を担うケースを考えてみてください。Pod全体の平均メトリクスでは実態を正しく捉えられず、HPAは本来基準にすべき重要なコンテナの使用状況に基づいたスケーリングができません。

Deployment内の全Podの平均リソース使用率に基づくHPAスケーリング
新しい実装
Kubernetes v1.20で導入され、v1.30で安定版(stable)に昇格したContainer resource metrics機能を使うと、HPAでPod内の個々のコンテナのメトリクスをターゲットに指定できます。Pod内の特定コンテナのリソース使用率(CPUやメモリなど)に基づいてスケーリングするよう、HPAを定義できるのです。
これによりリソースを効率的に割り当てられ、重要度の低いコンテナによってPod全体の使用率が押し上げられ不要なスケーリングが発生する事態も防げます。中核機能を担うコンテナのリソース消費だけを監視すれば、本来のworkloadに焦点を絞ってスケーリングを判断でき、パフォーマンスのボトルネックも未然に防げます。

Deployment内の全Podにおける、対象コンテナの平均リソース使用率に基づくHPAスケーリング
本記事では、マルチコンテナPod構成のDeploymentをスケールさせる際に、container resource metrics機能をどのように活用するかを解説します。
前提条件
- バージョン1.27以降のKubernetesクラスター
- KubernetesクラスターにMetrics Serverがデプロイされていること
- 作業端末にKubectlがインストールされていること
Container resource metricsによるスケーリングを試す
- 以下のマニフェストでサンプルとなるマルチコンテナDeploymentをデプロイします。
cpu-stressorはKubernetes Pod上でCPU負荷をシミュレートするためのメインコンテナです。cpu-stressorツールの詳細はGitHubのリポジトリを参照してください。log-genertorは同じPod内に配置したサンプルのセカンダリコンテナです。
cat <<EOF | kubectl apply -f -
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: crm-scaling-demo
labels:
app: crm-scaling-demo
spec:
selector:
matchLabels:
app: crm-scaling-demo
template:
metadata:
labels:
app: crm-scaling-demo
spec:
containers:
- name: cpu-stressor
image: narmidm/k8s-pod-cpu-stressor:1.0.0
args:
- "-cpu=0.5"
- "-duration=3600s"
resources:
limits:
cpu: "200m"
requests:
cpu: "100m"
- name: log-generator
image: busybox:1.28
args: [/bin/sh, -c,\
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
resources:
requests:
cpu: "100m"
EOF

サンプルのPodと、Pod内の全コンテナのリソース使用状況
- Podのメトリクスではなく、
cpu-stressorコンテナのCPU使用率を基準にスケーリングするHorizontailPodAutoscalerリソースを作成します。
cat <<EOF | kubectl apply -f -
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: crm-scaling-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: crm-scaling-demo
minReplicas: 1
maxReplicas: 10
metrics:
- type: ContainerResource #new-metrics-source
containerResource:
name: cpu
container: cpu-stressor #container-name
target:
type: Utilization
averageUtilization: 50
EOF

cpu-stressorコンテナのメトリクスに基づくHPA設定例
この例では、HPAコントローラは、全Podのcpu-stressorコンテナにおけるCPU平均使用率が50%になるように対象をスケールさせます。
cpu-stressorコンテナがCPU負荷をかけ始めるのを待つと、HPAがcpu-stressorコンテナのCPU使用率に基づいてPod数を再計算する様子が確認できます。

cpu-stressorコンテナのメトリクスに基づくHPAスケーリングの例
container resource metricsを用いたHPAスケーリングのデモ
スクリーンショットとデモ動画から、マルチコンテナPod構成においてcpu-stressorコンテナを基準としたHPAスケーリングが想定どおりに動作していることがわかります🚀。
container resource metricsがKubernetes v1.30で安定版に昇格したことで、Horizontal Pod Autoscalingの精度を一段と高め、アプリケーションのパフォーマンスを最適に保てるようになりました。
本記事がお役に立てば幸いです。さらに詳しく知りたい方は、以下のリソースもあわせてご覧ください。