プロンプトとコンテキスト
プラットフォームチームが、Podを再作成することなくCPUとメモリを変更したいと考えています。インプレースリサイズフローを設計し、コンテナの再起動が必要となるタイミング、容量不足への対処方法、そしてオブザーバビリティとロールバックの方法を説明してください。
Kubernetes 1.33でコンテナのインプレースリサイズがBetaに昇格し、1.36ではPodレベルのリソースリサイズがBetaになりました。稼働中のPodは新しいCPUおよびメモリリソースを受け取ることができ、kubeletはresizePolicy、ノード容量、cgroupの状態を使用して変更を適用または延期します。「specを変更する」ことは「決して再起動しない」ことを意味するわけではありません。
面接官がテストしていること
Podレベルの境界とコンテナリソース、resizePolicyのCPUとメモリのセマンティクス、PendingおよびInProgress条件、実行不可能(infeasible)および延期(deferred)された要求、schedulerとkubeletの責務の違い、QoSと優先度、そしてカナリアリリースとロールバックの境界を網羅します。
30秒の回答フレームワーク
「リサイズを宣言的な要求とステートマシンとして設計します。コントローラーがリソースspecを更新し、kubeletが実現可能性をチェックしてPodResizePendingまたはPodResizeInProgressを報告します。CPUは多くの場合再起動なしで適用されますが、メモリの再起動動作は各コンテナのresizePolicyに従います。実行不可能な要求はその理由を保持し、制限の下で再試行されます。プラットフォームはobservedGeneration、実際のcgroups、再起動、QoSの変更を監視し、小さなカナリアとロールバック用の逆パッチを使用します。」
ステップバイステップの詳細解説
ステップ1:リソースモデルの定義
コンテナリソースは各コンテナのrequestsとlimitsを設定します。サポートされているバージョンではPodレベルの集約境界も公開されます。Podのlimitは総使用量の上限を設定しますが、コンテナのlimitがそれを超えることはできません。APIはspec.containers[*].resourcesまたはspec.resourcesのどちらを編集しているかを明示する必要があります。
ステップ2:宣言的リサイズフローの構築
プラットフォームはターゲットと理由を受け入れ、リソースフィールドを書き込み、古い値、実行者、generationを保存します。APIがノードのcgroupsを直接編集することはありません。kubeletは新しいgenerationを検知し、チェックして適用した後にstatusを書き込みます。
ステップ3:再起動ポリシーの処理
コンテナはリソースごとにポリシーを選択できます:
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainerNotRequiredはオンライン更新を試みます。RestartContainerは新しい値を適用するための再起動を許可します。restartPolicy: Neverを持つPodの場合、すべてのコンテナリソースでNotRequiredを使用する必要があり、そうでない場合要求は無効となります。
ステップ4:実現可能性と延期ステータスのモデリング
ノードがターゲットを提供できない場合、kubeletはInfeasibleやDeferredなどの理由とともにPodResizePendingを報告します。処理された要求はPodResizeInProgressに移行できます。コントローラーはAPI specだけでなくstatusを読み取る必要があり、observedGenerationを使用してstatusを要求されたgenerationに関連付けます。
ステップ5:CPUとメモリを異なるものとして扱う
CPUは通常、アプリケーションを再起動せずにcgroupのクォータを更新できます。メモリの縮小は現在のワーキングセットによって制約を受ける可能性があり、一部のランタイムでは安全に適用するために再起動が必要です。CPUからメモリの動作を推測しないでください。リソースごとのポリシーを読み取り、明示的なイベントを発行します。
ステップ6:スケジューリングとQoSの調整
インプレース更新は再スケジューリングではありません。requestを増やすにはノードの容量が必要になる場合があるため、延期された要求はPriorityClass、QoSクラス、および待機時間によって再試行する必要があります。namespaceやGuaranteedワークロードの計算が暗黙的に不足しないように、更新後にクォータ、QoS、アラートを再計算します。
ステップ7:有効な値の監視
期待されるspec、statusのconditions、observedGeneration、実際のコンテナcgroups、再起動、OOM、CPUスロットリング、およびメモリワーキングセットを収集します。statusが完了を示していてもcgroupsが変更されていない場合は、障害として扱い、変更を積み重ねるのではなく別のパッチをブロックします。
ステップ8:カナリア、レート制限、およびロールバック
ワークロードおよびノードプールごとにバッチでリサイズし、同時実行操作を制限し、Pendingのタイムアウトと再試行上限を設定します。障害発生時は保存されたリソースを復元します。メモリポリシーによってコンテナが再起動される場合は、トラフィックを退避(ドレイン)させ、拡張前にreadinessを確認します。コントローラーの再試行による作業の重複を防ぐため、すべての要求に冪等性キーが必要です。
トレードオフと境界
再起動なしの継続性 vs リソースの確実性
インプレースの変更は中断を減らしますが、容量と延期状態により完了は非同期になります。レイテンシに敏感なサービスには小さなステップを使用します。バッチジョブは確定的な結果を得るために再起動を受け入れる場合があります。
Podの境界 vs コンテナの精度
Podリソースは共有上限を表し、コンテナリソースはクリティカルなコンテナを保護します。両方が存在する場合、コンテナのlimitがPodの境界内に収まっていることを検証し、UIおよび監査レコードに有効な境界を表示します。
自動再試行 vs 承認
一時的な容量不足には、制限付きの再試行が適しています。メモリの再起動、QoSの変更、または本番環境のピーク時には、承認またはメンテナンスウィンドウが必要になる場合があります。無限の再試行は安全ではありません。
障害訓練と進化計画
ノードの容量不足
ノード容量を超える拡張を送信し、InfeasibleまたはDeferredを確認して、再試行によって古い有効な値が変更されないことを検証します。
メモリ変更によるコンテナの再起動
メモリにRestartContainerを設定し、トラフィックのドレイン、再起動、readinessの回復、イベントの順序を観察します。コントローラーが再起動をビジネス上の障害として報告しないようにします。
generationの競合
2つのターゲットを素早く送信します。古いgenerationが新しいターゲットを上書きしてはならず、最終的なobservedGenerationがcgroupの値と一致する必要があります。
よくある間違いとフォローアップ
間違い1:インプレースリサイズでは決して再起動が発生しないと思い込む
フォローアップ:何が再起動を引き起こしますか?コンテナのresizePolicyによって、特にメモリにおいて再起動が必要になる場合があります。Podレベルのリサイズには個別の再起動ポリシーはありませんが、コンテナのポリシーは引き続き適用されます。
間違い2:specの更新を完了とみなす
フォローアップ:成功をどのように確認しますか?期待されるフィールドだけでなく、conditions、observedGeneration、cgroups、コンテナイベント、および再起動回数を確認します。
間違い3:容量が不足しているときにパッチ適用を繰り返す
フォローアップ:何が正しい対応ですか?Pendingの理由を保持し、優先度と時間の制限内で再試行し、マイグレーション、より小さなターゲット、または承認の選択肢を提供します。
発展的なフォローアップと模範解答
なぜCPUとメモリを別々に設計するのですか?
CPUクォータは通常オンラインで変更できます。メモリの縮小はワーキングセットとランタイムの動作によって制約され、再起動が必要になる場合があります。共有APIであっても、リソースごとのポリシーと状態が必要です。
重複したリサイズ要求が新しいターゲットを上書きするのを防ぐにはどうすればよいですか?
条件付き更新のためにリソースバージョンまたはgenerationを使用し、最新のターゲットのみを受け入れ、observedGenerationを介してstatusとcgroupsを調整(reconcile)します。
インプレースリサイズを避けるべきなのはどのような場合ですか?
強力な分離が必要な場合、容量が不安定な場合、アプリケーションが再起動を許容できない場合、またはリソースの変更がランタイムの前提条件に違反する場合は、ローリング置換(rolling replacement)を使用します。インプレースリサイズは制御された最適化として維持してください。