Zero-Restart Scaling: KubernetesのインプレースPodリサイズとDRAによるステートフルシミュレーションブリッジの拡張

Quick answer
Zero-Restart Scaling: Kubernetes DRAとインプレースでの拡張: localhost tunnel answer
A localhost tunnel gives your local app a public HTTPS URL without opening router ports, which is useful for demos, QA, mobile testing, and provider callbacks.
How do I expose localhost without opening ports?
Use a reverse HTTPS tunnel. Your machine connects outbound to the tunnel service, and the public URL forwards requests back to your local app.
When should I use a localhost tunnel?
Use one for webhook testing, OAuth callbacks, client demos, QA previews, mobile device checks, and short-lived development reviews.
GPUメモリを増やすためにPodを停止して再スケジュールすることは、ステートフルなリアルタイムレンダリングブリッジにとって壊滅的な障害です。この記事では、KubernetesのIn-Place Pod Resize(v1.35から安定化)とDynamic Resource Allocation(v1.34から安定化、v1.36でさらに拡張)が、フレームを落とさずに空間ネットワーキングパイプラインを垂直にスケールさせる方法と、その際の課題について解説します。
はじめに:Podのリスケジュールによる高リスクな中断
リアルタイムの3Dシミュレーションやデジタルツインの同期は、産業コンピューティングにおいてミッションクリティカルなワークロードとなっています。NVIDIA Omniverseのようなプラットフォームは、工場のフロアや物流ハブ、航空宇宙システムの高忠実度デジタルレプリカを構築するために使われ、これらの環境は非常にステートフルです。連続した空間テレメトリや高密度のポイントクラウドデータを処理しています。
物理ハードウェアとクラウドベースのシミュレーションエンジンを接続するために、チームはローカルデータルーティングPod(「シミュレーションブリッジ」)をクラウドやエッジのKubernetesクラスター内で運用します。これらのブリッジは長寿命のWebSocketやgRPC接続を保持し、メモリ内にフレームシーケンスをバッファリングし、Dense CADやポイントクラウドデータを事前レンダリングまたは縮小して、集中型の可視化環境に送信します。
歴史的に、ブリッジPodがリソース制限に達した場合、Kubernetesには唯一の手段:エビクトして再スケジュールする方法しかありませんでした。垂直オートスケーラーやオペレーターはPodを殺し、空き容量のあるノードを見つけ、ボリュームを再マウントし、コンテナを再起動します。これはステートレスWebサービスにとっては小さな問題ですが、ステートフルなシミュレーションブリッジにとっては、以下のような具体的な問題を引き起こします:
- トンネルの破損 — TCP/WebSocketのライブセッションが即座に切断され、エッジデバイスでタイムアウトの連鎖を引き起こす
- キャッシュの無効化 — メモリ内のフレームバッファや空間インデックスが消去され、再初期化に時間がかかる
- 視覚的なカクつき — リアルタイムレンダリングの同期がフリーズまたはフレームドロップし、人間のオペレーターや自動検査システムに影響
このギャップを埋めるのが、インプレースPodリサイズ(コンテナのCPU/メモリの変更を再起動なしで行う)とDynamic Resource Allocation(DRA)(属性ベースのハードウェアデバイスのクレームで、Podの再作成を必要としない)です。これらはもはや新しい技術ではなく、バージョン履歴を正確に把握することが重要です。以下に現状を解説します。
正確なタイムラインの把握
これらの機能が実際に安定したのはいつか、正確に理解しておく必要があります。なぜなら、これらは異なるリリースで段階的に成熟したからです:
| 機能 | アルファ | ベータ | 安定(GA) |
|---|---|---|---|
| In-Place Pod Resize(コンテナレベル、KEP-1287) | v1.27(2023) | v1.33(2025年5月) | v1.35(2025年12月17日) |
Dynamic Resource Allocation(コア、resource.k8s.io/v1) |
v1.26 | v1.32–1.33 | v1.34(2025年8/9月) |
| Pod-*レベル*のインプレースリサイズ(リソースの集約、KEP-5419) | v1.35 | v1.36(2026年4月22日) | —(まだベータ) |
つまり、Kubernetes 1.35(「Timbernetes」)のリリース時点で、DRAはすでにGAになっており、その上にインプレースリサイズが安定化した形です。これらの機能は互いに補完し合いますが、リリースのタイミングは異なります。v1.35では、長らく制限されていたメモリ制限の減少も許可されるようになり、現在の使用状況に応じて最善努力のチェックが行われます。
最新のKubernetesリリースはv1.36(「Haru」)(2026年4月22日リリース)で、これらの機能はさらに拡張されています。詳細は後述します。
cgroups v2の役割
インプレースリサイズはLinuxカーネルのcgroups v2の統一階層に依存します。これにより、kubeletは実行中のプロセスのリソース境界(cpu.max、memory.max)を書き換えることができ、終了シグナルを送る必要がありません。カーネルは新しい境界を即座に適用し、PIDやソケット、メモリ状態は変更されません。
従来のGPUスケジューリングはDevice Pluginモデルに依存しており、GPUを不透明な整数(nvidia.com/gpu: 1)としてリクエストしていました。これはVRAMの部分的な増加やデバイスプロファイルの交換を、Podを破棄せずに行うことはできませんでした。これを可能にするのがDRAです。
詳細解説:インプレースPodリサイズの仕組み
resizeサブリソース、PATCHではなく
最初に指摘しておきたいのは、インプレースリサイズは一般的なPATCHを使って適用されるわけではないことです。Kubernetesはこれを専用の/resizeサブリソースとして公開しており、kubectlはv1.32以降でこれを使用できます:
kubectl patch pod omniverse-local-bridge \
--subresource resize \
--type='json' \
-p='[
{"op": "replace", "path": "/spec/containers/0/resources/requests/cpu", "value": "8"},
{"op": "replace", "path": "/spec/containers/0/resources/limits/cpu", "value": "8"},
{"op": "replace", "path": "/spec/containers/0/resources/requests/memory", "value": "32Gi"},
{"op": "replace", "path": "/spec/containers/0/resources/limits/memory", "value": "32Gi"}
]'
リサイズを/resizeサブリソース経由で行うことは、運用上も重要です。これにより、オートスケーリングコントローラーにpods/resizeへのpatch権限を付与しつつ、Podの他の部分への書き込み権限を与えない、より厳格なRBAC設定が可能になります。
Kubernetesのリサイズ追跡
リサイズのライフサイクルは、Podの状態フィールドと条件によって追跡されます。トップレベルの単一の列挙型ではありません:
| フィールド / 条件 | 意味 |
|---|---|
spec.containers[*].resources |
望ましいリソース — 要求した内容 |
status.containerStatuses[*].resources |
実際/割当済みリソース — 現在適用されているリソース |
PodResizePending(理由:Deferred) |
ノードに一時的に容量が不足している; kubeletは再試行 |
PodResizePending(理由:Infeasible) |
要求がノードの容量を超えているなど、満たせない場合。Podは以前の状態のまま動作 |
PodResizeInProgress |
kubeletがリサイズを受理し、適用中 |
QoSクラスの不変性
PodのQoSクラス(Guaranteed、Burstable、BestEffort)は、リクエストとリミットの関係から計算され、リサイズによって変わりません。これはKEP-1287の明示的な非ゴールの一つです。Guaranteed(リクエスト=リミット)のPodでリミットだけを変更し、リクエストを変えなければ、APIサーバは拒否します。両方のフィールドを一緒にスケールさせてください。
ダウンスケーリングのガードレール
GAリリース前は、メモリリミットの減少は完全にブロックされていました。v1.35以降は許可されましたが、kubeletは安全性を確保するために最善努力のチェックを行います。コンテナの現在のメモリ使用量をcgroupの統計から読み取り、提案されたリミット以下に収めます。使用量が超えている場合、リサイズはPodResizePending(理由:Deferred)にとどまり、OOMキルを避けます。このチェックは絶対保証されるものではなく、レースコンディションのため、メモリの変動が激しいワークロードでは注意が必要です。
ノードがすべての保留中リサイズを一度に満たせない場合、優先順位に従って再試行されます:PriorityClass、QoSクラス(Guaranteed優先)、待機時間の順です。
深掘り:GPUのためのDynamic Resource Allocation
DRAのコアAPIは、安定したresource.k8s.io/v1 APIグループに属します(v1alpha3はGA前のバージョン):
- DeviceClass — クラスター全体で定義されるハードウェアの分類(管理者やデバイスベンダーが作成)で、CEL(Common Expression Language)式を使ってハードウェアを識別します。例:
device.driver == "gpu.nvidia.com"に一致するデバイス。 - ResourceSlice — 各ノードのデバイスドライバーが公開する、利用可能なデバイスとその属性、容量の情報。
- ResourceClaim —
PersistentVolumeClaimのデバイス版。特定のDeviceClassにマッチするハードウェアの具体的なリクエストで、Podのライフサイクルに依存しません。 - ResourceClaimTemplate — Podスペックに埋め込み、Kubernetesが自動的に各Podに専用の
ResourceClaimを生成し、Pod終了時に削除します。
アーキテクチャの比較
| 旧Device Plugin | DRA (resource.k8s.io/v1) |
|
|---|---|---|
| 割り当て | 整数値(nvidia.com/gpu: 1) |
属性ベース(VRAM、MIGプロファイル、ドライバー、トポロジー) via CEL |
| ライブ再構成 | Podの再作成が必要 | テンプレートベースでClaimsを更新可能; 新しいClaimsは他のPodフィールドに影響しない |
| デバイス共有 | 静的、ベンダー固有のハック | ネイティブ共有(v1.36ベータではGPUパーティショニングもサポート) |
ゼロダウンタイムシミュレーションブリッジの設計
以下は、安定したDRAスキーマを用いた修正済みのマニフェスト例です(deviceClassNameとselectorsをexactly:ブロックで囲む必要があります):
apiVersion: v1
kind: Pod
metadata:
name: omniverse-local-bridge
namespace: spatial-net
labels:
app: simulation-pipeline
spec:
resourceClaims:
- name: dynamic-gpu-allocation
resourceClaimTemplateName: omniverse-gpu-template
containers:
- name: spatial-router-container
image: cr.enterprise.internal/spatial/omniverse-bridge:v2026.2.1
imagePullPolicy: IfNotPresent
# リソース変更によるコンテナ再起動の制御
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: NotRequired
# 基本リソース — Guaranteed QoS(requests == limits)
resources:
requests:
cpu: "4"
memory: "16Gi"
limits:
cpu: "4"
memory: "16Gi"
claims:
- name: dynamic-gpu-allocation
ports:
- containerPort: 8080
name: websocket-sync
- containerPort: 9090
name: grpc-telemetry
---
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
name: omniverse-gpu-template
namespace: spatial-net
spec:
spec:
devices:
requests:
- name: primary-rendering-core
exactly:
deviceClassName: enterprise-nvidia-gpu
selectors:
- cel:
expression: |-
device.attributes["gpu.nvidia.com"].profile == "1g.5gb" ||
device.attributes["gpu.nvidia.com"].profile == "3g.20gb"
このPodをスケールアップするには、オートスケーリングコントローラーがPodの/resizeサブリソースに対してJSONパッチを送信し(上記例参照)、同時にResourceClaimを更新してより大きなMIGプロファイルをリクエストします。kubeletはノードの未割当CPU/メモリを確認し、gRPC経由でDRAドライバーと連携してGPUデバイスの再マッピングを行い、cgroupの境界を更新します。これにより、spatial-router-containerのWebSocketループは中断なくデータを読み続けます。
本番環境のエッジケースとガードレール
遅延容量の制約。 ノードがほぼ飽和状態の場合、リサイズリクエストはPodResizePending(Deferred)に留まり、容量が空くまで自動的に再試行されます。ただし、保証された時間枠はありません。遅延に敏感なブリッジでは、一定時間(例:数秒以上)待機した場合に手動移行にエスカレーションする仕組みを設けることが推奨されます。
コントローラー/設定のドリフト。 /resizeサブリソースを直接適用したリサイズは、所有するDeploymentやStatefulSetのPodテンプレートを更新しません。ノード障害やコントローラーの再スケジュール時に、元のリソースプロファイルのPodが再作成される可能性があります。実運用では、インプレースリサイズとVPA(InPlaceOrRecreateモード)やカスタムオペレーターを併用し、リサイズ情報をアノテーションでコントローラーに反映させることが一般的です。
静的リソースマネージャーポリシー。 Guaranteed QoSのPodのリサイズは、静的CPUやメモリマネージャーポリシー(専用コア/NUMAメモリのピン留め)を使用している場合は、KEP-1287の範囲外です。この場合、リサイズはInfeasibleとして拒否されます。静的CPUピン留めを必要とするワークロードでは、これを考慮してください。将来的なサポートについての議論はありますが、現状のv1.36では対応していません。
GA以降の新情報:Kubernetes v1.36(「Haru」2026年4月)
このスタックがGAになってから、以下の新機能が追加・拡張されました(2026年4月リリース、現行安定版):
- Podレベルのインプレースリサイズ(ベータ、デフォルト有効、
cgroups v2必須)により、Pod全体のリソース範囲に対してスケーリング可能に。複数コンテナのPod(例:ルーターとサイドカー)で、個々のコンテナではなく共有リソースのスケーリングが可能。 - Partitionable devices and Consumable Capacity in DRAがベータ化され、デフォルトで有効化。これにより、MIGスライスをCELセレクターでリクエストする従来の方法に代わり、GPUのパーティションを直接理解できるようになった。
- Device Taints and Tolerations(ベータ)により、GPUの状態(例:ECCエラー後)を
ResourceSliceにマークし、新しいClaimがそれを避けることが可能に。 - Podのリソースヘルスステータス(
allocatedResourcesStatus、ベータ)により、各デバイスの状態をPodのステータスやkubectl describe podで確認でき、GPUの劣化や故障を事前に把握可能に。
これらの新機能は、前述のアーキテクチャを変更するものではありませんが、GPUブリッジの観測性を大きく向上させ、遅延に敏感なシステムの監視を強化します。
結論
In-Place Pod Resize(v1.35でGA)とDynamic Resource Allocation(v1.34でGA)は、リリースが1サイクルずつずれているものの、リソースの変更にPodを破棄せずに済む仕組みです。これにより、WebSocketやgRPCの状態を保持したステートフルなシミュレーションブリッジは、負荷に応じて拡大・縮小できるライブパイプラインを維持でき、負荷増加時に接続が切断されることもなくなります。実際の仕組みは、/resizeサブリソースを経由し、QoSクラスは不変、ダウンスケーリングは安全性のためにチェックされるが保証はなく、静的CPU/メモリピン留めは未対応です。これらの制約を理解し、それに基づいて設計することが、実運用において「ゼロリスタート」アーキテクチャを実現するポイントです。
変更履歴
元のドラフトの修正点:
1. DRAのGAリリースはv1.34であり、v1.35ではない。 元の記述では、DRAが「v1.35とともに安定化」と誤解されていました。実際には、DRAのコア(resource.k8s.io/v1)はKubernetes 1.34(2025年8/9月)でGA化済みで、v1.35はIn-Place Pod ResizeのGAリリースです。表を追加して明示します。
2. リサイズAPIの動作修正。 元のJSONパッチ例はPodオブジェクトに直接適用していましたが、正しくは/resizeサブリソースを使います(kubectl patch --subresource resize、v1.32以降)。例とRBACの影響も追記。
3. Pod状態モデルの修正。 表はAllocatedやResourcesがトップレベルのフィールドと誤解されていましたが、実際にはspecとstatus.containerStatusesにあり、DeferredやInfeasibleは条件の理由です。表を再構築。
4. DRAマニフェストのAPIバージョン修正。 元のYAMLはresource.k8s.io/v1alpha3を使っていましたが、現行のresource.k8s.io/v1に更新し、exactly:ラッパーも追加。
5. メモリリミットの減少と遅延リサイズの優先順位追加。 これらはv1.35のGAで新たにサポートされた内容です。
6. 静的リソースマネージャーポリシーの制限について追記。 これもKEP-1287の非ゴールであり、Infeasibleとして拒否されるケースです。
7. v1.36の新情報追加。 Podレベルのインプレースリサイズ、パーティショナブルデバイス、デバイステイント・トレイタンス、リソースヘルスステータスなど、最新の機能を解説。
8. 不要なSEO・AIドラフトの残存要素削除と整形。
参考資料: - Kubernetes 1.35: In-Place Pod Resize Graduates to Stable - Resize CPU and Memory Resources assigned to Containers - Resize CPU and Memory Resources assigned to Pods - In-Place Update of Pod Resources, KEP-1287 - Kubernetes v1.34: DRA has graduated to GA - Dynamic Resource Allocation - Allocate Devices to Workloads with DRA - Kubernetes v1.36: ハル (Haru) - Kubernetes v1.36 Release: New Features, Stable APIs Breaking Changes - Kubernetes releases
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.