Kubernetes リソースとオートスケーリングの管理

KubernetesBeginner
オンラインで実践に進む

はじめに

スケジューラーはリソースリクエストを基に Pod の配置先を決定し、kubelet はリミットを適用します。また、HorizontalPodAutoscaler はメトリクスと適切な使用率の基準値を必要とします。これらの設定が、容量管理の一連のワークフローを構成します。

この実験では、リクエストとリミットを設定し、現在の使用量を確認して HPA を作成します。その後、負荷を発生させ、レプリカ数の変化を観察します。

これらの設定は依存関係のある連鎖を形成します。CPU リクエストが基準値を定め、metrics-server が直近の使用量を報告し、HPA が両者を比較してレプリカ数を変更するか判断します。リクエストを設定しなければ、パーセンテージによる CPU 使用率を意味のある形で計算できません。

リクエストとリミットを設定する

このステップでは、リソースを明示的に指定して Kubernetes HPA のサンプルをデプロイします。

リクエストは、スケジューリングに使用される量であり、オートスケーリングの分母にもなります。リミットは、コンテナに適用される最大値です。CPU にはコア数またはミリコア(100m は 0.1 コア)を使用し、メモリには Mi などのバイト単位を使用します。

cd /home/labex/project/resource-autoscaling
kubectl create namespace practice-capacity
kubectl create deployment cpu-demo -n practice-capacity --image=registry.k8s.io/hpa-example:latest --replicas=1

生成された Deployment にリソース設定を追加します。kubectl set resources は Pod テンプレートを更新するため、ロールアウトが開始されます。

kubectl set resources deployment/cpu-demo -n practice-capacity --requests=cpu=100m,memory=32Mi --limits=cpu=200m,memory=64Mi
kubectl expose deployment cpu-demo -n practice-capacity --port=80 --target-port=80
kubectl rollout status deployment/cpu-demo -n practice-capacity --timeout=60s
kubectl get deployment cpu-demo -n practice-capacity -o jsonpath='{.spec.template.spec.containers[0].resources}{"\n"}'

100m は CPU コア 1 個の 10 分の 1 を意味します。リクエストはスケジューリングと使用率計算に影響し、リミットはコンテナが消費できる量の上限になります。

JSONPath の出力には requests と limits の両方が含まれているはずです。リミットだけを設定しても、HPA が使用する使用率の分母は提供されません。

deployment "cpu-demo" successfully rolled out
{"limits":{"cpu":"200m","memory":"64Mi"},"requests":{"cpu":"100m","memory":"32Mi"}}

JSON ではキーの表示順が異なる場合があります。行内での位置ではなく、4 つの値が存在することを確認してください。

リソースメトリクスを確認する

このステップでは、準備済みのメトリクスパイプラインが動作していることを確認し、使用量を調べます。

kubectl top は、オペレーティングシステムの top コマンドに近い、直近の使用量のスナップショットを表示します。設定済みのリクエストやリミットは表示されません。これらは引き続きワークロードの仕様の一部です。

cd /home/labex/project/resource-autoscaling
kubectl get deployment metrics-server -n kube-system
for attempt in $(seq 1 18); do
  if kubectl top nodes >/dev/null 2>&1 && kubectl top pods -n practice-capacity --containers >/dev/null 2>&1; then
    break
  fi
  echo "Waiting for the first metrics sample (${attempt}/18)..."
  sleep 5
done
kubectl top nodes
kubectl top pods -n practice-capacity --containers

kubectl top はリソースリクエストではなく、直近のメトリクスを読み取ります。メトリクスが利用可能になるまで少し時間がかかる場合があります。新しい Pod にまだサンプルがない場合は、数秒待ってから再試行してください。

上のループが、その再試行を自動的に行います。最大 18 回まで何も表示せずに確認し、各試行の間に 5 秒待機します。その後、サンプルが利用可能になった時点で 2 つの top コマンドを表示付きで実行します。確認処理では、>/dev/null によって通常の出力を破棄し、2>&1 によってエラー出力も同じ場所へ送ります。これにより、「まだメトリクスを取得できない」といった想定内のメッセージがターミナルに表示されません。この遅延は、直近の使用量を収集するパイプラインでは通常の動作です。Pod に障害が発生したことを意味するものではありません。

ノードと Pod の値は環境によって異なるため、正確な数値ではなく、CPU とメモリの列が表示されていることを確認してください。1 つの Pod に複数のコンテナが含まれる場合、--containers を指定するとコンテナごとの使用量を確認できます。

