Cloud Intelligence™
起動時の過剰プロビジョニングはもう不要:GKEの新機能CPU startup boost
このページはEnglish、Deutsch、Español、Français、Italiano、Portuguêsでもご覧いただけます。
About Chimbu Chinnadurai
I've probably debugged a Kubernetes issue in more time zones than I care to count. Based in London, I help engineering teams across EMEA get their clusters to behave — and actually understand why they misbehaved in the first place.
I write, speak, and guest on podcasts about all things cloud-native. Away from the terminal: I enjoy cooking almost as much as simplifying overly complex systems.
My personal pageJVMやSpring Bootアプリ、あるいは重量級フレームワークを使ったアプリケーションをKubernetes上で運用したことがあれば、おなじみの光景でしょう。コンテナのウォームアップが済んでしまえば、すべては順調です。レイテンシは安定し、CPU使用率は下がり、あとは淡々と動き続けます。しかし起動直後の数秒間、ときには数十秒間は、まったく別のワークロードです。クラスのロード、JITのウォームアップ、依存性注入グラフの構築、コネクションプールの初期化。これらすべてが一斉にCPUを大量消費し、始まったかと思えばすぐに終わります。
Kubernetesは「定常状態」と「コールドスタート」を区別しません。コンテナに設定したCPUリクエストが、Podのライフサイクル全体を通じてそのまま適用されます。
PerfectScale™ for Kubernetes
Ready to optimize?
Get your free Kubernetes savings analysis

