# KEP-4381: Dynamic Resource Allocation with Structured Parameters [Kubernetes Enhancement Proposal (KEP) 4381](https://github.com/kubernetes/enhancements/issues/4381)。sig-node 主導(sig-scheduling・sig-autoscaling 参加)、著者 [[Patrick Ohly]]([[Intel]])。2024-01-05 作成、2026-08-19 時点で `status: implemented`・`stage: stable`。Kubernetes 1.30 でアルファ実装、1.31 で `v1alpha3` API 刷新、1.32 でベータ(`v1beta1`)、1.33 で GA 相当構造の `v1beta2`、1.34 で GA 昇格。最新マイルストーンは v1.35。(Source: kep.yaml) このKEPはもともと["classic" DRA #3063 KEP](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3063-dynamic-resource-allocation)の拡張として書かれたが、役割が逆転し、本KEPが基盤機能を定義し #3063 がオプション拡張を追加する関係になった。 ## 動機:デバイスプラグインAPIの4つの限界 Kubernetes は当初CPU・RAMのみを追跡し、後にストレージと離散的な拡張リソース(extended resources)を追加、kubelet の[device plugin API](https://github.com/kubernetes/design-proposals-archive/blob/main/resource-management/device-plugin.md)がノードローカルなカスタムリソースを露出させてきた。しかし新世代デバイス(GPU・FPGA等)には次の4限界がある。 1. **デバイス初期化・クリーンアップ**: FPGAの再構成に必要な設定情報を渡す手段がなく、ワークロード終了後のポストストップ処理(状態消去・電源管理)もサポートされない。 2. **部分割当(partial allocation)**: NVIDIA MIGやSR-IOVでデバイスを分割利用したくても、デバイスプラグインAPIでは事前分割・事前公開が必要で、要求時に動的生成する仕組みがない。ユーザーは抽象的な資源制約でなく特定の事前分割済みデバイスを選ばされる。 3. **オプショナル割当**: GPUや暗号オフロードエンジンのような「あれば使う、なければCPUにフォールバック」という要求はデバイスプラグイン・既存Pod資源宣言のどちらでも表現できない。 4. **ファブリック越しデバイス**: デバイスプラグインAPIはノードローカル発見が前提で、[Akri](https://www.cncf.io/projects/akri/)のようなプロジェクトは同一ネットワーク接続リソースを接続可能な全ノードに重複公開し使用時に全ノードの空き情報を更新するという回避策を強いられている。 Non-Goal として、デバイスプラグインAPIの置き換えではなく共存を明言し、また「何らかのGPUが欲しい」という抽象化レイヤーの提供もスコープ外とする(ポータビリティは属性の標準化によって将来積み上げる余地を残すのみ)。 ## API設計:3つの新規オブジェクト型 - **ResourceSlice**: 各ノードのDRAドライバが自分の担当分のデバイス一覧を named list として公開するオブジェクト。デバイスごとに `attributes`(型付き値。ベンダー名前空間で自動修飾)と `capacity`(数量)を持つ。`resource.kubernetes.io/` 名前空間はKubernetesプロジェクトによる標準属性用に予約されており、本KEPは `pcieRoot`・`pciBusID` の2属性を標準化する(ノード内トポロジ整合のため)。kubelet起動時に自ノードの全ResourceSliceを`DeleteCollection`で削除してから再構築するため、ドライバ再起動前にPodがスケジュールされることを防ぐ。 - **ResourceClaim / ResourceClaimTemplate**: ユーザーが「どんなデバイスがいくつ必要か」を宣言するnamespacedオブジェクト。`spec`は不変、`status`(`allocation`・`reservedFor`)がシステムにより更新される。永続的ResourceClaim(明示作成・複数Pod間共有)とephemeral ResourceClaim(ResourceClaimTemplateからPodごとに自動生成・OwnerReferenceでPod削除時にGC)の2ライフサイクルを持つ。デバイス選択は `device` 変数を介したCEL式のセレクタで行い、`AllocationMode`は`ExactCount`(既定、`count`で個数指定)と`All`(プール内の全マッチデバイス)を持つ。 - **DeviceClass**: 管理者・ベンダーが定義するクラスタスコープのプリセット。ResourceClaimのリクエストが参照する形で、セレクタと設定パラメータ(不透明なベンダー固有パラメータを含む)を継承させる。「rootで初期化コマンドを実行する」ような管理者専用の危険な設定は、ユーザー入力側のパラメータでは許可しない設計上の注意が明記されている。 Config・Selectorsに含まれる不透明なベンダーパラメータはスケジューラのデバイス選択には使われず、割当確定後にDRAドライバへそのまま渡される。割当結果は `AllocationResult`(`<driver>/<pool>/<device>` の組で一意特定)としてResourceClaim statusに記録される。 ![[_attachments/4381-dra-structured-parameters/fig01-components-architecture.png]] (KEPが定義するコンポーネント構成図。apiserver配下にnamespacedなPod/ResourceClaim/ResourceClaimTemplateとcluster-scopedなResourceSlice/DeviceClassが並び、controller-managerのresource claim controller・schedulerのresource plugin・kubeletのresource manager/plugin managerが、DRAドライバのkubelet pluginとgRPCで通信する全体像を示す。Source: KEP-4381 `components.png`) ## スケジューリングフロー:kube-schedulerの7段階拡張点 新設の "claim plugin" は `EventsToRegister`(Queuing hintsで無関係なPodの再試行を抑制)・`PreEnqueue`(claim存在確認)・`Pre-filter`(情報収集)・`Filter`(ノードごとの割当可否判定。CEL評価コストのため既定10秒のタイムアウトを持ち `DRASchedulerFilterTimeout` フィーチャーゲートで無効化可能)・`Post-filter`(delayed allocationのclaimを1つ解放して再試行)・`Reserve`(割当結果をin-flightマップに保持しブロッキングAPI呼び出しを避ける)・`Unreserve`(スケジュール失敗時にreservedForエントリを取り消しデッドロックを防ぐ)の順で動作する。`scheduler_perf`実測では定常状態Filterが約10ms、5000pod/500node充填時で最大200msとされる。 複数スケジューラ・複数Pod間の競合(同一claimへの同時予約・delayed allocationの重複割当試行)は、いずれもResourceClaim statusへの書き込み競合(conflict error)で検出され、負けた側が再試行キューに戻る形で解決される。 ## kubelet-DRAドライバ間通信 kubelet pluginは[CSI](https://github.com/container-storage-interface/spec/blob/master/spec.md)を参考にした独自gRPCインターフェース(`k8s.io/kubelet/pkg/apis/dra`)をUnix Domain Socket経由で提供する。`NodePrepareResource`/`NodeUnprepareResources`のRPCで、kubeletはPodスケジュール時にリソース準備を指示し、DRAドライバはCDI(Container Device Interface)のJSONファイルを生成してCDIデバイスIDを返す。バージョンスキュー対応のため、kubeletはResourceSlice管理をほぼ全面的にプラグインへ委譲し、古いkubeletと新しいDRAドライバの組み合わせでも動作できる設計になっている。 ![[_attachments/4381-dra-structured-parameters/fig02-kubelet-resource-preparation-flow.png]] (PodスケジュールからNodePrepareResource呼び出し・CDI JSONファイル生成・CRIランタイムへのデバイスID受け渡し・コンテナ起動、そしてPod終了時のNodeUnprepareResourceに至る一連のアクティビティ図。Source: KEP-4381 `kubelet.png`) ## セキュリティモデルとリスク kubeletはResourceClaimへの書き込み権限を意図的に持たない(read-only)。これは、侵害されたkubeletがスケジューリング中のPodの割当結果を偽装してDoS攻撃を行うことを防ぐためである。侵害されたDRAドライバはResourceSliceへの書き込み権限を持つため、ノード単位の影響に限定はできるが、ハードウェア管理のためroot権限が必要になりがちで、権限昇格のリスクがある。ephemeral claimはkube-controller-managerが自動作成するため、RBACによるResourceClaim作成制限が事実上回避され得る点も明記されている。 ## GA(Kubernetes 1.34)への昇格条件 Graduation Criteriaは、Alpha(フィーチャーフラグ実装)・Beta(フル実装+フィードバック収集)を経て、GAには以下を課す。 - **異なる組織による実DRAドライバ実装3件以上** - **ノード内トポロジ整合(NUMA・PCIeルート等)に適した標準属性の少なくとも1つの標準化** - スケーラビリティ・性能解析の完了と公開 - kubelet再起動・ノードブート/再起動・ドライバランタイム・アップグレード/ダウングレードの障害モード定義 ## 代替案として却下されたアプローチ - **Node statusへの資源情報公開**: 全ドライバの情報が単一の巨大オブジェクトに集約され肥大化する、全node watcherに不要な情報が伝播する、alpha品質のフィールドがGA APIに混入する、の3点で却下。 - **既存ボリューム(CSI/PVC)の流用**: 初期プロトタイプ([intel/proof-of-concept-cdi](https://github.com/intel/proof-of-concept-cdi))はカスタムCSIドライバで試みたが、per-resourceパラメータをPVCアノテーションに押し込む必要がありUXが悪く、SIG-Storageは「アプリのポータビリティを損なう」として類似提案を過去に却下している。 - **デバイスプラグインAPIの拡張**: `Deallocate`追加やPodアノテーション経由のパラメータ渡しが過去に試みられたが、部分割当・オプショナル割当は既存のリソース宣言モデルを変えないと実現できず、既存デバイスプラグインに無意味なAPI呼び出し(スタブ実装)を強制することになるため却下。 ## トラブルシューティングで明記される既知の障害モード - kube-schedulerがResourceClaimを割当できない(`cannot allocate all claims` / `ResourceClaim not created yet`)。`unschedulable_pods`メトリクスの`dynamicresources`プラグインラベルで検知。 - ResourceClaim/ResourceClaimTemplateフィールドを認識しない古いMutating Pod Webhookが、Pod作成時にこれらのフィールドを黙って落とす(v1.32のcore v1 API拡張に追従していないwebhookで発生)。 - スケジューラがCEL評価に時間を要し `timed out trying to allocate devices` でPodがpending化する。`FilterTimeout`設定の緩和か、問題ドライバのアンインストールで緩和する。 - [device taints](https://github.com/kubernetes/enhancements/issues/5055)(将来KEP)を使い、`dra_resource_claims_in_use`メトリクスがゼロになったことを確認してからドライバを安全に削除する運用パターンが示されている。 ## 出典 - Patrick Ohly ほか, "KEP-4381: Dynamic Resource Allocation with Structured Parameters", kubernetes/enhancements, `keps/sig-node/4381-dra-structured-parameters/README.md`, creation-date 2024-01-05, 参照日 2026-08-19. - 同ディレクトリ `kep.yaml`(著者・マイルストーン・フィーチャーゲート・メトリクス定義)。