たとえば、テスト環境では、ノード一覧とコンテナごとの一覧が次のように表示されました。

NAME         CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
labex-v135   182m         9%       1602Mi          44%

POD                         NAME          CPU(cores)   MEMORY(bytes)
cpu-demo-...                hpa-example   1m           9Mi

これらの数値は設定値ではなく実測値であるため、環境によって異なっていて問題ありません。

HorizontalPodAutoscaler を作成する

このステップでは、平均 CPU 使用率の目標を 30 パーセントに設定し、レプリカ数を 1〜4 の範囲で調整できるようにします。

リクエストが 100m の場合、30% の目標は、Pod あたり平均しておよそ 30m の CPU 使用量に相当します。HPA は Deployment の希望レプリカ数を調整しますが、min=1 未満にも max=4 超にもなりません。

cd /home/labex/project/resource-autoscaling
kubectl autoscale deployment cpu-demo -n practice-capacity --cpu=30% --min=1 --max=4
kubectl get hpa cpu-demo -n practice-capacity
kubectl describe hpa cpu-demo -n practice-capacity

使用率は、100m の CPU リクエストを基準として測定されます。このリクエストがなければ、パーセンテージによる CPU 目標の分母が存在しません。

現在の kubectl autoscale 構文では、パーセンテージを --cpu=30% のように明示的に指定します。これは以前の --cpu-percent フラグに代わるものであり、Kubernetes 1.35 では後者は非推奨として報告されます。

最初の数秒間は、新しいメトリクスサンプルが収集されるまで、TARGETS 列に <unknown> と表示される場合があります。describe hpa を実行すると、コントローラーが利用可能なメトリクスを取得できているかどうかを示す状態やイベントを確認できます。

そのため、初期状態の一覧はエラーがなくても次のように表示される場合があります。

NAME       REFERENCE             TARGETS              MINPODS   MAXPODS   REPLICAS
cpu-demo   Deployment/cpu-demo   cpu: <unknown>/30%   1         4         0

コントローラーの次回同期後には、<unknown> が測定されたパーセンテージに変わり、REPLICAS に Deployment のレプリカ数が反映されます。

負荷を発生させ、スケーリングを確認する

このステップでは、一時的なクライアントを実行し、最大 60 秒間 Service に対して繰り返しリクエストを送信します。

BusyBox の timeout コマンドは、内部のリクエストループを 60 秒間実行します。while ループは CPU 負荷の高いサンプルのエンドポイントを繰り返し呼び出し、>/dev/null はレスポンス本文を破棄してターミナルを見やすく保ちます。制限時間に達すると通常はゼロ以外のステータスが返されるため、|| true によって、予定どおりの停止を正常終了として扱います。

cd /home/labex/project/resource-autoscaling
kubectl run load-generator -n practice-capacity --image=busybox:1.36 --image-pull-policy=IfNotPresent --restart=Never --rm -i -- sh -c 'timeout 60 sh -c "while true; do wget -qO- http://cpu-demo >/dev/null; done" || true'
kubectl get hpa cpu-demo -n practice-capacity
kubectl get deployment cpu-demo -n practice-capacity

HPA は非同期に反応するため、クライアントの終了後もレプリカ数の変更が続く場合があります。すぐにスケーリングされると決めつけず、HPA の状態とイベントを確認してください。

最初の一覧でスケーリングが確認できない場合は、kubectl get hpa cpu-demo -n practice-capacity -w を短時間実行し、変化を確認したら Ctrl+C を押してください。-w は更新を監視するだけで、HPA 自体は変更しません。メトリクスの制御ループは非同期で動作するため、正確な所要時間は検証条件に含めていません。

テスト時には、HPA が目標値を上回る使用量を検出し、Deployment を Ready なレプリカ 2 個まで増やしました。

NAME       REFERENCE             TARGETS        MINPODS   MAXPODS   REPLICAS
cpu-demo   Deployment/cpu-demo   cpu: 55%/30%   1         4         2

NAME       READY   UP-TO-DATE   AVAILABLE
cpu-demo   2/2     2            2

実際の使用率やレプリカ数は異なる場合があります。重要なのは、現在の 55% が目標の 30% を上回ったため、1〜4 の範囲内で希望容量が増加したという点です。

まとめ

リクエスト、リミット、リアルタイムのメトリクス、使用率の目標、HPA の判断がどのように連携するかを確認しました。容量管理はフィードバックループです。基準値を定義し、使用量を観測し、範囲を設定して、コントローラーの状態を確認します。