トレードオフ:起動速度か、アイドル時の無駄か
Kubernetes上でレイテンシに敏感な重いワークロードを運用するチームは、どちらも悩ましい2つの妥協のいずれかを選ばざるを得ません。
起動に合わせてサイジングし、その分を払い続ける。 初期化を素早く終えられるよう、CPUリクエストを高めに設定します。ウォームアップ後のアプリはわずかなCPUしか必要としないにもかかわらず、です。そのリクエストは24時間365日そこに居座り続けます。スケジューラがPodの配置に使うのも、クラスタオートスケーラーがノード追加の判断に使うのも、課金の対象になるのも、この値です。レプリカが数百規模になれば、起動の高速化と引き換えに続く無駄はあっという間に積み上がります。
定常状態に合わせてサイジングし、起動のたびに苦しむ。 リクエストを実際のランタイム使用量に合わせ、再起動・ローリングデプロイ・ノードアップグレードのたびにReadyまでの長い道のりを受け入れる、というやり方です。CPUスロットリングの影響で、本来5秒で終わるはずのJVMウォームアップが30秒以上に延びることもあります。その結果、ロールアウトは遅くなり、HPAイベント時のスケールアウトも遅れ、ユーザーにレイテンシスパイクが及ぶおそれもあります。
どちらも到底受け入れられるものではありません。CPU startup boostは、このギャップを埋めるために作られた機能です。
CPU startup boostが実際に解決すること
CPU startup boostは、GKEのVertical Pod Autoscaler(VPA)の新機能で、現在プレビュー版として提供されています。Podの初期化中にコンテナのCPUリクエストを一時的に引き上げ、その後コンテナを再起動することなく自動的にベースラインまで戻すことができます。
リソースを大量に消費するランタイム(Java、Node.js、重いインポートを伴うPython)は、必要なとき、つまり初期化中にだけ、必要なCPUの余裕を確保できます。ベースラインのリクエストは、Podの寿命の最初の数秒のために水増しした妥協の値ではなく、実際の定常状態の使用量を反映した値にできます。ブースト値からベースラインへの縮小には、Podの退避と再作成ではなくKubernetesのインプレースPodリサイズ(IPPR)が使われるため、コンテナはその間ずっと動き続けます。
この機能は、長期的なリソースサイジングを推奨・適用するというVPA本来の役割と併用できます。startup boostは実のところ、VPA(またはユーザー自身)がすでに確立したベースラインの上に重ねる、短命のオーバーライドにすぎません。
仕組みと設定方法
詳しい手順はこちら:Accelerate application startup with CPU startup boost。
CPU startup boostは、VerticalPodAutoscalerオブジェクトにstartupBoostブロックを追加することで定義します。Podレベルで適用してすべてのコンテナに同じブーストをかけることも、コンテナレベルで特定のコンテナだけを対象にしたり、Pod全体のブーストから特定のコンテナを除外したりすることもできます。
発動するのはPod作成時のみです。Pod自体は生きたまま後からコンテナが再起動した場合(たとえばOOMKill後など)には、ブーストは再適用されません。ブーストを注入するアドミッションWebhookは、Podの最初のアドミッション時にしか実行されないためです。
ブーストは倍率でも固定量でも指定できます。type: "Factor"はベースラインのCPUリクエストを倍率でスケールし(factor: 2なら2倍)、type: "Quantity"はベースラインに固定量のCPUを上乗せします。
この機能はVPAの更新モードを置き換えるのではなく、併用する形で動作します。ブーストの挙動だけが欲しければupdateMode: "Off"で運用し、継続的な使用状況に基づいてVPAにリソース調整も続けさせたければupdateMode: "InPlaceOrRecreate"と組み合わせてください。
Podレベルのブーストを設定するには、次のいずれかのオプションを使用します。
Podレベルのブースト(VPAの適用はオフ)
ブーストだけが欲しい場合はこちらを使います。VPAはそれ以外のリソース推奨を一切適用しません。
apiVersion: "autoscaling.k8s.io/v1"kind: VerticalPodAutoscalermetadata: name: example-vpaspec: targetRef: apiVersion: "apps/v1" kind: Deployment name: example updatePolicy: updateMode: "Off" startupBoost: cpu: type: "Factor" factor: 2 durationSeconds: 10Pod内のすべてのコンテナは、PodがReadyになってから最初の10秒間、ベースラインCPUリクエストの2倍を受け取り、その後GKEがインプレースで元のサイズに戻します。
Podレベルのブーストと継続的なVPA管理の併用
起動時のブーストに加えて、その後も継続的なインプレースのライトサイジングを行いたい場合はこちらです。
apiVersion: "autoscaling.k8s.io/v1"kind: VerticalPodAutoscalermetadata: name: example-vpaspec: targetRef: apiVersion: "apps/v1" kind: Deployment name: example updatePolicy: updateMode: "InPlaceOrRecreate" startupBoost: cpu: type: "Factor" factor: 2 durationSeconds: 10ブーストの挙動は同じですが、updateMode: "InPlaceOrRecreate"により、VPAはPodのライフタイム全体を通じてリソース変更の推奨と適用を続けます。その際、まずインプレースのリサイズを試み、できない場合に再作成へフォールバックします。
コンテナレベルのブースト:特定のコンテナだけを対象に
Deploymentにサイドカーやユーティリティコンテナがあり、起動時のCPUスパイクを必要としない場合に便利です。resourcePolicy.containerPoliciesを使って、ブーストを必要とするコンテナだけにスコープを絞ります。
apiVersion: "autoscaling.k8s.io/v1"kind: VerticalPodAutoscalermetadata: name: example-vpaspec: targetRef: apiVersion: "apps/v1" kind: Deployment name: example updatePolicy: updateMode: "Off" resourcePolicy: containerPolicies: - containerName: "boosted-container-name" mode: "Off" startupBoost: cpu: type: "Quantity" quantity: "2"この例では、boosted-container-nameは起動中、ベースラインのリクエストに加えて2 vCPUを追加で受け取ります。倍率ではなく固定量による指定です。
Podレベルのブーストから特定のコンテナを除外する
逆のケースです。Podレベルのブーストが設定されているものの、あるコンテナだけは他と一緒にブーストしたくない場合に使います。
apiVersion: "autoscaling.k8s.io/v1"kind: VerticalPodAutoscalermetadata: name: example-vpaspec: targetRef: apiVersion: "apps/v1" kind: Deployment name: example updatePolicy: updateMode: "InPlaceOrRecreate" startupBoost: cpu: type: "Factor" factor: 2 resourcePolicy: containerPolicies: - containerName: "disable-cpu-boost-for-this-container" startupBoost: cpu: type: "Factor" factor: 1Podレベルのブーストはデフォルトですべてのコンテナに2倍の係数を適用しますが、コンテナポリシーにより、指定したコンテナだけは係数1にオーバーライドされます。
Your cloud bill shouldn't be a mystery
Optimization, automation, expertise. In one platform.
有効化する前に知っておきたいこと
CPU startup boostを使う前に、いくつかの運用上の要件を満たす必要があります。
要件。 GKE 1.36.0-gke.4447000以降が必要で、StandardとAutopilotの両方で利用できます。VPAが有効になっていることも必要です。Autopilotではデフォルトで有効、Standardでは明示的に有効化します。また、ワークロードはコントローラー(DeploymentやStatefulSetなど)で管理されている必要があり、スタンドアロンのPodはサポートされません。完全なリストはこちら:CPU startup boost requirements。
HPAとの相互作用。 Horizontal Pod Autoscalerも併用している場合は、readinessProbeを定義し、ブーストにdurationSeconds: 0を設定してください。そうしないと、HPAが一時的なCPUスパイクを実際の負荷と誤認し、早すぎるスケールアウトを行ってしまうおそれがあります。詳しくはInteractions with horizontal Pod autoscalingを参照してください。
Standardにおけるクラスタオートスケーラーとの相互作用。 startup boostは、ブースト後のリクエストを収容するためにノードのスケールアップを引き起こすことがあります。ブーストが終了してノードが低使用率に見えると、今度はスケールダウンが発生してPodが退避される、というループに陥りかねません。こうしたデフラグメンテーションのループを最初から避けたい場合、GKEはAutopilotの利用を明示的に推奨しています。詳しくはCluster autoscaler and eviction loopsを参照してください。
ノード容量の制限。 Standardクラスタでは、ブースト後のリクエスト全量を収容する余裕がない場合、GKEはノードに実際に収まる分までブーストを制限します。
検証。 ブーストが適用されたかどうかは、PodにvpaCpuStartupBoost/<container-name>アノテーションがあるかで確認できます。ブーストの解除が行われたかどうかは、InPlaceResizedByVPAイベント(kubectl get events --field-selector reason=InPlaceResizedByVPA)で確認します。手順の詳細はこちら:Verify CPU startup boost。
まとめ
CPU startup boostは、Kubernetesのリソースサイジングに実際に存在していたギャップを埋める機能です。「アプリが速く起動するために必要なもの」と「起動後のアプリに必要なもの」を切り離せるようになりました。これまでこの区別は、ベースラインのリクエストを永久に水増しし続けるか、スロットリングされた遅い起動に耐えるか、のどちらかを意味していました。今では、高速な起動とスリムな定常状態フットプリントの両方が手に入ります。適用は自動で、解除もコンテナを中断することなくインプレースで行われます。
まだプレビュー版の機能なので、お決まりの注意点が当てはまります。まずは非本番環境で評価し、広く展開する前にHPAとクラスタオートスケーラーの相互作用に十分注意してください。
起動時だけで終わらないライトサイジング
CPU startup boostは起動時のスパイクを解決しますが、正確な定常状態のベースラインが前提であることに変わりはありません。大規模な運用環境では、ベースラインのCPUとメモリのリクエストを長期にわたって正確に保つこと自体が継続的な課題になります。
そこで登場するのがPerfectScale by DoiTです。PerfectScaleは実際の使用状況を監視し、Podのベースラインリクエストを継続的にライトサイジングします。インプレースPodリサイズを利用するため、退避や再起動なしにリソースを調整でき、Cluster AutoscalerやKarpenterといった既存のオートスケーラーとも併用できます。
startup boostが高速で中断のないコールドスタートをもたらすものだとすれば、PerfectScaleは、Podのライフサイクルの残りの部分が過剰・過少プロビジョニングの領域に逆戻りしないようにするものです。
PerfectScale by DoiTについて詳しく知りたい方は、デモを予約してください。