Photo by Andrii Yalanskyi from Shutterstock
アプリケーションの性能を維持しつつリソース利用率を最適化することは、Kubernetes運用における永遠の課題です。アプリが必要とするリソース量を初期段階で正確に見積もるのは難しく、CPUやメモリを変更する従来の方法ではPodの再作成が避けられず、稼働中のworkloadsに影響が及ぶこともしばしばでした。こうした中断はサービス品質の低下、ダウンタイム、運用負荷の増大を招きます。そこで力を発揮するのが PerfectScale のようなプラットフォームです。workloads全体のリソース使用状況を継続的に分析し、中断を伴う変更に踏み切る前に最適な割り当てを導き出します。
多くのユーザーが待望していた「再起動なしでKubernetes Podをリサイズする」機能は、Kubernetes v1.27 でアルファ版として登場し、v1.33 でベータに昇格しました。機能名は InPlacePodVerticalScaling。Podコンテナの resources フィールドにおいて、cpu と memory の値を変更できるようになり、稼働中のPod specにパッチを当てるだけで反映されます。
インプレースPodリソースリサイズの主なメリット:
- ダウンタイムの削減: Pod再起動に伴うダウンタイムやデータ損失リスクを排除し、サービスを止めずに運用を継続できます。
- 効率の向上: Podのライトサイジングは、リソース利用を最適化するうえで欠かせません。
InPlacePodVerticalScalingなら必要な分だけ正確に割り当てられ、過剰割り当て(コストの無駄)も過小割り当て(性能不足)も回避できます。 - 俊敏性の向上: 動的なスケーリングにより、需要の変化に即応可能。突発的なトラフィック急増でも、定期バッチでも、Podがリソース使用量をシームレスに調整し、最適な性能と応答性を維持します。
- コスト削減: 過剰割り当てを防ぎリソース使用を最適化することで、InPlacePodVerticalScalingはそのままコスト削減に直結します。リソース単位で課金されるクラウド環境では特に効果的です。
- 運用のシンプル化: 複雑なデプロイの管理は容易ではありませんが、InPlacePodVerticalScalingは手動での再起動を不要にし、リソース管理に新たな選択肢をもたらします。
本記事では、インプレースPodリソースリサイズを実際に試す手順を紹介します。本機能は kubernetes v1.33 時点でベータ版であり、本番環境での利用は推奨されていません。Kubernetesコミュニティは引き続き、本番運用に耐える堅牢性の確保、性能改善、機能の安定化に取り組んでいます。
インプレースPodリソースリサイズを試す
InPlacePodVerticalScaling 機能は、v1.33を実行するクラスタではデフォルトで有効です。minikube クラスタでは以下のコマンドで明示的に有効化できます。マネージドKubernetesクラスタでデフォルト有効になっていない場合は、フィーチャーゲートを有効にしてください。
minikube start --feature-gates=InPlacePodVerticalScaling=true
サンプルPodをクラスタにデプロイしてみましょう。Pod spec内に新たに加わった restartPolicy により、リソースのリサイズ時にコンテナをどう扱うかをユーザー側で制御できます。
以下のサンプルPod構成では、メモリリソースの resizePolicy はメモリ割り当て変更時にコンテナの再起動を要するよう指定し、CPUリソースについてはリサイズ時の再起動が不要であることを示しています。
コンテナを再起動するかどうかは、アプリケーションが再起動なしで更新後のリソースを利用できるかどうかで決まります。たとえば、アプリの動作にとってメモリ使用量が決定的な意味を持つ場合、メモリ変更時にコンテナを再起動することで、正しいメモリ量で起動することを担保できます。これにより、潜在的な不具合や誤動作を未然に防げます。
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resizePolicy:
- resourceName: "memory"
restartPolicy: "RestartContainer"
- resourceName: "cpu"
restartPolicy: "NotRequired"
resources:
limits:
cpu: "300m"
memory: "1Gi"
requests:
cpu: "100m"
memory: "500Mi"
EOF
PodがRunning状態に遷移するのを待ち、Pod構成を確認してみましょう。Podのstatus内 containerStatuses に新フィールド allocatedResources が追加され、Podのコンテナに現在割り当てられているノードリソースが反映されます。
さらに、コンテナのstatusにも resources という新フィールドが追加され、コンテナランタイムが報告する、稼働中コンテナに実際に設定されているrequestsとlimitsを確認できます。
CPUのリサイズ
では、以下のpatchコマンドでPodの CPU リソースを調整し、リサイズ操作の挙動を見てみましょう。Podリソースの変更は、Podの resize サブリソース経由で行う必要があり、kubectl v1.32以降がこの引数に対応しています。
kubectl patch pod nginx --subresource resize --patch '{"spec": {"containers": [{"name":"nginx", "resources":{"requests": {"cpu" :"300m"},"limits": {"cpu" :"500m"}}}]}}'
リサイズ操作のステータスは、2つのPod conditionsで確認できるようになりました:
PodResizePending: Kubeletがリサイズを即座に実行できないことを示します(例:一時的に対応不可ならreason: Deferred、ノード上で実行不可能ならreason: Infeasible)。PodResizeInProgress: リサイズが受理され適用中であることを示します。このフェーズで発生したエラーは、reason: Errorとしてこのconditionのメッセージに記録されます。
コミュニティはKubeletのPod Lifecycle Event Generator(PLEG)を改良し、ベータ版ではKubeletがリサイズへの応答と完了をより迅速に行えるようになりました。ただし、Podのリサイズが他のPod更新と競合する場合があり、その際はリサイズの発動が遅れ、更新後のコンテナリソースがPodのstatusに反映されるまでに時間を要することがあります。
メモリのリサイズ
続いて Memory リソースを調整してみましょう。restartPolicy の指定に従い、コンテナが再起動されます。
kubectl patch pod nginx --subresource resize --patch '{"spec": {"containers": [{"name":"nginx", "resources":{"requests": {"memory" :"700Mi"}}}]}}'
スクリーンショットでは、リサイズ操作とコンテナの再起動が問題なく完了した様子を確認できます 🚀。
本機能はまだ成熟の途上にありますが、PerfectScale のようなプラットフォームは、安全性・性能・コスト効率を自動化されたリソース管理に統合し、すでに本番運用レベルの最適化ワークフローを提供しています。本記事の手順に沿って、ぜひその効果を体感してみてください。
本記事がお役に立てば幸いです。さらに詳しくは、以下のリソースをご参照ください: